假设 John 与 Jessica 在一个特性(featureA)上工作, 同时 Jessica 与第三个开发者 Josie 在第二个特性(featureB)上工作。

公司使用了一种整合-管理者工作流程,独立小组的工作只能被特定的工程师整合, 主仓库的 master 分支只能被那些工程师更新。 在这种情况下,所有的工作都是在基于团队的分支上完成的并且稍后会被整合者拉到一起。

目前,Jessica 以及克隆完整体仓库,并打算决定先实现 featureA,于是创建新分支并推进了一些提交:

# Jessica's Machine
$ git checkout -b featureA
Switched to a new branch 'featureA'
$ vim lib/simplegit.rb
$ git commit -am 'add limit to log function'
[featureA 3300904] add limit to log function
 1 files changed, 1 insertions(+), 1 deletions(-)

Jessica 觉得需要将工作共享给 John,于是推送 featureA 分支到服务器上(只有整合工程师有 master 的推送权限):这里的 -u 是在推送的同时绑定本地 featureA 与远程分支 origin/featureA 关联,下次再提交时只需要 git push 即可

$ git push -u origin featureA
...
To jessica@githost:simplegit.git
 * [new branch]      featureA -> featureA

之后 Jessica 打算去实现 featureB 的功能,首先重新拉取 orgin 的内容,再创建一个基于 origin/master 的分支并切换上去做了一些提交:

# Jessica's Machine
$ git fetch origin
$ git checkout -b featureB origin/master
Switched to a new branch 'featureB'
$ vim lib/simplegit.rb
$ git commit -am 'made the ls-tree function recursive'
[featureB e5b0fdc] made the ls-tree function recursive
 1 files changed, 1 insertions(+), 1 deletions(-)
$ vim lib/simplegit.rb
$ git commit -am 'add ls-files'
[featureB 8512791] add ls-files
 1 files changed, 5 insertions(+), 0 deletions(-)

而在 Jessica 推送 featureB 之前,Josie 说已经做了一些工作在服务器新建的 featureBee 分支,因此 Jessica 需要先将服务器中的 featureBee 合并到自己的 featureB 并重新推送到服务器的 featureBee 中。

假设 Jessica 还在 featureB 分支上,需要先拉取并合并到 origin/featureB 中:

$ git fetch origin
...
From jessica@githost:simplegit
 * [new branch]      featureBee -> origin/featureBee
$ git merge origin/featureBee
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
 lib/simplegit.rb |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

可以发现并没有合并冲突出现,目前本地的 featureB 就是合并过的分支,而推送时为了在服务器保持一致,需要指定名称:这里和之前一样,使用-u参数后下次推送 featureB 分支时就会自动推送到 origin/featureBee

$ git push -u origin featureB:featureBee
...
To jessica@githost:simplegit.git
   fba9af8..cd685d1  featureB -> featureBee

之后 John 推送了一些改动到 featureA,Jessica 先抓取更新并查看:

$ git fetch origin
...
From jessica@githost:simplegit
   3300904..aad881d  featureA   -> origin/featureA
$ git log featureA..origin/featureA
commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
Author: John Smith <jsmith@example.com>
Date:   Fri May 29 19:57:33 2009 -0700
 
    changed log output to 30 from 25

如果觉得可以,就将其合并到本地的 featureA 分支上:

$ git checkout featureA
Switched to branch 'featureA'
$ git merge origin/featureA
Updating 3300904..aad881d
Fast forward
 lib/simplegit.rb |   10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)

最后,Jessica 可能想要对整个合并后的内容做一些小修改, 于是她将这些修改提交到了本地的 featureA 分支,接着将最终的结果推送回了服务器。

$ git commit -am 'small tweak'
[featureA 774b3ed] small tweak
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git push
...
To jessica@githost:simplegit.git
   3300904..774b3ed  featureA -> featureA

这时,Jessica、Josie 与 John 通知整合者服务器上的 featureAfeatureBee 分支准备好整合到主线中了。 在整合者将这些分支合并到主线后,就能一次将这个新的合并提交抓取下来,历史看起来就会像这样: