Wednesday, September 30, 2009

Effectively publishing branches with Git / Deleting remote branches

We recently ran into some problems when trying to push branches to a central remote to share changes with each other. We were following this workflow:

1. Create a local branch: git checkout -b feature
2. Make some changes.
3. Decide that a coworker should see this feature branch: git push origin feature
4. Make more changes.
5. Push those changes: git push

At this point git push may return an error or try to do something very wrong. Those of you more experienced with git have already spotted the problem. At no point did we tell git that our local branch is now tracking the new remote branch we published! This prevents us from running git push/pull without arguments.

Some users use the following workflow to get around this problem:
1. Create a remote branch: git push origin master:refs/heads/feature
2. Checkout remote branch: git checkout -b feature origin/feature (--track is default when the start point is a remote branch)

I don't like this workflow though. It assumes that I'm connected to the internet where git is trying to leverage disconnected workflows. It also assumes that I know when I create the branch that I'm going to want/need to share it. This isn't always true.

I feel that the right solution to this problem is to update the git config with the information it needs to start tracking the remote branch. Doing this by hand (either editing .git/config or using the git config command) is error prone at best. I was going to write a script until I realized that I already had the tool installed that I needed.

Let me introduce you to William's miscellaneous git tools.

Once I've installed git-publish-branch, my workflow looks like this:
1. Create a local branch: git checkout -b feature
2. Make some changes.
3. Decide that a coworker should see this feature branch: git publish-branch
(Without arguments publish-branch pushes the current branch to origin.)
4. Make more changes.
5. Push those changes: git push

This works correctly. You can also check to see if you're tracking the right branch and if you're in sync with the humorously named git-wtf from the same website.

Bonus points: Run "git config --global color.ui auto" for fun colors from these commands.



The other thing we discovered is that when we delete remote branches (with "git push origin :branch-to-delete"), the person who did the delete has their remote tracking branch (not the same as the remote branch itself) deleted but others who have run git fetch at some point still have that stale remote tracking branch. This can be cleaned up by running "git remote prune origin" periodically. My desire would be to get a notification of a deleted branch when I run git fetch but that's not how it works.

No comments: