I love using the Git branching model outlined by Vincent Driessen. My flow is almost identical to what he has described except for where the feature branches are stored. Specifically he states:
Feature branches typically exist in developer repos only, not in origin.
I’m a little less trusting with feature branches and instead often push them to the central remote repository. For me, I fear that days of work could be lost by keeping the work solely on my repo until it is ready to be merged back into the develop branch. I can imagine my repository being corrupted, my hard drive dying or my computer being stolen all causing work loss. I don’t like to leave my hard work to Murphy’s law.
Now one could use a backup strategy to mitigate this issue and I do highly recommend doing this. I have used CrashPlan for years and it has saved me a few times, making CrashPlan worth every penny. However, I also like to know there is a central Git repository holding my code (again a trust issue). Plus some companies will not allow their code to be placed on any server outside of their network.
Since myself and my entire team have chosen to place our “feature-*” branches on our central remote repository, it has caused a small issue. We find that we end up with a lot of old and forgotten branches on this remote repository as well as our local machines. Of course Git is great at this task of removing the old branches.
Delete Local & Remote Branches
We can remove the remote branch by using the command:
git push origin --delete <branchName>
Then we can remove the local branch with the command:
git branch -d <branchName>
Great, problem solved I can run those two commands each time I’m done working on a feature. But wait, I don’t want to remember those two commands and I want to run only one command. So, I put together a couple bash functions that will make this easier. Just drop these functions in your ~/.bashrc
file or in the appropriate dotfiles directory if you happen to be using my Dot File Manager.
function confirm () {
# call with a prompt string or use a default
read -r -p "${1:-Are you sure? [y/N]} " response
case $response in
[yY][eE][sS]|[yY])
true
;;
*)
false
;;
esac
}
function git-delete-branch () {
if [ "$#" -ne 1 ]; then
printf "Usage: $FUNCNAME branchName\nWill delete the specified branch from both the local repository and remote\n";
return 1;
fi
echo "Delete the branch '$1' from your local repository?" && confirm && git branch -d $1;
echo "Delete the branch '$1' from the remote repository?" && confirm && git push origin --delete $1;
}
After adding these functions don’t forget to use the source command to load the functions into your shell.
Now a branch can be easily deleted from both the local and remote repository or just one of them by executing the command:
git-delete-branch <branchName>
Delete Merged Branches
Since we have multiple developers all pushing their branches to the central repository, we often find that over time we start to get a long list of orphaned branches (branches that no one is working on anymore). Any easy way to clean up most of these branches is with the following command which will show the branches that have already been merged into your current branch.
git branch --merged
Then each branch can be manually deleted with the command:
git push origin --delete <branchName>
Again, I like things simple so I put together the following function to streamline the process:
function git-delete-merged-branches () {
echo && \
echo "Branches that are already merged into $(git rev-parse --abbrev-ref HEAD) and will be deleted from both local and remote:" && \
echo && \
git branch --merged | grep feature && \
echo && \
confirm && git branch --merged | grep feature | xargs -n1 -I '{}' sh -c "git push origin --delete '{}'; git branch -d '{}';"
}
Make sure you use the the confirm
function pasted above.
Another tool
Another possible solution to the above stated problem is to use the git-flow tool. At first glance it seems to be a handy tool to automate many of the tasks in the GitFlow process.
However, in my short experience with it, I found it doing things I didn’t expect. I then checked the github repository and noticed an unhealthy amount of open issues (175) and pull requests (78) with the last commit date being September of 2012. This project is officially dead in my book.
More recently, I have found out that there is another fork of this project that is being kept up-to-date. It’s called git-flow (AVH Edition). This one might have more potential.
However, I think the GitFlow approach is easy enough to carry out with the standard Git tool that I have not yet taken the time to test out this newer git-flow (AVH Edition) tool.
Have you used the newer git-flow tool? What are your experiences with it? Do you have any other git commands or tools that have helped with your day-to-day Git operations?