git 代码合并

cysin2012 8年前
   <p>在Git中, git merge 和 git rebase 都是用来将一个分支的修改并入另一个分支,只不过方式不同。</p>    <p>在日常工作中基本都会有一个工作主分支,一般我们会新建一个新的分支开始我们的工作,以免影响主分支。我们假设以下的情景来说明代码合并。</p>    <p>小李需要开发FeatureA,因此他在项目主分支的基础上新建了一个FeatureA的分支开始了他的工作,在他工作的同时,同事修复了两个bug,并且都合入了主分支,于是代码分支变成 了下面这种情况:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/bd56882e69518014ba6d4aff89f7e53b.png"></p>    <p>分支状况</p>    <p>这时候小李想基于修复好bug的版本继续之前的开发,那么就需要将自己的代码和已经分叉的主分支进行合并,采取的方法可以是 git merge ,也可以是 git rebase .</p>    <p>git merge</p>    <p>一般来说,最简单的操作就是执行下面的步骤:</p>    <pre>  git checkout featureA  git merge master</pre>    <p>或者直接:</p>    <pre>  git merge master featureA</pre>    <p>这样就会产生一个三路合并:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/8329bdbf3f942a103147452463022f3f.png"></p>    <p>git merge</p>    <p>git merge 的优点就是简单,并且产生一个合并的历史,但是如果master分支的历史很活跃,你又想始终保持与master一致,那么多多少少那么多的合并历史会影响到你分支历史的整洁性。这时候 git rebase 就可以登场了。</p>    <p>关于更多 git merge 的详细述说可以看我上一篇文章:git 分支管理</p>    <p>git rebase</p>    <p>作为 merge 的替代,我们可以这样执行 rebase :</p>    <pre>  git checkout featureA  git rebase master</pre>    <p>它会把整个featureA的分支直接移到现在master分支的后面:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/55ba5d5973bd55db411aa3520c36ec2a.png"></p>    <p>git rebase</p>    <p>git rebase 最大的特点就是会使你的项目历史非常干净,呈现出一条线性提交,因为它不会引入合并提交,这让你更容易使用 git log 、 git bisect 和 gitk 来查看项目历史。</p>    <p>不过说 git rebase 也是 git 中的黑魔法,如果不遵守使用 git rebase 的黄金法则,也会给你的项目历史带来灾难性的影响, rebase 使你的 feature 分支没有合并提交历史,所以你也看不出 feature 合并进了上游的哪些修改。</p>    <p>交互式的rebase</p>    <p>这里假设小A在他的 featureA 分支已经有三个提交了,这时候如果直接 rebase 就会把 这三个提交历史都接到 master 分支后面。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/18cbb88c5ce94aa773815d1b9047c56c.png"></p>    <p>带有三次提交历史的feature分支</p>    <p>而交互式的 rebase 则可以对 featureA 的分支历史进行清理。</p>    <p>加上 -i ,我们执行交互式的 rebase :</p>    <pre>  git checkout featureA  git rebase -i master</pre>    <p>它会打开你 git 的文本编辑器:</p>    <pre>  pick 33d5b7a Message for commit #1  pick 9480b3d Message for commit #2  pick 5c67e61 Message for commit #3</pre>    <p>这个列表显示了你fetureA的历史,你可以通过更改顺序,更改pick或者使用fixup来合并你的历史。比如如果 #2 和 #3 包含了修复性的更改,你想合并他们,那么你可以加上一个fixup:</p>    <pre>  pick 33d5b7a Message for commit #1  pick 9480b3d Message for commit #2  fixup 5c67e61 Message for commit #3</pre>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/5652c3fef0f7f3f25bc3b2ca745f7e2c.png"></p>    <p>fixup</p>    <p>如图所示, #2 和 #3 被合并为一次提交,这样在合并的过程中还能简化项目历史,这是 git merge 办不到的。</p>    <p>Rebase黄金法则</p>    <p>当你使用 Rebase 更加方便地处理你的分支时,你也必须懂得有哪些潜在的风险。使用 rebase 的一条黄金法则就是,绝对不要在公共分支上使用它。假设你使用了,那么便会发生下面的情况:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/a79782634d08b97a5d00f107979119bc.png"></p>    <p>在主分支上rebase</p>    <p>如上图,你在主分支上的 git rebase 将 master 分支移到了 featureA 分支的后面,而其他开发者还是基于原有的 master 分支进行开发,这时候你的 master 分支就和别人的分叉了,如果需要同步,则需要额外的一次 git merge ,以让你目前的 master 和别人的 master 合并,你的项目历史更加令人迷惑。</p>    <p>所以,在进行 git rebase 时,务必确认有没有别人在此分支上工作,如果有的话,那么你就得考虑一种无害的方式来进行你的提交,比如 git revert 这样的操作。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/b15574f50939</p>    <p> </p>