Created
April 15, 2020 00:05
-
-
Save brettbuddin/9f112f69fc8b2bd439f26ac3ae9db91f to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
# 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