March 9th, 2009
|01:33 am - Fun with remote branches (1)|
When you collaborate with others using a shared central repository, you must have the integration branch (or branches) in the central repository. That is the point of origin that everybody will work on top. Let's call that the "master" branch. You do not have to have anything else at the shared central repository in order to take advantage of git nor its topic branches workflow.
The simplest way to collaborate using a shared central repository would go like this:
- You clone from the shared repository to create your work repository (this needs to be done only once at the start).
- You never work directly on your "master" branch. Everything you do will be done first by forking a topic branch, and you do not talk with others until you perfect it.
- Once you perfect a theme on your topic branch, you merge it to "master" and push it back to the central repository.
The first step would look like this:
$ git clone /git/projects/hello.git hello
$ cd helloAnd you can see you have only "master" branch from "git branch" output:
$ git branch
* master You will use the local "master" branch to grow the history here. The branches that are taken from the source of the cloning are kept as remote tracking branches. For example, if the shared repository had two integration branches "master" and "maint", you would see:
$ git branch -r
origin/HEAD -> origin/master
orign/masterand you can use these names to refer to the history leading to the tip of the branches that appear there, like so:
$ git log master..origin/master
$ git log origin/master..master
$ git log origin/master...master
The first form lists commits that do not appear in the local "master" but appear in the "origin/master" (that is the "master" branch at the "origin" repository --- where you cloned from). In other words, they are what others did.
The second form lists commits that do appear in the local "master" but do not appear in the "origin/master". They are what you hare still holding onto without showing others.
The last one shows both. It is often useful to use with --left-right option, like this:
$ git log --oneline --graph --left-right origin...master
One bad thing about git UI is that we tend to emphasize the size of the first one too much. If you always work on "master", it is good to know that you are behind and encourage you to catch up, but saying that to any topic branch you fork is misleading. You should not update your topic branches from where you forked from unless you have a good reason to, and "other people have new work on the branch I forked from" is never a good reason for such a merge.
But that is an unrelated tangent for the purpose of this entry.
The second step is to fork a topic branch to work on your theme.
$ git checkout -b bufgix-42 origin/master
$ edit, test, cleanup, ...
$ git commitAnd the third step, once the topic is perfected in your repository, is to merge it back to the integration branch and push it back to the shared repository. First you make sure you are up to date with respect to the shared repository:
$ git checkout master
$ git pullThis should fast forward because you are not supposed to have done anything on your master. Then:
$ git merge bugfix-42
$ review, test, convince yourself...
$ git push origin master
If your project's policy is not to have anything but the public integration branches (i.e. "master" in this example), then the default behaviour of "git push" that pushes the matching refs will also be appropriate here.
You can, optionally, rebase bugfix-42 branch on top of master before pushing it back. As long as what was done by others does not conflict with what you did while on bugfix-42 branch, it will make a cleaner history. It is not a big deal to have an extra merge commit, and such a rebase is strictly optional.
Continued to the second installment.