Skip to content

Instantly share code, notes, and snippets.

@nickboldt
Last active February 14, 2020 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickboldt/4111850 to your computer and use it in GitHub Desktop.
Save nickboldt/4111850 to your computer and use it in GitHub Desktop.
script to automate git workflow, using topic branches & PRs
#!/bin/bash
# 4 steps in git workflow: prepare for work, (do work), pull-request, apply pull-request, drop topic branch
#alias gw1='~/bin/gitwork.sh 1 -t $topic -b $branch'
# do work after step 1
#alias gw2='~/bin/gitwork.sh 2 -t $topic -b $branch'
#alias gw3='~/bin/gitwork.sh 3 -t $topic -b $branch'
#alias gw4='~/bin/gitwork.sh 4 -t $topic -b $branch'
usage ()
{
echo "Usage: $0 <stepNumberOrName1> <stepNumberOrName2> <...> -t topic-branch -b branch -u username-for-github-fork"
echo "Example: $0 -s 1 -t jbide-1234 -b master -u nickboldt"
echo "Example: $0 -s 2 -s 3 -s 4 -t jbide-1234 -b master -u nickboldt"
exit 1;
}
if [[ $# -lt 1 ]]; then
usage;
fi
gituser=${GITUSER}
others=""
force="" # force a change to github with -f
# read commandline args
while [[ "$#" -gt 0 ]]; do
case $1 in
'-t') topic="$2"; shift 1;;
'-b') branch="$2"; shift 1;;
'-u') gituser="$2"; shift 1;;
'-s') steps="$steps $2"; shift 1;;
'-f') force="-f"; shift 0;;
*) others="$others,$1"; shift 0;;
esac
shift 1
done
if [[ ! $gituser ]]; then
echo "gituser is not set!"; exit 1
fi
if [[ "$others" != "" ]]; then
others=${others:1}; # echo $others
topic=${others%%,*}; # echo $topic
branch=${others##*,}; # echo $branch
# echo "-------"
fi
if [[ ! $topic ]]; then
echo "topic is not set!"; exit 1
fi
if [[ ! $branch ]]; then
echo "branch is not set!"; exit 1
fi
if [[ ! $steps ]]; then
echo "no step(s) selected!"; exit 1
fi
export topic=${topic}
export branch=${branch}
echo ""
echo "export topic=$topic"
echo "export branch=$branch"
echo ""
for step in $steps; do
if [[ $step -eq 1 ]] || [[ $step == "prepare" ]]; then
# step 1: prepare for work - if anything not yet committed locally, stash it before pulling w/ rebase
git stash
git checkout ${branch}
git pull origin ${branch}
git pull origin
git checkout origin/${branch} -b ${topic}
git checkout ${topic}
git stash pop
elif [[ $step -eq 2 ]] || [[ $step == "pullrequest" ]]; then
# step 2: pull-request
numCommits=`git status | egrep "by [0-9]+ commit" | sed "s/.\+by \([0-9]\+\) commit.*/\1/"`
if [[ $numCommits -gt 1 ]]; then
#squash commits
echo ""
echo "Squash commits:"
echo " git rebase -i HEAD~$numCommits"
echo ""
git rebase -i HEAD~$numCommits
if [[ "$?" != "0" ]]; then break 2; fi
fi
git pull --rebase origin ${branch}
git push ${gituser} ${topic} ${force}
parentProject=`git remote -v | grep origin | grep push | sed "s/.\+github.com\(:\|\/\)\(.\+\)\/.\+/\2/"`
thisProject=`git remote -v | grep origin | grep push | sed "s/.\+github.com\(:\|\/\)\(.\+\)\/\(.\+\)\.git.\+/\3/"`
# to do a 'hub pull-request' you must install hub first: https://github.com/defunkt/hub#readme
# alternatively, you can do a pull request in your browser from https://github.com/${gituser}/devstudio-<component>
lastCommitComment="$(git log -1 --pretty=%B)"
if [[ ${lastCommitComment:45} ]]; then
msgTitle=${lastCommitComment:0:45} # first 45 chars
msgTitle=${msgTitle% *} # no partial words
hub pull-request -o -f -m "${msgTitle}...
${lastCommitComment}" -b ${parentProject}:${branch} -h ${gituser}:${topic}
else
hub pull-request -o -f -m "${lastCommitComment}
${lastCommitComment}" -b ${parentProject}:${branch} -h ${gituser}:${topic}
fi
echo ""
echo " >> Pull Request: https://github.com/${parentProject}/${thisProject}/pulls/${gituser}"
echo " >> Topic Branch: https://github.com/${gituser}/${thisProject}/commits/${topic}"
echo " >> Origin Branch: https://github.com/${parentProject}/${thisProject}/commits/${branch}"
echo " >> JIRA / Topic: https://issues.jboss.org/browse/${topic}"
echo ""
elif [[ $step -eq 3 ]] || [[ $step == "apply" ]]; then
# step 3: apply pull-request
git checkout origin/${branch} -b ${branch}; git checkout ${branch}
git pull --rebase origin ${branch}
git checkout origin/${branch} -b ${topic}; git checkout ${topic}
git rebase ${branch}; git checkout ${branch}; git rebase ${topic}
git push origin ${branch}
parentProject=`git remote -v | grep origin | grep push | sed "s/.\+github.com\(:\|\/\)\(.\+\)\/.\+/\2/"`
thisProject=`git remote -v | grep origin | grep push | sed "s/.\+github.com\(:\|\/\)\(.\+\)\/\(.\+\)\.git.\+/\3/"`
echo ""
echo " >> Pull Request: https://github.com/${parentProject}/${thisProject}/pulls/${gituser}"
echo " >> Origin Branch: https://github.com/${parentProject}/${thisProject}/commits/${branch}"
echo " >> JIRA / Topic: https://issues.jboss.org/browse/${topic}"
echo ""
elif [[ $step -eq 4 ]] || [[ $step == "droptopic" ]]; then
# step 4: drop topic branch
git checkout ${branch}
git push ${gituser} :${topic}
git branch -d ${topic} && export topic=
git pull ${gituser} ${branch} -p
git pull origin ${branch} -p
git branch -a
fi
done
~/bin/gi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment