Skip to content

Instantly share code, notes, and snippets.

@brettbuddin
Created April 15, 2020 00:05
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 brettbuddin/9f112f69fc8b2bd439f26ac3ae9db91f to your computer and use it in GitHub Desktop.
Save brettbuddin/9f112f69fc8b2bd439f26ac3ae9db91f to your computer and use it in GitHub Desktop.
#!/bin/bash
# Usage: git-cut-branch <name>
# Create a new branch named <name> pointed at HEAD and reset the current branch
# to the head of its tracking branch. This is useful when working on master and
# you realize you should be on a topic branch.
set -e
# bail out with message to stderr and exit status 1
die() {
echo "$(basename $0):" "$@" 1>&2
exit 1
}
# write a short sha for the given sha
shortsha() {
echo "$1" |cut -c1-7
}
# show usage
[ -z "$1" -o "$1" = "--help" ] && {
grep '^#/' "$0" |cut -c4-
exit 2
}
# first argument is the new branch name
branch="$1"
# get the current branch for HEAD in refs/heads/<branch> form
ref=$(git symbolic-ref -q HEAD)
sha=$(git rev-parse HEAD)
[ -n "$ref" ] ||
die "you're not on a branch"
# just the branch name please
current=$(echo "$ref" |sed 's@^refs/heads/@@')
[ -n "$current" ] ||
die "you're in a weird place; get on a local branch"
# figure out what branch we're currently tracking
remote=$(git config --get "branch.$current.remote" || true)
merge=$(git config --get "branch.$current.merge" | sed 's@refs/heads/@@')
# build up a sane <remote>/<branch> name
if [ -n "$remote" -a -n "$merge" ]
then tracking="$remote/$merge"
elif [ -n "$merge" ]
then tracking="$merge"
else die "$current is not tracking anything"
fi
# make sure there's no changes before we reset hard
if ! git diff-index --quiet --cached HEAD || ! git diff-files --quiet
then die "cannot cut branch with changes to index or working directory"
fi
# reset the current branch to its tracking branch, create the new branch, and
# switch to it.
git branch "$branch"
git reset -q --hard "$tracking"
git checkout -q "$branch"
git reset -q --hard "$sha"
echo "[$(shortsha "$sha")...$(shortsha $(git rev-parse $tracking))] $current"
echo "[0000000...$(shortsha $(git rev-parse HEAD))] $branch"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment