1 Commits

Author SHA1 Message Date
Ivan Malopinsky 32e798c218 Merge pull request #59 from imsky/safety-checks
add safety checks before running git-fresh
2015-12-03 20:28:20 -05:00
4 changed files with 34 additions and 118 deletions
+2 -4
View File
@@ -5,16 +5,15 @@ Keep your repo fresh with one command.
## Usage
```
Usage: git fresh [-fmrtF] [-sl] [remote] [root]
Usage: git fresh [-fmrF] [-sl] [remote] [root]
By default, git-fresh will:
- rebase against remote current branch
- rebase against remote current branch
- 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
-F: Reset local root to remote root, wipe workspace
-s: Apply stashed changes after run
@@ -34,7 +33,6 @@ root: root branch, master by default
### Package
* [Homebrew](http://brew.sh/): `brew install git-fresh`
* [bpkg](http://www.bpkg.io/): `bpkg install imsky/git-fresh`
## License
+30 -112
View File
@@ -7,7 +7,7 @@
usage () {
cat << EOD
Usage: git fresh [-fmrtF] [-sl] [remote] [root]
Usage: git fresh [-fmrF] [-sl] [remote] [root]
By default, git-fresh will:
- rebase against remote current branch
- stash changes
@@ -16,7 +16,6 @@ By default, git-fresh will:
-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
-F: Reset local root to remote root, wipe workspace
-s: Apply stashed changes after run
@@ -29,22 +28,19 @@ EOD
exit 0
}
say () {
echo "[git-fresh] $@" 1>&2
}
die () {
say $@
error () {
echo "[git-fresh] error on line $1"
exit 1
}
error () {
die "Error on line $1: $(head -n $1 $0 | tail -1)"
die () {
echo "[git-fresh] $@" 1>&2
exit 1
}
trap 'error $LINENO' ERR
while getopts ":fmrtslFT" opt; do
while getopts ":fmrslF" opt; do
case $opt in
f)
FORCE_DELETE_STALE=true
@@ -55,9 +51,6 @@ while getopts ":fmrtslFT" opt; do
r)
REBASE=true
;;
t)
TAGS=true
;;
s)
APPLY_STASH=true
;;
@@ -67,9 +60,6 @@ while getopts ":fmrtslFT" opt; do
F)
FORCE_LOCAL_RESET=true
;;
T)
TEST=true
;;
*)
usage
break
@@ -79,85 +69,33 @@ done
shift $((OPTIND-1))
# Are we in testing mode?
if [[ $TEST = true ]]; then
PATH=$(pwd):$PATH
TEST_DIR=/tmp/git-fresh-test
mkdir -p $TEST_DIR; cd $TEST_DIR
git init; touch test; git add test; git commit -am 'test'
git checkout -b test; rm test; git commit -am 'delete test'
git checkout master; git merge test; git checkout test
git-fresh -fr; rm -rf $TEST_DIR
exit 0
fi
# Are we inside a git repository?
INSIDE_GIT_REPO=$(git rev-parse --is-inside-work-tree 2> /dev/null)
if [[ -z "$INSIDE_GIT_REPO" ]]; then
die "Not a git repository"
fi
# Are we in a non-empty git repository?
TOP_LEVEL_DIRECTORY=$(git rev-parse --show-toplevel)
[[ $(ls -1 "$TOP_LEVEL_DIRECTORY/.git/refs/heads" | wc -l | xargs) -eq "0" ]] && die "No HEAD ref available"
[[ ! -e .git ]] && die "Not a git repository"
[[ $(ls -l .git/refs/heads | wc -l) -eq "1" ]] && die "No HEAD ref available"
CURRENT=$(git rev-parse --abbrev-ref HEAD)
REMOTE=${1:-origin}
ROOT=${2:-master}
if [[ $(git remote -v | wc -l) -gt "0" ]]; then
REMOTES=true
fi
git remote update
git remote prune $REMOTE
STASH_STAMP=git-fresh-$(date +%s)
# Stash changed files
if ! git diff-files --quiet; then
git stash save $STASH_STAMP
fi
if [[ $REMOTES = true ]]; then
# Update remotes and prune stale remotes
git remote update
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
# Switch to root branch (master)
git rebase $REMOTE $CURRENT
git checkout $ROOT > /dev/null 2>&1
if [[ $REMOTES = true ]]; then
if [[ "$FORCE_LOCAL_RESET" = true ]]; then
git clean -dfx
git reset --hard $REMOTE/$ROOT
else
git rebase -q $REMOTE/$ROOT
fi
if [[ "$FORCE_LOCAL_RESET" = true ]]; then
git clean -dfx
git reset --hard $REMOTE/$ROOT
else
git rebase -q $REMOTE/$ROOT
fi
# Compute stale branches
SMART_STALE=$(git branch -a --merged | tr -d "\* " | grep -Ev ">|$ROOT" | cat)
LOCAL_STALE=$(grep -Ev "^remotes/" <<< "$SMART_STALE" | cat)
@@ -170,9 +108,9 @@ if [[ ! -z "${SMART_STALE// }" ]]; then
if [[ ! -z "${LOCAL_STALE// }" ]]; then
STALE_BRANCHES=true
if [[ "$FORCE_DELETE_STALE" = true ]]; then
echo -n $LOCAL_STALE | tr " " "\0" | xargs -0 git branch -d 2> /dev/null
echo -n $LOCAL_STALE | xargs git branch -d 2> /dev/null
else
say "Local stale branches found:" $(echo -n $LOCAL_STALE | tr "\n" " ")
echo "Local stale branches found:" $(echo -n $LOCAL_STALE | tr "\n" " ")
fi
fi
@@ -180,61 +118,41 @@ if [[ ! -z "${SMART_STALE// }" ]]; then
STALE_BRANCHES=true
if [[ "$FORCE_DELETE_STALE" = true ]]; then
if [[ "$DELETE_ONLY_LOCAL" != true ]]; then
echo -n $REMOTE_STALE | tr " " "\0" | xargs -0 git push $REMOTE --delete
echo -n $REMOTE_STALE | xargs git push $REMOTE --delete
fi
else
say "Remote stale branches found:" $(echo -n $REMOTE_STALE | tr "\n" " ")
echo "Remote stale branches found:" $(echo -n $REMOTE_STALE | tr "\n" " ")
fi
fi
if [[ "$FORCE_DELETE_STALE" != true && "$STALE_BRANCHES" = true ]]; then
say "Delete stale branches with: git fresh -f"
echo "Delete stale branches with: git fresh -f"
fi
fi
# Rebase or merge remote root against local branch
if [[ ! -z $(git rev-parse --verify --quiet "$CURRENT") ]]; then
git checkout $CURRENT
git checkout $CURRENT 2> /dev/null
if [ "$REBASE" = true ] && [ "$MERGE" = true ]; then
say "Rebase and merge enabled, skipping both"
echo "Rebase and merge enabled, skipping both"
else
if [[ "$REMOTES" = true ]]; then
if [[ "$REBASE" = true ]]; then
git rebase $ROOT
fi
if [[ "$REBASE" = true ]]; then
git rebase $REMOTE/$ROOT
fi
if [[ "$MERGE" = true ]]; then
git merge --no-edit $ROOT
fi
if [[ "$MERGE" = true ]]; then
git merge --no-edit $REMOTE/$ROOT
fi
fi
else
echo "$CURRENT branch was stale, staying on $ROOT"
fi
# Remove local tags that are missing on the remote
if [[ "$TAGS" = true ]]; then
REMOTE_TAGS=$(git ls-remote --tags $REMOTE | cut -f 2)
LOCAL_TAGS=$(git show-ref --tags | cut -d' ' -f 2)
for tag in $LOCAL_TAGS; do
if [[ -z $(grep $tag <<< "$REMOTE_TAGS" | cat) ]]; then
MISSING_TAG="${tag//refs\/tags\/}"
git tag -d $MISSING_TAG
fi
done
fi
# Restore stashed changes
if [[ ! -z $(git stash list | grep $STASH_STAMP | cat) ]]; then
if [[ "$APPLY_STASH" = true ]]; then
git stash pop
else
say "Stashed changes present, apply with: git stash pop"
echo "Stashed changes present, apply with: git stash pop"
fi
fi
View File
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "git-fresh",
"version": "1.6.2",
"version": "1.3.0",
"description": "Utility to keep Git repositories fresh",
"global": true,
"repo": "imsky/git-fresh",
"install": "sudo ./install.sh"
"install": "sudo ./install"
}