You are viewing gitster

March 9th, 2009


Previous Entry Add to Memories Share Next Entry
01:50 am - Fun with remote branches (2)
The simplest way outlined in the first installment assumed that you complete your topic branch to perfection without talking to others, but in real life, you are not always capable to do so, and you would need help from others.

Suppose Alice and Bob need to work together on a theme and they need to share a topic branch.  There are three ways to do this.

(1) Sharing the topic branch in a peer-to-peer way

Alice and Bob would initialize their work repositories this way:
alice$ cd /home/alice
alice$ git clone /git/projects/hello.git hello
alice$ cd hello

bob$ cd /home/bob
bob$ git clone /git/projects/hello.git hello
bob$ cd hello
Suppose Alice goes first and starts working on this shared theme.  She creates a topic branch for implementing a new feature:
alice$ git checkout -b feature-42
alice$ edit, test, work, ... 
Alice cannot finish this theme alone, and Bob helps her.  First, he picks up from the point where she managed to reach:
bob$ git fetch /home/alice/hello feature-42
bob$ git checkout -b feature-42 FETCH_HEAD
bob$ edit, test, work, ...
bob$ git commit
They both work, perhaps independently, perhaps together. When Bob thinks what he has done so far would help Alice, he tells Alice that his feature-42 branch is ready for her to pick up.  Alice may be doing her own work when she hears this, but once she concludes whatever she was in the middle of, she can pick up what Bob did to help her, like this:
alice$ git pull /home/bob/hello feature-42
Bob can later help Alice again by first picking up her work:
bob$ git pull /home/alice/hello feature-42
bob$ edit, test, work, ...
bob$ git commit
After going back and forth for a while, their collaboration will hopefully come to completion.  Then the merged result can be pushed back to the shared repository, in the same way as if Alice worked on the topic alone without help from anybody:
alice$ git checkout master
alice$ git pull
alice$ git merge feature-42
alice$ git push origin master
Of course, commits made by Bob will record him as the author, so people can notice that they collaborated and Bob gets his share of the credit, but two important points to notice here are that the steps necessary for the final integration is the same as described in the previous entry where you worked alone to complete the topic, and that the two managed to collaborate without cluttering the central shared repository and other people who were not involved in this topic did not even had to notice.

Sharing topic branches between repositories this way can only work when the work repositories are somehow accessible.  In this example, Alice and Bob worked on the same machine and presumably they were in the same group to allow them to read from each other's repository. If this cannot be arranged, you have to use some other ways.  Read on.

(2) Sharing the topic branch via the central repository

Alice and Bob could share the topic branches between them by going through the central shared repository.  The workflow is similar to the previous one.  First Alice creates a topic branch for implementing a new feature:
alice$ git checkout -b feature-42
alice$ edit, test, work, ... 
Alice cannot finish this theme alone, and needs to ask Bob to help her.  With this workflow, you do not share topic branches directly among yourselves, so Alice publishes the topic to the central shared repository:
alice$ git push origin feature-42
Then Bob can pick up the point where she managed to reach:
bob$ git fetch
bob$ git checkout -b feature-42 origin/feature-42
bob$ edit, test, work, ...
bob$ git commit
They both work, perhaps independently, perhaps together. When Bob thinks what he has done so far would help Alice, he publishes what he did on his feature-42 branch for her to pick up:
bob$ git push origin feature-42
Alice may be doing her own work when she hears about Bob's work, but once she concludes whatever she was in the middle of, she can pick up what Bob did to help her, like this:
alice$ git fetch origin
alice$ git rebase origin/feature-42
This time Alice used "rebase", but "merge" is also fine. It is a matter of taste and there is no cut-and-dried way to tell which one is better for a local integration of your own work like this.

After going back and forth for a while, their collaboration will hopefully  come to completion.  Then the merged result can be pushed back to the shared repository, in the same way as if Alice worked on the topic alone without help from anybody:
alice$ git checkout master
alice$ git pull
alice$ git merge feature-42
alice$ git push origin master
This workflow is the only one that can be used when you are using a centralized version control system like CVS or Subversion, and for that reason, it may be the most familiar to novice git users who recently migrated from such systems.

A major drawback of this workflow is that the feature-42 branch, which nobody other than Alice and Bob needs to even know about, is shown to everybody, only for these two to be able to share it.  Even if the work done on feature-42 is not of a private nature, it is unnecessary to show it to people who do not need to know, and more importantly, publishing such a branch that is not universally interesting means you force others to be aware of it by cluttering the central shared repository.  In other words, this workflow is not fully taking advantage of distributedness of git.

