git 关于merge rebase(衍合)

merge  rebase都是合并分支的命令

git 关于merge rebase(衍合)_第1张图片

 

merge 之后的情形如下:

结果上c5有两个上游分支,衍合的结果c5上上游只有一个分支(这样日志更干净一些)

git 关于merge rebase(衍合)_第2张图片

另外一个选择:你可以把在 C3 里产生的变化补丁重新在 C4 的基础上打一遍。在 Git 里,这种操作叫做_衍合(rebase)_。有了 rebase 命令,就可以把在一个分支里提交的改变在另一个分支里重放一遍。

在这个例子里,可以运行下面的命令:

$ git checkout experiment ------------------切换到experiment分支

$ git rebase master -------------------把当前分支衍合到master分支上。
First, rewinding head to replay your work on top of it...
Applying: added staged command

git 关于merge rebase(衍合)_第3张图片

它的原理是回到两个分支(你所在的分支和你想要衍合进去的分支)的共同祖先,提取你所在分支每次提交时产生的差异(diff),把这些差异分别保存到临时文件里,然后从当前分支转换到你需要衍合入的分支,依序施用每一个差异补丁文件。图 3-29 演示了这一过程:git 关于merge rebase(衍合)_第4张图片

现在,合并后的 C3(即现在的 C3’)所指的快照,同三方合并例子中的 C5 所指的快照内容一模一样了。最后整合得到的结果没有任何区别,但衍合能产生一个更为整洁的提交历史。如果视察一个衍合过的分支的历史记录,看起来更清楚: 仿佛所有修改都是先后进行的,尽管实际上它们原来是同时发生的。

你可以经常使用衍合,确保在远程分支里的提交历史更清晰。比方说,某些项目自己不是维护者,但想帮点忙,就应该尽可能使用衍合:先在一个分支里进行开发,当准备向主项目提交补丁的时候,再把它衍合到 origin/master 里面。这样,维护者就不需要做任何整合工作,只需根据你提供的仓库地址作一次快进,或者采纳你提交的补丁。

请注意,合并结果中最后一次提交所指向的快照,无论是通过一次衍合还是一次三方合并,都是同样的快照内容,只是提交的历史不同罢了。衍合按照每行改变发生的次序重演发生的改变,而合并是把最终结果合在一起。

永远不要衍合那些已经 推送到公共仓库的更新。

 

如果你遵循这条金科玉律,就不会出差错。否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。

在衍合的时候,实际上抛弃了一些现存的 commit 而创造了一些类似但不同的新 commit。如果你把commit 推送到某处然后其他人下载并在其基础上工作,然后你用 git rebase 重写了这些commit 再推送一次,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容的时候事情就会变得一团糟。

果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些永远不会公开的 commit,那就不会有任何问题。 如果衍合那些已经公开的 commit,而与此同时其他人已经用这些 commit 进行了后续的开发工作,那你有得麻烦了。

你可能感兴趣的:(c,工作,git,command,merge)