Branching with Git

Now that jQuery UI is on Github, I need to learn how to branch and merge with Git – and not just local branches, but also pushing branches to Git so that others can work on them.

The chapter on branching from Pro Git is a good start for learning branching in Git. And the next step, remote branches, has its own chapter as well.

In order to be able to repeat the necessary steps, I’ll describe here how to create a local branch, commit some changes, and then push that branch to your Github repository.

The following command creates a new branch and switches to that:

git checkout -b "newbranch"

To see the local branches and which one is the active one, use:

git branch

That should now display a list like

master
* newbranch

Where the asterix marks the new active branch. With that, you can modify stuff in the branch. Then, to add all modified files to a commit, along with a message:

git commit -a -m "Message along with modifications"

Now comes the interesting part, pushing the branch back to the remote repository, Github in my case:

git push origin tooltip

Git knows that “origin” refers to [email protected]:jquery/jquery-ui.git, so it’s enough to add the name of the branch.

This works so far, but isn’t optimal yet: To push from the tooltip branch, I need to use “git push origin tooltip” again. I’ve found two ways to fix this, both way to complicated for such a simple requirement.

Either manually edit your .git/config file and add the branch, you should then end up with something like this:

[branch "master"]
	remote = origin
	merge = refs/heads/master
[branch "tooltip"]
	remote = origin
	merge = refs/heads/tooltip

For my “tooltip” branch, I added the entry below the entry for “master”, and just replaced “master” with “tooltip”.

To avoid editing that config file, I found this to work:

git branch -D tooltip
git checkout --track origin/tooltip

With branch -D I forced a deletion of the local branch, then used checkout with the –track option to check it out again and have Git set up the config entries for “tracking”. There should be an easier way to do that.

Update: Apparently you can configure Git to automatically setup the tracking via:

git config --global branch.autosetupmerge true

You can leave out “–global” to apply it only to the current project. Seems to be more useful as a global setting…

-Jörn

No more comments.
  1. Things to read up on:

    1. Add actual jQuery’s master branch to a list of remotes on your tree.
    (investigate “git remote” and “git branch -a”)
    This would allow you to pull changes that happened upstream like so: “git fetch nameofshortcuttoremote” to pull the upstream changes in and investigate them locally. “git checkout master”, “git merge nameofshortcuttoremote” will finish the job.

    2. Do not publish to github branches you expect to rebase.
    (If you have active upstream, pretty all of your branches, unless you intend them to accumulate and collect dust will need to be rebased at some point. GitHub will not let you push rebased branch. You cannot seem to delete them either once published.)
    If upstream maintainers take time to review your code and accept, Try rebasing internally, and sending patches. Constantly rebasing published branches on top of new upstream code and pushing new branch up will drive you nuts.
    Try to see if upstream is welcoming to formatted patches, rebased on most current commit. This is the safest route and not as painful for you.

    3. If you are on windows, use Cygwin’s version of git with GitExtensions UI.

    4. Bibles:
    http://www-cs-students.stanford.edu/~blynn/gitmagic/
    http://progit.org/book/

    Good luck.

  2. Thanks Daniel! Since writing this post I’ve researching branching, rebasing and cherry-picking a good bit, and we’ve set up some rules to avoid cluttering branches with changes to master.