Regrettably, many projects seem to do use this workflow, and it is a major source of "I want to push only the current branch", which is a misguided feature request (even though we do have a way to let you do so).

(3) Sharing by publishing at one's own public repository

Instead of using the shared central repository, Alice and Bob can use their own public repositories to exchange the work done on the shared topic branch to collaborate.  In addition to her work repository, Alice will prepare her own public repository and register it as remote "pub" to her work repository:
alice$ cd /home/alice
alice$ git clone /git/projects/hello.git hello
alice$ mkdir -p /git/projects/alice/hello.git
alice$ cd /git/projects/alice/hello.git && git init --bare
alice$ cd /home/alice/hello
alice$ git remote add pub /git/projects/alice/hello.git
Bob will do the same (just replace "alice" with "bob" in the above command sequence).

Again, Alice will work first on feature-42, and when she needs help from Bob, she publishes what she achieved so far to her public repository:
alice$ git checkout -b feature-42
alice$ edit, work, ...
alice$ git commit
alice$ git push pub feature-42
Bob picks it up from her public repository, works on it, and publishes what he did to his public repository:
bob$ git remote add alice /git/projects/alice/hello.git
bob$ git fetch alice
bob$ git checkout -b feature-42 alice/feature-42
bob$ edit, work, ...
bob$ git commit
bob$ git push pub feature-42
Note that the name "pub" for Alice and Bob refers to different repositories.  When Alice wants to receive what Bob did, she integrates from Bob's public repository:
alice$ git remote add bob /git/projects/bob/hello.git
alice$ git fetch bob
alice$ git merge bob/feature-42
They can keep working together without disturbing others at the shared central repository this way.  Once their topic is complete, one of them can do the honors:
alice$ git checkout master
alice$ git pull
alice$ git merge feature-42
alice$ git push origin master
This workflow, especially when a repository hosting service such as repo.or.cz, github or gitorius is used to house the public repository of each participant, is a truly distributed way to collaborate by allowing Alice and Bob to work from anywhere on the globe.  Among the three workflows discussed here, this one takes advantage of the distributedness of git the most.


Addendum in another installment...

Tags:

(4 comments | Leave a comment)

Comments:


From:Jakub Narębski [openid.pl]
Date:March 9th, 2009 10:32 am (UTC)

git pull --rebase

(Link)
Why not use "git pull --rebase" instead of fetch + rebase, just like one would use "git pull" usually, rather than fetch + merge?
From:(Anonymous)
Date:March 9th, 2009 07:29 pm (UTC)

Re: git pull --rebase

(Link)
Because that is just an immaterial shortcut, and having to explain it disrupts the flow of the description of the workflow?
From:(Anonymous)
Date:March 10th, 2009 03:52 am (UTC)

Where does the email flow fit?

(Link)
If Bob and Alice would use git format-patch and git am they would not need to do the remote repository setup. What are the pros and cons of using email? Are there less features provided by git for the merging or is it just outside this discussion?

Thanks!!!
[User Picture]
From:gitster
Date:March 10th, 2009 10:00 am (UTC)

Re: Where does the email flow fit?

(Link)
Alice and Bob can exchange e-mailed patches to do something similar, but it is fundamentally different in one aspect.

Fetch/pull style of integration is about sharing the history. Patch/apply style of collaboration is about growing two independent histories whose trees hopefully will converge. Alice may say "Here is what I did", and Bob will apply her patches to his repository, but that does not recreate the history Alice has. It creates a new, parallel history that is different from Alice, but records (hopefully) the same tree.

This affects the final integration stage the most. Once Alice does the honors to push the final result to the shared central repository, Bob should not merge his remainder with it. If he still has some leftover that he wants to integrate on top of what Alice merged and pushed back on the master branch, he needs to rebase (he could merge, and git will notice that two histories are different but results in the same tree and it will cleanly merge them, but it does not change the fact that the resulting history will have two identical-looking commits that represents the two histories) his remaining changes.
gitster's journal - Fun with remote branches (2)

> Recent Entries
> Archive
> Friends
> Profile

Links
Pages at the k.org
Gifts
貢ぎ物
The latest blog by Gitster

> Go to Top
LiveJournal.com