Skip to content

Instantly share code, notes, and snippets.

@mchaver
Created February 25, 2017 14:07
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 mchaver/69020484c3dc6160801f98ee8739e6ac to your computer and use it in GitHub Desktop.
Save mchaver/69020484c3dc6160801f98ee8739e6ac to your computer and use it in GitHub Desktop.
Help you switch git branches and maintain a .stack-work directory for each branch.
#!/bin/bash
# file: switch-branch.sh
# this program helps you switch between git branches and maintaining a
# stack-work directory for each branch. WARNING: .stack-work dirs may be large
# so its a good idea to occasionally remove them.
# check if you can switch out of the current branch or not
# http://stackoverflow.com/a/3879077
require_clean_work_tree () {
# Update the index
git update-index -q --ignore-submodules --refresh
err=0
# Disallow unstaged changes in the working tree
if ! git diff-files --quiet --ignore-submodules --
then
echo >&2 "You cannot switch branches: you have unstaged changes."
git diff-files --name-status -r --ignore-submodules -- >&2
err=1
fi
# Disallow uncommitted changes in the index
if ! git diff-index --cached --quiet HEAD --ignore-submodules --
then
echo >&2 "You cannot switch branches: your index contains uncommitted changes."
git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2
err=1
fi
if [ $err = 1 ]
then
echo >&2 "Please commit or stash them before running this script again."
exit 1
fi
}
# this program requires one command line argument <target_branch>
if [[ $# -eq 0 || $# -gt 1 ]] ; then
printf "Usage:\n swtich-branch.sh <target_branch>\n"
exit 1
fi
target_branch=$1
# if target_branch does not exist in your local git, then exit
if ! [[ $(git branch --list ${target_branch}) ]]; then
printf "The branch '${target_branch}' does not exist. Provide the name of an local existing branch or try running 'git fetch' first.\n"
exit 0
fi
current_branch=$(git rev-parse --abbrev-ref HEAD)
# do not need to do anything if we are already on the target_branch.
if [[ $current_branch == $target_branch ]]; then
printf "You are already on the branch '${target_branch}'. There is not need to move the .stack-work directory\n"
exit 1
fi
require_clean_work_tree
# if .stack-work exists in your current working branch, then move it into
# a dir with the current branch name tagged to the end.
if [[ -d ./.stack-work ]]; then
printf "Moving .stack-work to .stack-work-${current_branch}\n"
mv .stack-work ".stack-work-${current_branch}"
else
printf "The current branch '${current_branch}' does not have a .stack-work directory\n"
fi
# if there is a ,stack-work with a tag for the target branch, then rename it
# as stack-work. Otherwise, compy the directory we just move from .stack-work
# into .stack-work if it exsts.
if [[ -d "./.stack-work-${target_branch}" ]]; then
printf "Moving .stack-work-${target_branch} to .stack-work.\n"
mv ".stack-work-${target_branch}" .stack-work
else
if [[ -d "./.stack-work-${current_branch}" ]]; then
printf "The directory .stack-work-${target_branch} does not exist. Copying .stack-work-${current_branch} to .stack-work\nThis may take a while..."
cp -rf ".stack-work-${current_branch}" .stack-work
else
printf "The directories .stack-work-${target_branch} and .stack-work-${current_branch} do not exist. No .stack-work directories will be manipulated\n"
fi
fi
# finally, checkout the target branch
git checkout $target_branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment