text: 之前介绍过，整合分支最容易的方法是merge命令。它会把两个分支的最新快照（C3和C4）以及二者最近的共同祖先（C2）进行三方合并，合并的结果是生成一个新的快照（并提交）。
  在上面这个例子中，运行：
  它的原理是首先找到这两个分支（即当前分支experiment、变基操作的目标基底分支master）的最近共同祖先C2，然后对比当前分支相对于该祖先的历次提交，提取相应的修改并存为临时文件，然后将当前分支指向目标基底C3,最后以此将之前另存为临时文件的修改依序应用。（译注：写明了commitid，以便理解，下同）
  现在回到master分支，进行一次快进合并。
  此时，C4'指向的快照就和上面使用merge命令的例子中C5指向的快照一模一样了。这两种整合方法的最终结果没有任何区别，但是变基使得提交历史更加整洁。你在查看一个经过变基的分支的历史记录时会发现，尽管实际的开发工作是并行的，但它们看上去就像是串行的一样，提交历史是一条直线没有分叉。
  一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。在这种情况下，你首先在自己的分支里进行开发，当开发完成时你需要先将你的代码变基到origin/master上，然后再向主项目提交修改。这样的话，该项目的维护者就不再需要进行整合工作，只需要快进合并便可。
  请注意，无论是通过变基，还是通过三方合并，整合的最终结果所指向的快照始终是一样的，只不过提交历史不同罢了。变基是将一系列提交按照原有次序依次应用到另一分支上，而合并是把最终结果合在一起。
  在对两个分支进行变基时，所生成的“重放”并不一定要在目标分支上应用，你也可以指定另外的一个分支进行应用。就像从一个特性分支里再分出一个特性分支的提交历史中的例子那样。你创建了一个特性分支server，为服务端添加了一些功能，提交了C3和C4。然后从C3上创建了特性分支client，为客户端添加了一些功能，提交了C8和C9。最后，你回到server分支，又提交了C10。
  以上命令的意思是：“取出client分支，找出处于client分支和server分支的共同祖先之后的修改，然后把它们在master分支上重放一遍”。这理解起来有一点复杂，不过效果非常酷。
  现在可以快进合并master分支了。（如图快进合并master分支，使之包含来自client分支的修改）：
  如图将server中的修改变基到master上所示，server中的代码被“续”到了master后面。
  然后就可以快进合并主分支master了：
  呃，奇妙的变基也并非完美无缺，要用它得遵守一条准则：
  如果你遵循这条金科玉律，就不会出差错。否则，人民群众会仇恨你，你的朋友和家人也会嘲笑你，唾弃你。
  变基操作的实质是丢弃一些现有的提交，然后相应地新建一些内容一样但实际上不同的提交。如果你已经将提交推送至某个仓库，而其他人也已经从该仓库拉取提交并进行了后续工作，此时，如果你用gitrebase命令重新整理了提交并再次推送，你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合，如果接下来你还要拉取并整合他们修改过的提交，事情就会变得一团糟。
  然后，某人又向中央服务器提交了一些修改，其中还包括一次合并。你抓取了这些在远程分支上的修改，并将其合并到你本地的开发分支，然后你的提交历史就会变成这样：
  接下来，这个人又决定把合并操作回滚，改用变基；继而又用gitpush--force命令覆盖了服务器上的提交历史。之后你从服务器抓取更新，会发现多出来一些新的提交。
  结果就是你们两人的处境都十分尴尬。如果你执行gitpull命令，你将合并来自两条提交历史的内容，生成一个新的合并提交，最终仓库会如图所示：
  此时如果你执行gitlog命令，你会发现有两个提交的作者、日期、日志居然是一样的，这会令人感到混乱。此外，如果你将这一堆又推送到服务器上，你实际上是将那些已经被变基抛弃的提交又找了回来，这会令人感到更加混乱。很明显对方并不想在提交历史中看到C4和C6，因为之前就是他把这两个提交通过变基丢弃的。
  实际上，Git除了对整个提交计算SHA-1校验和以外，也对本次提交所引入的修改计算了校验和——即“patch-id”。
  如果你拉取被覆盖过的更新并将你手头的工作基于此进行变基的话，一般情况下Git都能成功分辨出哪些是你的修改，并把它们应用到新分支上。
  举个例子，如果遇到前面提到的有人推送了经过变基的提交，并丢弃了你的本地开发所基于的一些提交那种情境，如果我们不是执行合并，而是执行gitrebaseteamone/master,Git将会：
  检查哪些提交是我们的分支上独有的（C2，C3，C4，C6，C7）
  检查其中哪些提交不是合并操作的结果（C2，C3，C4）
  检查哪些提交在对方覆盖更新时并没有被纳入目标分支（只有C2和C3，因为C4其实就是C4'）
  从而我们将得到与你将相同的内容又合并了一次，生成了一个新的提交中不同的结果，如图在一个被变基然后强制推送的分支上再次执行变基所示。
  要想上述方案有效，还需要对方在变基时确保C4'和C4是几乎一样的。否则变基操作将无法识别，并新建另一个类似C4的补丁（而这个补丁很可能无法整洁的整合入历史，因为补丁中的修改已经存在于某个地方了）。
  在本例中另一种简单的方法是使用gitpull--rebase命令而不是直接gitpull。又或者你可以自己手动完成这个过程，先gitfetch，再gitrebaseteamone/master。
  只要你把变基命令当作是在推送前清理提交使之整洁的工具，并且只在从未推送至共用仓库的提交上执行变基命令，就不会有事。假如在那些已经被推送至共用仓库的提交上执行变基命令，并因此丢弃了一些别人的开发所基于的提交，那你就有大麻烦了，你的同事也会因此鄙视你。
  如果你或你的同事在某些情形下决意要这么做，请一定要通知每个人执行gitpull--rebase命令，这样尽管不能避免伤痛，但能有所缓解。
  至此，你已在实战中学习了变基和合并的用法，你一定会想问，到底哪种方式更好。在回答这个问题之前，让我们退后一步，想讨论一下提交历史到底意味着什么。
  有一种观点认为，仓库的提交历史即是记录实际发生过什么。它是针对历史的文档，本身就有价值，不能乱改。从这个角度看来，改变提交历史是一种亵渎，你使用_谎言_掩盖了实际发生过的事情。如果由合并产生的提交历史是一团糟怎么办？既然事实就是如此，那么这些痕迹就应该被保留下来，让后人能够查阅。
  另一种观点则正好相反，他们认为提交历史是项目过程中发生的事。没人会出版一本书的第一版草稿，软件维护手册也是需要反复修订才能方便使用。持这一观点的人会使用rebase及filter-branch等工具来编写故事，怎么方便后来的读者就怎么写。
  总的原则是，只对尚未推送或分享给别人的本地修改执行变基操作清理历史，从不对已推送至别处的提交执行变基操作，这样，你才能享受到两种方式带来的便利。