1 Commits

Author SHA1 Message Date
Ivan Malopinsky a40501a0f5 1.10.1 2017-07-19 20:07:38 -04:00
6 changed files with 70 additions and 265 deletions
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017-2020 Ivan Malopinsky
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+22 -34
View File
@@ -5,57 +5,45 @@ Keep your repo fresh with one command.
## Usage
```
SYNOPSIS
git-fresh [-fmrtRWS] [-sl] [remote] [root]
Usage: git fresh [-fmrtRW] [-sl] [remote] [root]
By default, git-fresh will:
- rebase against remote current branch
- stash changes
- prune remote branches
DESCRIPTION
git-fresh helps keep your Git repo fresh.
git-fresh will ignore any branches listed in a .freshignore file.
.freshignore should contain branch names you would like to ignore
on separate lines. The file can exist in the current Git repo
or in the home directory, i.e. ~/.freshignore.
By default, git-fresh will:
- update local root (master) to match remote root
- stash changes
- prune remote branches
-f: Delete stale local and remote branches
-m: Merge remote root into current branch
-r: Rebase current branch against remote root
-t: Remove local tags that do not exist on remote
-R: Reset local root to remote root
-W: Wipe workspace clean
git-fresh will ignore any branches listed in a .freshignore file.
.freshignore should contain branch names you would like to ignore
on separate lines. The file can exist in the current Git repo
or in the home directory, i.e. ~/.freshignore.
-s: Apply stashed changes after run
-l: Only delete local stale branches
remote is origin by default. root is master by default.
-v: Print git-fresh version and exit
OPTIONS
-f Delete stale local and remote branches
-m Merge remote root into current branch
-r Rebase current branch against remote root
-t Remove local tags that do not exist on remote
-R Reset local root to remote root
-W Wipe workspace clean
-S Clear all stash entries
-s Apply stashed changes after run
-l Only delete local stale branches
-v Print git-fresh version and exit
remote: remote name, origin by default
root: root branch, master by default
```
## Installation
### Manual on Linux or macOS
### Manual
1. Clone or download
2. `cd git-fresh`
3. `sudo ./install.sh`
### Manual on Windows
Copy the file [git-fresh](https://raw.githubusercontent.com/imsky/git-fresh/master/git-fresh) to `usr\bin` in your git installation directory.
This usually is `C:\Program Files\Git\usr\bin`.
3. `sudo ./install`
### Package
* [Homebrew](http://brew.sh/): `brew install git-fresh`
* [bpkg](http://www.bpkg.io/): `bpkg install imsky/git-fresh`
* [AUR](https://aur.archlinux.org/): [git-fresh](https://aur.archlinux.org/packages/git-fresh/)
## License
+47 -125
View File
@@ -1,5 +1,4 @@
#!/usr/bin/env bash
# generate man page with: txt2man.sh -t git-fresh <(./git-fresh -?) > git-fresh.1
# git-fresh
# https://github.com/imsky/git-fresh
@@ -7,48 +6,33 @@
# MIT License
usage () {
cat << EOT
NAME
git-fresh
cat << EOD
Usage: git fresh [-fmrtRW] [-sl] [remote] [root]
By default, git-fresh will:
- rebase against remote current branch
- stash changes
- prune remote branches
SYNOPSIS
git-fresh [-fmrtRWS] [-sl] [remote] [root]
git-fresh will ignore any branches listed in a .freshignore file.
.freshignore should contain branch names you would like to ignore
on separate lines. The file can exist in the current Git repo
or in the home directory, i.e. ~/.freshignore.
DESCRIPTION
git-fresh helps keep your Git repo fresh.
-f: Delete stale local and remote branches
-m: Merge remote root into current branch
-r: Rebase current branch against remote root
-t: Remove local tags that do not exist on remote
-R: Reset local root to remote root
-W: Wipe workspace clean
By default, git-fresh will:
- update local root (master) to match remote root
- stash changes
- prune remote branches
-s: Apply stashed changes after run
-l: Only delete local stale branches
git-fresh will ignore any branches listed in a .freshignore file.
freshignore should contain branch names you would like to ignore
on separate lines. The file can exist in the current Git repo
or in the home directory, i.e. ~/.freshignore.
-v: Print git-fresh version and exit
remote is origin by default. root is master by default.
OPTIONS
-f Delete stale local and remote branches
-m Merge remote root into current branch
-r Rebase current branch against remote root
-t Remove local tags that do not exist on remote
-R Reset local root to remote root
-W Wipe workspace clean
-S Clear all stash entries
-s Apply stashed changes after run
-l Only delete local stale branches
-v Print git-fresh version and exit
BUGS
Issues are tracked on GitHub: https://github.com/imsky/git-fresh
AUTHOR
Ivan Malopinsky - http://imsky.co
EOT
remote: remote name, origin by default
root: root branch, master by default
EOD
exit 0
}
@@ -63,17 +47,12 @@ die () {
}
error () {
ERR=${ERR:-unknown}
die "Error on line $1: $ERR"
die "Error on line $1: $(head -n $1 $0 | tail -1)"
}
trap 'error $LINENO' ERR
if [[ "$1" = '--help' ]]; then
usage
fi
while getopts ":fmrtslRWSTv" opt; do
while getopts ":fmrtslRWTv" opt; do
case $opt in
f)
FORCE_DELETE_STALE=true
@@ -99,14 +78,11 @@ while getopts ":fmrtslRWSTv" opt; do
W)
WIPE_WORKSPACE=true
;;
S)
CLEAR_STASH=true
;;
T)
TEST=true
;;
v)
VERSION=1.12.1
VERSION=1.10.1
;;
*)
usage
@@ -156,48 +132,20 @@ if [[ -z "$INSIDE_GIT_REPO" ]]; then
fi
# Are we in a non-empty git repository?
ERR="could not get top-level-directory"
TOP_LEVEL_DIRECTORY=$(git rev-parse --show-toplevel)
REMOTE=${1:-origin}
ROOT=${2:-master}
ROOT_GUESS=master
if [[ -n $(git show-ref refs/heads/main) && -z $(git show-ref refs/heads/master) ]]; then
ROOT_GUESS=main
if [[ $(ls -1 "$TOP_LEVEL_DIRECTORY/.git/refs/heads" | wc -l | xargs) -eq "0" ]]; then
if git rev-parse --verify "$ROOT"; then
git rev-parse "$ROOT" > "$TOP_LEVEL_DIRECTORY/.git/refs/heads/$ROOT"
else
(git fsck --lost-found &> /dev/null; git checkout "$ROOT") || die "No HEAD ref available"
fi
fi
ROOT=${2:-$ROOT_GUESS}
# Recover the root HEAD if it is missing or corrupt (e.g. master head reads "master")
recover_root () {
ROOT_HEAD_FILE="$TOP_LEVEL_DIRECTORY/.git/refs/heads/$ROOT"
if [[ -e "$ROOT_HEAD_FILE" ]]; then
if [[ $(cat "$ROOT_HEAD_FILE") = $(echo $ROOT) ]]; then
CORRUPT_ROOT_HEAD=true
fi
else
MISSING_ROOT_HEAD=true
fi
if [[ "$CORRUPT_ROOT_HEAD" = "true" || "$MISSING_ROOT_HEAD" = "true" ]]; then
ERR="failed to recover $ROOT HEAD"
RECOVERED_ROOT_HEAD=$(cat "$TOP_LEVEL_DIRECTORY/.git/logs/refs/heads/$ROOT" | tail -n1 | cut -d' ' -f2)
echo "$RECOVERED_ROOT_HEAD" > "$ROOT_HEAD_FILE"
say "Recovered $ROOT HEAD, set to $RECOVERED_ROOT_HEAD"
CORRUPT_ROOT_HEAD=false
MISSING_ROOT_HEAD=false
fi
}
recover_root
LAST_WORKING_DIRECTORY="$(pwd)"
cd "$TOP_LEVEL_DIRECTORY"
ERR="could not get current commit"
CURRENT=$(git rev-parse --abbrev-ref HEAD)
ERR=""
if [[ $(git remote -v | wc -l) -gt "0" ]]; then
REMOTES=true
@@ -217,52 +165,55 @@ if [[ -f $FRESH_IGNORE ]]; then
fi
fi
STASH_STAMP=git-fresh-$(date +%s)
# Stash changed files
if ! git diff-files --quiet; then
ERR="could not stash changes"
git stash save $STASH_STAMP
fi
if [[ $REMOTES = true ]]; then
# Update remotes and prune stale remotes
ERR="could not update and prune remotes"
git remote prune $REMOTE
git remote update $REMOTE
git remote prune $REMOTE
# If the current branch exists on the remote, rebase against it
REMOTE_CURRENT=$(git ls-remote $REMOTE --heads 2> /dev/null | grep "heads/$CURRENT$" | cat)
if [[ ! -z "$REMOTE_CURRENT" ]]; then
git rebase $REMOTE $CURRENT
fi
fi
# If we are not already on root branch, switch to root branch (master)
if [[ "$ROOT" != "$CURRENT" ]]; then
ERR="could not check out $ROOT branch"
git checkout $ROOT > /dev/null 2>&1
fi
# Wipe workspace?
if [[ $WIPE_WORKSPACE = true ]]; then
ERR="could not wipe workspace"
git clean -dfx
fi
if [[ $REMOTES = true ]]; then
# Reset root?
# Reset root?
if [[ $REMOTES = true ]]; then
if [[ $RESET_ROOT = true ]]; then
ERR="could not reset root"
git reset --hard $REMOTE/$ROOT
fi
fi
ERR="could not perform fast forward merge"
git pull --quiet --ff-only $REMOTE $ROOT || say "Fast forward merge failed on $ROOT. You can reset local $ROOT by running git fresh -R."
if [[ $REMOTES = true ]]; then
git rebase -q $REMOTE/$ROOT
fi
# Compute stale branches
ERR="could not determine stale branches"
SMART_STALE=$(git branch -a --merged | tr -d "\* " | grep -Ev ">|$ROOT" | cat)
LOCAL_STALE=$(grep -Ev "^remotes/" <<< "$SMART_STALE" | cat)
@@ -281,7 +232,6 @@ if [[ ! -z "${SMART_STALE// }" ]]; then
fi
fi
if [[ "$FORCE_DELETE_STALE" = true ]]; then
ERR="could not delete stale local branches: $LOCAL_STALE"
echo -n $LOCAL_STALE | tr " " "\0" | xargs -0 git branch -d 2> /dev/null
else
if [[ $STALE_BRANCHES = true ]]; then
@@ -300,7 +250,6 @@ if [[ ! -z "${SMART_STALE// }" ]]; then
fi
if [[ "$FORCE_DELETE_STALE" = true ]]; then
if [[ "$DELETE_ONLY_LOCAL" != true ]]; then
ERR="could not delete stale remote branches: $REMOTE_STALE"
echo -n $REMOTE_STALE | tr " " "\0" | xargs -0 git push $REMOTE --delete
fi
else
@@ -325,9 +274,7 @@ fi
if [[ ! -z $(git rev-parse --verify --quiet "$CURRENT") ]]; then
if [[ "$ROOT" != "$CURRENT" ]]; then
ERR="could not check out $CURRENT branch"
git checkout $CURRENT
recover_root
fi
if [ "$REBASE" = true ] && [ "$MERGE" = true ]; then
@@ -335,12 +282,10 @@ if [[ ! -z $(git rev-parse --verify --quiet "$CURRENT") ]]; then
else
if [[ "$REMOTES" = true ]]; then
if [[ "$REBASE" = true ]]; then
ERR="could not rebase against $ROOT branch"
git rebase $ROOT
fi
if [[ "$MERGE" = true ]]; then
ERR="could not merge $ROOT branch"
git merge --no-edit $ROOT
fi
fi
@@ -352,7 +297,6 @@ fi
# Remove local tags that are missing on the remote
if [[ "$TAGS" = true ]]; then
ERR="could not get remote tags"
REMOTE_TAGS=$(git ls-remote --tags $REMOTE | cut -f 2)
LOCAL_TAGS=$(git show-ref --tags | cut -d' ' -f 2)
@@ -368,32 +312,10 @@ fi
if [[ ! -z $(git stash list | grep $STASH_STAMP | cat) ]]; then
if [[ "$APPLY_STASH" = true ]]; then
ERR="could not apply stashed changes"
git stash pop
else
say "Stashed changes present, apply with: git stash pop"
fi
fi
# Clear stashed changes
if [[ "$CLEAR_STASH" = true ]]; then
ERR="could not clear stashed changes"
git stash clear
fi
if ! git gc --auto --force; then
ERR="git prune failed"
git prune
rm -rf "$TOP_LEVEL_DIRECTORY/.git/gc.log"
fi
if [[ -d "$LAST_WORKING_DIRECTORY" ]]; then
cd "$LAST_WORKING_DIRECTORY"
else
say "Previous working directory does not exist on the branch $ROOT"
fi
recover_root
ERR=""
git gc --auto --prune=now
-73
View File
@@ -1,73 +0,0 @@
." Text automatically generated by txt2man
.TH git-fresh "January 21, 2019" "" ""
.SH NAME
\fBgit-fresh
\fB
.SH SYNOPSIS
.nf
.fam C
\fBgit-fresh\fP [\fB-fmrtRWS\fP] [\fB-sl\fP] [\fIremote\fP] [\fIroot\fP]
.fam T
.fi
.SH DESCRIPTION
\fBgit-fresh\fP helps keep your Git repo fresh.
.PP
By default, \fBgit-fresh\fP will:
.IP \(hy 3
update local \fIroot\fP (master) to match \fIremote\fP \fIroot\fP
.IP \(hy 3
stash changes
.IP \(hy 3
prune \fIremote\fP branches
.PP
\fBgit-fresh\fP will ignore any branches listed in a .freshignore file.
\ .freshignore should contain branch names you would like to ignore
on separate lines. The file can exist in the current Git repo
or in the home directory, i.e. ~/.freshignore.
.PP
\fIremote\fP is origin by default. \fIroot\fP is master by default.
.SH OPTIONS
.TP
.B
\fB-f\fP
Delete stale local and \fIremote\fP branches
.TP
.B
\fB-m\fP
Merge \fIremote\fP \fIroot\fP into current branch
.TP
.B
\fB-r\fP
Rebase current branch against \fIremote\fP \fIroot\fP
.TP
.B
\fB-t\fP
Remove local tags that do not exist on \fIremote\fP
.TP
.B
\fB-R\fP
Reset local \fIroot\fP to \fIremote\fP \fIroot\fP
.TP
.B
\fB-W\fP
Wipe workspace clean
.TP
.B
\fB-S\fP
Clear all stash entries
.TP
.B
\fB-s\fP
Apply stashed changes after run
.TP
.B
\fB-l\fP
Only delete local stale branches
.TP
.B
\fB-v\fP
Print \fBgit-fresh\fP version and exit
.SH BUGS
Issues are tracked on GitHub: https://github.com/imsky/\fBgit-fresh\fP
.SH AUTHOR
Ivan Malopinsky - http://imsky.co
-11
View File
@@ -3,14 +3,3 @@ INSTALL_DIR=${1:-/usr/local/bin}
mkdir -p $INSTALL_DIR
cp git-fresh $INSTALL_DIR && ([ -e $INSTALL_DIR/git-fresh ] && echo git-fresh installed in $INSTALL_DIR)
if [[ -e /usr/local/man ]]; then
MAN_DIR=/usr/local/man
elif [[ -e /usr/local/share/man ]]; then
MAN_DIR=/usr/local/share/man
fi
if [[ ! -z "$MAN_DIR" ]]; then
mkdir -p "$MAN_DIR/man1"
cp git-fresh.1 "$MAN_DIR/man1/" 2> /dev/null || echo Failed to install git-fresh man page
fi
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "git-fresh",
"version": "1.13.0",
"version": "1.10.0",
"description": "Utility to keep Git repositories fresh",
"global": true,
"repo": "imsky/git-fresh",