-
-
Save dkirrane/92bb0751153f321e1610b63af18ef072 to your computer and use it in GitHub Desktop.
A bash script to batch git cherry-pick of many commits from a single source branch. It can become a new git command if you save it in your path with a name like git-quickpick. Then, you can run it like so `git quickpick foo/bar'. Very handy, that.
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 | |
# Author: Thomas Berezansky <[email protected]> | |
# Author: Jason Stephenson <[email protected]> | |
# | |
# Feel free to use and to share this script in anyway you like. | |
# This script is intended as a shortcut for the git cherry-pick | |
# command when you have several commits that you want to cherry-pick | |
# into your local branch from another branch. It often results in a | |
# cleaner commit history than simply doing a git merge. | |
# It can be run in two ways and either method takes an optional | |
# parameter, -s. If provided the -s parameter will add your git | |
# signature to each incoming commit as they are cherry-picked. This | |
# is a handy way to sign off on someone else's commits in bulk when | |
# your project has a policy of requiring sign offs on anything going | |
# into the main git repository. If you supply the -s parameter, it | |
# should come before any branch or commit arguments on the command | |
# line. | |
# The simpler way to run this script is to simply supply the branch | |
# name whose commits you want to cherry-pick into your current branch. | |
# For instance, if you want to cherry-pick the commits from branch | |
# `bar' of remote `foo' that do not exist in your current branch you | |
# would use the following: | |
# | |
# quickpick foo/bar | |
# | |
# or | |
# | |
# quickpick -s foo/bar | |
# | |
# to include your sign off. | |
# The other way to use this script is to supply start and end git | |
# commit hashes. This is useful if there are commits on the external | |
# branch that you don't want, and you only want those from start to | |
# end. For example, if you want all commits between aef2247 and | |
# c6e1234, then you would use the following: | |
# | |
# quickpick aef2247 c6e1234 | |
# | |
# When used in this way, the script will retrieve the commits via the | |
# git log command in reverse order so that commits are applied in the | |
# proper order, if later commits depend on earlier commits. | |
# Should you run into a conflict while cherry-picking, you would | |
# resolve in the usual way. Should you still have outstanding commits | |
# left to pull in, you may pickup where you left off by using the | |
# special argument `--continue.' Even if you believe that your | |
# conflict occurred in the final cherry-pick, it won't hurt to use the | |
# --continue argument as a precaution against missing any commits. | |
# The script keeps track of the commits that have been cherry-picked | |
# as it runs, and so it would be safe to run --continue when there are | |
# none left. | |
if [ "$1" == "-s" ]; then | |
SIGN="-s" | |
shift | |
else | |
SIGN="" | |
fi | |
START=${1:-'FAIL'} | |
END=${2:-'CHERRY'} | |
if [ "$1" == 'FAIL' ]; then | |
echo "NEED SOURCE BRANCH" | |
exit 1; | |
fi | |
if [ "$START" == '--continue' ]; then | |
COMMITS=`cat ~/.git-cherrypick-resume-commits` | |
SIGN=`cat ~/.git-cherrypick-resume-sign` | |
elif [ "$END" == 'CHERRY' ]; then | |
COMMITS=`git cherry HEAD $START | grep ^+ | cut -f2 -d' '` | |
else | |
COMMITS=`git log --pretty=oneline --reverse $START...$END | cut -f1 -d' '` | |
fi | |
if [ "$SIGN" != "-s" ]; then | |
SIGN='' | |
fi | |
for commit in $COMMITS | |
do | |
COMMITS=`echo $COMMITS | sed -e "s/.*$commit\s*//"` | |
git cherry-pick $SIGN $commit | |
if [ $? -ne 0 ]; then | |
echo $COMMITS > ~/.git-cherrypick-resume-commits | |
echo "$SIGN" > ~/.git-cherrypick-resume-sign | |
exit 1 | |
fi | |
done | |
rm -f ~/.git-cherrypick-resume-commits ~/.git-cherrypick-resume-sign | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment