Created
February 25, 2017 14:07
-
-
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.
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 | |
# 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