【转】git rebase 用法
来源:互联网 发布:绘制论文世界地图软件 编辑:程序博客网 时间:2024/05/16 11:56
3.6 Git Branching - Rebasing
Rebasing
把一个分支整合到另一个分支的办法有两种:merge(合并)
rebase(衍合)
。在本章我们会学习什么是衍合,如何使用衍合,为什么衍合操作如此富有魅力,以及我们应该在什么情况下使用衍合。
Rebase基础
请回顾之前有关合并的一节(见图3-27),你会看到开发进程分叉到两个不同分支,又各自提交了更新。
之前介绍过,最容易的整合分支的方法是 merge
其实,还有另外一个选择:你可以把在 C3 里产生的变化补丁重新在 C4 的基础上打一遍。在 Git里,这种操作叫做衍合(rebase)。有了 rebase
在这个例子里,可以运行下面的命令:
$ git checkout experiment$ git rebase masterFirst, rewinding head to replay your work on top of it...Applying: added staged command
它的原理是回到两个分支(你所在的分支和你想要衍合进去的分支)的共同祖先,提取你所在分支每次提交时产生的差异(diff),把这些差异分别保存到临时文件里,然后从当前分支转换到你需要衍合入的分支,依序施用每一个差异补丁文件。图3-29 演示了这一过程:
现在,你可以回到 master 分支然后进行一次快进合并(见图3-30):
现在,合并后的 C3(即现在的 C3')所指的快照,同三方合并例子中的C5所指的快照内容一模一样了。最后整合得到的结果没有任何区别,但衍合能产生一个更为整洁的提交历史。如果视察一个衍合过的分支的历史记录,看起来更清楚:仿佛所有修改都是先后进行的,尽管实际上它们原来是同时发生的。
你可以经常使用衍合,确保在远程分支里的提交历史更清晰。比方说,某些项目自己不是维护者,但想帮点忙,就应该尽可能使用衍合:先在一个分支里进行开发,当准备向主项目提交补丁的时候,再把它衍合到origin/master
请注意,合并结果中最后一次提交所指向的快照,无论是通过一次衍合还是一次三方合并,都是同样的快照内容,只是提交的历史不同罢了。衍合按照每行改变发生的次序重演发生的改变,而合并是把最终结果合在一起。
更多有趣的衍合
你还可以在衍合分支以外的地方衍合。以图 3-31的历史为例。你创建了一个特性分支 server
client
server
假设在接下来的一次软件发布中,你决定把客户端的修改先合并到主线中,而暂缓并入服务端软件的修改(因为还需要进一步测试)。你可以仅提取对客户端的改变(C8和 C9),然后通过使用 gitrebase
--onto
$ git rebase --onto master server client
这基本上等于在说“检出 client分支,找出 client
server
master
现在可以快进 master 分支了(见图 3-33):
$ git checkout master$ git merge client
现在你决定把 server
server
master
server
分支再衍合。gitrebase [主分支][特性分支]
server
,然后在主分支 master
$ git rebase master server
于是 server
master
然后快进主分支 master
:
$ git checkout master$ git merge server
现在 client
server
$ git branch -d client$ git branch -d server
衍合的风险
呃,奇妙的衍合也不是完美无缺的,一句话可以总结这点:
永远不要衍合那些已经推送到公共仓库的更新。
如果你遵循这条金科玉律,就不会出差错。否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。
在衍合的时候,实际上抛弃了一些现存的 commit而创造了一些类似但不同的新 commit。如果你把commit推送到某处然后其他人下载并在其基础上工作,然后你用 gitrebase
下面我们用一个实际例子来说明为什么公开的衍合会带来问题。假设你从一个中央服务器克隆然后在它的基础上搞了一些开发,提交历史类似图3-36:
现在,其他人进行了一些包含一次合并的工作(得到结果C6),然后把它推送到了中央服务器。你获取了这些数据并把它们合并到你本地的开发进程里,让你的历史变成类似图 3-37 这样:
接下来,那个推送 C6上来的人决定用衍合取代那次合并;他们用 git push--force
这时候,你需要再次合并这些内容,尽管之前已经做过一次了。衍合会改变这些commit 的 SHA-1 校验值,这样 Git 会把它们当作新的 commit,然而这时候在你的提交历史早就有了 C4的内容(见图 3-39):
你迟早都是要并入其他协作者提交的内容的,这样才能保持同步。当你做完这些,你的提交历史里会同时包含 C4 和 C4',两者有着不同的 SHA-1校验值,但却拥有一样的作者日期与提交说明,令人费解!更糟糕的是,当你把这样的历史推送到服务器,会再次把这些衍合的提交引入到中央服务器,进一步迷惑其他人。
如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些永远不会公开的commit,那就不会有任何问题。如果衍合那些已经公开的 commit,而与此同时其他人已经用这些 commit进行了后续的开发工作,那你有得麻烦了。
转自:http://blog.csdn.net/trochiluses/article/details/14451777
- 【转】git rebase 用法
- git rmote 用法
- Git Stash用法
- git-rebase用法总结
- Git rebase 简明用法
- git rebase用法解析
- git rebase 用法记录
- git rebase 用法简介
- 转: IOS ----UIButton用法详解
- TouchJSON 用法
- (转)ORACLE WITH AS 用法
- 用法
- git diff wifi p2p
- git diff wifi p2p
- git 命令之git rebase 用法&git rebase介绍
- try catch finally 用法
- 转:assert() 函数用法
- 转:assert() 函数用法
- ubuntu下的libre office使用
- Android高手进阶教程(一)——-Android开发常用命令集合
- 查询BINLOG日志
- 【转】git am使用详解
- 【转】git-rebase(认真看,分析很…
- 【转】git rebase 用法
- 【转】git reset各个选项的区别
- 用git rebase压缩多个commit
- 【转】Linux内核中的内存屏障&nbsp…
- 步骤:用git提交patch,并发送邮件…
- 【转】Linux Kernel Device Tree
- PullToRefresh使用详解(一)--构建下拉刷新的listView
- vim删除行尾空格。和转换dos2unix
- arm v8汇编指令