42 Commits

Author SHA1 Message Date
Ivan Malopinsky d33bde493a bump to 1.6.2 2016-03-30 12:23:19 -04:00
Ivan Malopinsky 9a061ce30b reset/rebase against remote branches 2016-03-29 11:05:34 -04:00
Ivan Malopinsky 236f95ea18 merge/rebase against local root
fix #68
2016-03-28 17:34:47 -04:00
Ivan Malopinsky 2da11516b4 1.6.1 2016-03-22 22:20:19 -04:00
Ivan Malopinsky e735f44727 integrated testing mode 2016-03-22 22:20:14 -04:00
Ivan Malopinsky 8f40e82492 1.6.0 2016-03-22 22:02:03 -04:00
Ivan Malopinsky da4e21fe5c add remote testing 2016-03-22 22:01:24 -04:00
Ivan Malopinsky 01a44ddc7c replace spaces with NULs for xargs -0 2016-03-09 22:45:08 -05:00
Ivan Malopinsky 0702c3a67b only run remote commands if remote is present, rework rebase/reset 2016-03-09 22:38:49 -05:00
Ivan Malopinsky bcde137050 bump to 1.5.0 2016-03-09 19:43:58 -05:00
Ivan Malopinsky da31f19926 Merge pull request #66 from imsky/quotes-xargs
fix xargs failure for branches with quotes in names
2016-03-08 23:40:56 -05:00
Ivan Malopinsky 2b1fb56c4a fix xargs failure for branches with quotes in names
fix #65
2016-03-08 23:40:44 -05:00
Ivan Malopinsky 4f142bf0dd update readme to include tag option 2016-02-28 00:06:48 -05:00
Ivan Malopinsky 5c76da3ebd Merge pull request #64 from imsky/stale-tags
remove local tags that do not exist on remote, fix #62
2016-02-27 18:35:53 -05:00
Ivan Malopinsky 0d632b15e1 remove local tags that do not exist on remote, fix #62 2016-02-27 18:35:29 -05:00
Ivan Malopinsky f6898b7056 1.4.0 2016-01-21 23:16:00 -05:00
Ivan Malopinsky ae2fa19df6 add [git-fresh] to logs 2016-01-20 00:00:00 -05:00
Ivan Malopinsky 2798299f11 add comments 2016-01-19 00:00:00 -05:00
Ivan Malopinsky f3fb0fc3f9 check that remote branch exists before rebasing against it 2016-01-17 00:00:00 -05:00
Ivan Malopinsky c7d9abc59e fix HEAD ref check 2016-01-16 00:00:00 -05:00
Ivan Malopinsky 80593359ca fix git directory check 2016-01-15 00:00:00 -05:00
Ivan Malopinsky 337c9679bc homebrew now supported 2015-12-08 20:13:26 -05:00
Ivan Malopinsky f18a2dc6ba add safety checks before running git-fresh 2015-12-03 20:28:04 -05:00
Ivan Malopinsky 97c7dfb4b5 bump to 1.2.3 2015-12-03 12:45:31 -05:00
Ivan Malopinsky 46a74c1b08 Merge pull request #58 from bfontaine/patch-1
install: create the parent directory if necessary
2015-12-03 12:34:50 -05:00
Baptiste Fontaine b9336549c1 install: create the parent directory if necessary
This ensures the parent directory always exists.
2015-12-03 18:28:25 +01:00
Ivan Malopinsky 30ee8139f7 make install dir an argument 2015-12-03 00:18:03 -05:00
Ivan Malopinsky 4482885845 only echo install message if copy succeeded 2015-12-02 23:54:30 -05:00
Ivan Malopinsky 615988dc01 Merge pull request #57 from imsky/remove-makefile
move install step to separate script, remove dependency on make
2015-11-27 13:12:10 -05:00
Ivan Malopinsky c9b1f5c2e0 move install step to separate script, remove dependency on make 2015-11-27 13:11:06 -05:00
Ivan Malopinsky 85ee0683eb Merge pull request #56 from imsky/fresh-local-before-rebase
Rebase current branch before rebasing against remote root branch
2015-11-27 13:06:47 -05:00
Ivan Malopinsky c48f1d592a update usage in README, add install script 2015-11-27 13:06:14 -05:00
Ivan Malopinsky 15e62530d9 suppress error on invalid option 2015-11-27 13:03:46 -05:00
Ivan Malopinsky 8e81d7276e update usage 2015-11-27 12:59:18 -05:00
Ivan Malopinsky b6d35128c4 rebase local branch against its remote self before rebasing against remote root 2015-11-27 12:57:38 -05:00
Ivan Malopinsky 6dc3f6870d Merge pull request #54 from imsky/refactor/simplify-readme
simplify readme
2015-09-24 00:43:52 -04:00
Ivan Malopinsky 28f347b89d simplify readme 2015-09-24 00:43:43 -04:00
Ivan Malopinsky a94af51b11 Merge pull request #53 from imsky/bug/fix-syntax-error
fix syntax error
2015-09-24 00:41:53 -04:00
Ivan Malopinsky b11805e886 fix syntax error 2015-09-24 00:41:43 -04:00
Ivan Malopinsky 5327cb53c9 Merge pull request #52 from imsky/feature/delete-local-stale-only-flag
delete local stale only flag
2015-09-24 00:39:01 -04:00
Ivan Malopinsky c5db0306de bump version to 1.1 2015-09-24 00:38:32 -04:00
Ivan Malopinsky a16bc0b0c8 add option to remove only local stale branches, fix #50 2015-09-24 00:38:25 -04:00
5 changed files with 167 additions and 47 deletions
-2
View File
@@ -1,2 +0,0 @@
install:
cp git-fresh /usr/local/bin
+13 -11
View File
@@ -2,23 +2,24 @@
Keep your repo fresh with one command.
* Stashes your unstaged changes
* Updates local master to match remote, prunes stale branches
* Deletes stale local and remote branches with `-f` flag
* Merges remote master into current branch with `-m` flag
* Rebases current branch against remote master with `-r` flag
* Restores your stashed changes with `-s` flag
* Wipes the slate clean with `-F` flag
## Usage
```
Usage: git fresh [-fmrsF] [remote] [root]
Usage: git fresh [-fmrtF] [-sl] [remote] [root]
By default, git-fresh will:
- 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
-s: Apply stashed changes after run
-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
-l: Only delete local stale branches
remote: remote name, origin by default
root: root branch, master by default
```
@@ -29,10 +30,11 @@ root: root branch, master by default
1. Clone or download
2. `cd git-fresh`
3. `sudo make install`
3. `sudo ./install`
### Package
* [Homebrew](http://brew.sh/): `brew install git-fresh`
* [bpkg](http://www.bpkg.io/): `bpkg install imsky/git-fresh`
## License
+147 -32
View File
@@ -1,24 +1,50 @@
#!/usr/bin/env bash
# git-fresh
# https://github.com/imsky/git-fresh
# By Ivan Malopinsky - http://imsky.co
# MIT License
usage () {
echo "Usage: git fresh [-fmrsF] [remote] [root]"
echo "-f: Delete stale local and remote branches"
echo "-m: Merge remote root into current branch"
echo "-r: Rebase current branch against remote root"
echo "-s: Apply stashed changes after run"
echo "-F: Reset local root to remote root, wipe workspace"
echo "remote: remote name, origin by default"
echo "root: root branch, master by default"
exit 1;
cat << EOD
Usage: git fresh [-fmrtF] [-sl] [remote] [root]
By default, git-fresh will:
- 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
-l: Only delete local stale branches
remote: remote name, origin by default
root: root branch, master by default
EOD
exit 0
}
say () {
echo "[git-fresh] $@" 1>&2
}
die () {
say $@
exit 1
}
error () {
echo -n "[git-fresh] error on line $1"
die "Error on line $1: $(head -n $1 $0 | tail -1)"
}
trap 'error $LINENO' ERR
while getopts "fmrsF" opt; do
while getopts ":fmrtslFT" opt; do
case $opt in
f)
FORCE_DELETE_STALE=true
@@ -29,42 +55,109 @@ while getopts "fmrsF" opt; do
r)
REBASE=true
;;
t)
TAGS=true
;;
s)
APPLY_STASH=true
;;
l)
DELETE_ONLY_LOCAL=true
;;
F)
FORCE_LOCAL_RESET=true
;;
T)
TEST=true
;;
*)
usage
break
;;
esac
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"
CURRENT=$(git rev-parse --abbrev-ref HEAD)
REMOTE=${1:-origin}
ROOT=${2:-master}
git remote update
git remote prune $REMOTE
if [[ $(git remote -v | wc -l) -gt "0" ]]; then
REMOTES=true
fi
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 checkout $ROOT > /dev/null 2>&1
if [[ "$FORCE_LOCAL_RESET" = true ]]; then
git clean -dfx
git reset --hard $REMOTE/$ROOT
else
git rebase -q $REMOTE/$ROOT
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
fi
# Compute stale branches
SMART_STALE=$(git branch -a --merged | tr -d "\* " | grep -Ev ">|$ROOT" | cat)
LOCAL_STALE=$(grep -Ev "^remotes/" <<< "$SMART_STALE" | cat)
@@ -77,49 +170,71 @@ if [[ ! -z "${SMART_STALE// }" ]]; then
if [[ ! -z "${LOCAL_STALE// }" ]]; then
STALE_BRANCHES=true
if [[ "$FORCE_DELETE_STALE" = true ]]; then
echo -n $LOCAL_STALE | xargs git branch -d 2> /dev/null
echo -n $LOCAL_STALE | tr " " "\0" | xargs -0 git branch -d 2> /dev/null
else
echo "Local stale branches found:" $(echo -n $LOCAL_STALE | tr "\n" " ")
say "Local stale branches found:" $(echo -n $LOCAL_STALE | tr "\n" " ")
fi
fi
if [[ ! -z "${REMOTE_STALE// }" ]]; then
STALE_BRANCHES=true
if [[ "$FORCE_DELETE_STALE" = true ]]; then
echo -n $REMOTE_STALE | xargs git push $REMOTE --delete
if [[ "$DELETE_ONLY_LOCAL" != true ]]; then
echo -n $REMOTE_STALE | tr " " "\0" | xargs -0 git push $REMOTE --delete
fi
else
echo "Remote stale branches found:" $(echo -n $REMOTE_STALE | tr "\n" " ")
say "Remote stale branches found:" $(echo -n $REMOTE_STALE | tr "\n" " ")
fi
fi
if [[ "$FORCE_DELETE_STALE" != true && $STALE_BRANCHES = true ]]; then
echo "Delete stale branches with: git fresh -f"
if [[ "$FORCE_DELETE_STALE" != true && "$STALE_BRANCHES" = true ]]; then
say "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 2> /dev/null
git checkout $CURRENT
if [ "$REBASE" = true ] && [ "$MERGE" = true ]; then
echo "Rebase and merge enabled, skipping both"
say "Rebase and merge enabled, skipping both"
else
if [[ "$REBASE" = true ]]; then
git rebase $REMOTE/$ROOT
fi
if [[ "$REMOTES" = true ]]; then
if [[ "$REBASE" = true ]]; then
git rebase $ROOT
fi
if [[ "$MERGE" = true ]]; then
git merge --no-edit $REMOTE/$ROOT
if [[ "$MERGE" = true ]]; then
git merge --no-edit $ROOT
fi
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
echo "Stashed changes present, apply with: git stash pop"
say "Stashed changes present, apply with: git stash pop"
fi
fi
Executable
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
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)
+2 -2
View File
@@ -1,8 +1,8 @@
{
"name": "git-fresh",
"version": "1.0.0",
"version": "1.6.2",
"description": "Utility to keep Git repositories fresh",
"global": true,
"repo": "imsky/git-fresh",
"install": "sudo make install"
"install": "sudo ./install.sh"
}