-
-
Save rzwitserloot/964945 to your computer and use it in GitHub Desktop.
grb-like git frontend that does all grb does and more (specifically: all-work-in-branches model)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Copyright © 2009-2013 Reinier Zwitserloot and Roel Spilker. | |
# | |
# 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. | |
# | |
ORIGIN=origin | |
MASTER=master | |
EXPLAIN=no | |
OFFLINE=no | |
if [ "$1" = "explain" ]; then | |
EXPLAIN=yes | |
shift | |
fi | |
if [ "$1" = "-o" ]; then | |
OFFLINE=yes | |
shift | |
fi | |
if [ "$1" = "--offline" ]; then | |
OFFLINE=yes | |
shift | |
fi | |
if [ "$1" = "explain" ]; then | |
EXPLAIN=yes | |
shift | |
fi | |
runCmd() { | |
if [ "$EXPLAIN" = "yes" ]; then | |
echo $* | |
else | |
$* || exit 1 | |
fi | |
} | |
gitPull() { | |
if [ "$OFFLINE" != "yes" ]; then | |
runCmd git fetch --prune | |
runCmd git merge $ORIGIN/$MASTER | |
else | |
echo "WARNING: Skipping 'git pull' due to offline mode." | |
fi | |
} | |
cmdLineHelp() { | |
echo "start Create a new local branch after updating master." | |
echo "rename renames a local branch." | |
echo "publish promotes a local branch (uploads to remote so others can track it), and then tracks it." | |
echo "track creates a new local branch that tracks the given remote branch." | |
echo "join upgrades $MASTER to include the local branch via rebase so the history does not show a merge, then deletes the branch." | |
echo "merge upgrades $MASTER to include the named branch via merge so history does show the merge, then deletes the branch." | |
echo "update refreshes $MASTER then rebases local branch on top of any changes." | |
echo | |
echo "A command may be prefixed with 'explain' to print the git commands that it'll run." | |
echo "A command may be prefixed with '-o' to avoid things that require an internet connection (push and pull)." | |
echo "Where a local branch name is omitted, the branch you're currently in is used." | |
echo "the main branch is assumed to be '$MASTER' and the head remote is assumed to be called '$ORIGIN'." | |
} | |
LOCALNAME=$2 | |
CUR_BRANCH="$(git symbolic-ref HEAD 2>/dev/null)" | |
CUR_BRANCH="${CUR_BRANCH##refs/heads/}" | |
getBranchName() { | |
if [ "$LOCALNAME" = "" ]; then | |
if [ "$CUR_BRANCH" = "" ]; then | |
echo "Missing branch name and you're not in a branch right now." | |
exit 1 | |
fi | |
if [ "$CUR_BRANCH" = "$MASTER" ]; then | |
echo "Missing branch name and you're in $MASTER right now." | |
exit 1 | |
fi | |
LOCALNAME=$CUR_BRANCH | |
fi | |
} | |
getLocalBranchName() { | |
getBranchName | |
if git branch -r | grep "$ORIGIN/$LOCALNAME$" > /dev/null; then | |
echo "Branch $CUR_BRANCH isn't local." | |
exit 1 | |
fi | |
} | |
switchTo() { | |
if [ "$1" != "$CUR_BRANCH" ]; then | |
runCmd git checkout "$1" | |
fi | |
} | |
if [ "$1" = "" ]; then | |
cmdLineHelp | |
exit 0 | |
fi | |
if [ "$1" = "start" ]; then | |
if [ "$2" = "" ]; then | |
echo "Syntax: gitc start branchName" | |
exit 1 | |
fi | |
switchTo $MASTER | |
gitPull | |
runCmd git checkout -b "$2" | |
exit 0 | |
fi | |
if [ "$1" = "rename" ]; then | |
NEWNAME="$3" | |
if [ "$3" = "" ]; then | |
LOCALNAME="" | |
NEWNAME="$2" | |
fi | |
if [ "$NEWNAME" = "" ]; then | |
echo "Syntax: gitc rename newName to rename current branch, or gitc rename oldName newName." | |
exit 1 | |
fi | |
getLocalBranchName | |
runCmd git branch -m "$LOCALNAME" "$NEWNAME" | |
exit 0 | |
fi | |
if [ "$1" = "publish" ]; then | |
if [ "$OFFLINE" = "yes" ]; then | |
echo "ERROR: 'publish' not possible in offline mode." | |
fi | |
getLocalBranchName | |
echo "Should I try to rebase $LOCALNAME first? (y/n)" | |
read REBASEFIRST | |
if [ "$REBASEFIRST" = "y" ]; then | |
switchTo $MASTER | |
gitPull | |
runCmd git checkout $LOCALNAME | |
runCmd git rebase $MASTER | |
CUR_BRANCH=$LOCALNAME | |
elif [ "$REBASEFIRST" = "n" ]; then | |
echo Skipping Rebase | |
else | |
echo "Only 'y' or 'n' are valid answers." | |
exit 1 | |
fi | |
runCmd git push $ORIGIN $LOCALNAME:refs/heads/$LOCALNAME | |
runCmd git fetch $ORIGIN | |
runCmd git config branch.$LOCALNAME.remote $ORIGIN | |
runCmd git config branch.$LOCALNAME.merge refs/heads/$LOCALNAME | |
switchTo $LOCALNAME | |
exit 0 | |
fi | |
if [ "$1" = "track" ]; then | |
TRNAME="$2" | |
if [ "$TRNAME" = "" ]; then | |
echo "Syntax: gitc track remoteBranchName" | |
exit 1 | |
fi | |
if [ "$OFFLINE" != "yes" ]; then | |
runCmd git fetch $ORIGIN | |
fi | |
runCmd git branch --track $TRNAME $ORIGIN/$TRNAME | |
runCmd git checkout $TRNAME | |
exit 0 | |
fi | |
if [ "$1" = "update" ]; then | |
getLocalBranchName | |
switchTo $MASTER | |
gitPull | |
runCmd git checkout $LOCALNAME | |
runCmd git rebase $MASTER | |
exit 0 | |
fi | |
if [ "$1" = "join" ]; then | |
if [ "$OFFLINE" = "yes" ]; then | |
echo "ERROR: 'join' not possible in offline mode." | |
fi | |
getLocalBranchName | |
switchTo $MASTER | |
gitPull | |
runCmd git checkout $LOCALNAME | |
runCmd git rebase $MASTER | |
runCmd git checkout $MASTER | |
runCmd git merge $LOCALNAME | |
runCmd git branch -d $LOCALNAME | |
runCmd git push | |
exit 0 | |
fi | |
if [ "$1" = "merge" ]; then | |
if [ "$OFFLINE" = "yes" ]; then | |
echo "ERROR: 'join' not possible in offline mode." | |
fi | |
getBranchName | |
switchTo $MASTER | |
gitPull | |
runCmd git merge $LOCALNAME | |
runCmd git push | |
runCmd git branch -d $LOCALNAME | |
if git branch -r | grep "$ORIGIN/$LOCALNAME" > /dev/null; then | |
runCmd git push $ORIGIN :refs/heads/$LOCALNAME | |
fi | |
exit 0 | |
fi | |
echo Unknown command: $1 - rerun this script with no arguments to see available commands. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment