为艺术而技术

Git Pull, Merge and Rebase

May 22, 2019

三种操作都可以进行代码的整合。

Merge

Merge by Fast-forward

Fast-forward 这种类型就相当于把主线直接提前到和merge近来的支线的位置(master -> hotfix),是最简单的。

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

Merge by Three-way

所谓三方,如下所示

ThreeWay1

通过生成一个真正的改变的集合体(snapshot C6)来完成整合。

ThreeWay2

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

Rebase

对于三方(基方,分之一,分支二)整合,通过rebasing同样可以做到。本质就是把从基方开始一方的所有更改都重新加到另一方上面。

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

在这里,就是把C4的更改加到C3上面进而创造出C5并指向它, 也就是先把你所在的那个分支上所有的更改都保存到临时文件上去,然后把当前分支指向你要base的那个分支(名义上你当然还在自己的分支上),并把临时文件的更改都加上去。

Rebasing1

然后你可以把master分支fast forward到最新

$ git checkout master
$ git merge experiment

Rebasing2

一个复杂点的例子

Rebasing3

告诉系统把client与Server不一样的东西找到并rebase到master上去。

$ git rebase --onto master server client

Rebasing3

优点

很清晰的提交历史,线性的。

禁忌

不要在别人工作的分支上使用rebase。

Do not rebase commits that exist outside your repository and people may have based work on them.

换句话说,千万不要在公共分支上使用rebase。

Once you understand what rebasing is, the most important thing to learn is when not to do it. The golden rule of git rebase is to never use it on public branches.

Pull

git pull == git fetch + git merge [origin/master] git pull —rebase == git fetch + git rebase

有人认为在本地应该永远使用rebase,这样使得log非常清晰。如果你也赞同,可以通过如下设置使其变成默认行为。

git config branch.autosetuprebase always

如果是已有分支

git config branch.YOUR_BRANCH_NAME.rebase true

如果临时想用merge

git pull --no-rebase

致谢


Qingfei Yuan

Written by Qingfei Yuan who builds useful things.

© 2019 - 2020 yuanqingfei
Creative Commons License