采用一个类似使用 Subversion 或其他集中式的系统时会使用的工作流程。

假设有一个开发者 John,另一个开发者 Jessica,以及一个远程仓库。

首先 John 克隆了远程仓库的内容并做了一些提交:

# John's Machine
$ git clone john@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim lib/simplegit.rb
$ git commit -am 'remove invalid default value'
[master 738ee87] remove invalid default value
 1 files changed, 1 insertions(+), 1 deletions(-)

而此时,Jessica 也进行克隆并提交一些改动,且先于 John 推送到远程仓库中:

# Jessica's Machine
$ git clone jessica@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim TODO
$ git commit -am 'add reset task'
[master fbff5bc] add reset task
 1 files changed, 1 insertions(+), 0 deletions(-)
 
$ git push origin master
...
To jessica@githost:simplegit.git
   1edee6b..fbff5bc  master -> master

之后 John 想要进行推送时会发现推送失败,需要先抓取且合并 Jessica 的提交:

# John's Machine
$ git push origin master
To john@githost:simplegit.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'john@githost:simplegit.git'

尽管两个人并没有出现合并冲突,即没有编辑同一个文件,Git 也不会直接拿 John 的提交合并服务器上 Jessica 的提交。因此 John 必须先抓取 Jessica 的上游工作(即早于公共祖先的部分)并合并到自己的分支中才能提交:

$ git fetch origin
...
From john@githost:simplegit
 + 049d078...fbff5bc master     -> origin/master

抓取完成后将 master 合并到 origin/master 即自己的本地工作中:

$ git merge origin/master
Merge made by the 'recursive' strategy.
 TODO |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

测试 Jessica 的提交跟自己的合并后没有影响后,就可以进行推送了:

$ git push origin master
...
To john@githost:simplegit.git
   fbff5bc..72bbc59  master -> master

假如在 John 折腾提交的期间,Jessica 新建了一个 issue54 的分支并推进了3个提交: 那么当 Jessica 重新拉取仓库内容时,就会变成: 需要将 John 的工作合并到自己的工作中才能提交,因此需要先找出来那些是自己还没合并的部分,可以使用 git log 的提交区间筛选 来快速查看:

$ git log --no-merges issue54..origin/master
commit 738ee872852dfaa9d6634e0dea7a324040193016
Author: John Smith <jsmith@example.com>
Date:   Fri May 29 16:01:27 2009 -0700
 
   remove invalid default value

这里是只显示 origin/master 分支的内容而不显示 issue54 的内容,于是只剩下 738ee 一个提交需要合并。(72bcc 只是合并提交,没有做修改)

Jessica 在提交完自己的工作后,可以合并 issue54origin/master 两个分支到 master。(如果 issue54 的工作已经完成的话,否则就是只合并 origin/masterissue54

$ git merge issue54
Updating fbff5bc..4af4298
Fast forward
 README           |    1 +
 lib/simplegit.rb |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)
 
$ git merge origin/master
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
 lib/simplegit.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git push origin master
...
To jessica@githost:simplegit.git
   72bbc59..8059c15  master -> master

此时如果 John 没有更多的推送,Jessica 就可以正常推送到服务器,John 也可以拉取到对应的内容,同样也需要将 Jessica 的工作合并到自己的分支中后才能提交。