Git rebase失去了历史,那么为什么rebase?
过去几天我一直在寻找Git的重装。 大多数重新认定的论据说,它清理历史,使其更线性。 如果你做了简单的合并(例如),你会得到一个历史logging,显示历史发生什么时候,什么时候它们被合并在一起。 据我所知,重新设定可以消除所有的历史。 问题是:为什么你不希望回购历史反映代码开发的所有方式,包括它在何处以及如何分歧?
据我所知,重新设定可以消除所有的历史。
这是不正确的。 正如其名称所暗示的,重新设置会改变提交的基础 。 通常在这个过程中没有任何提交(除了你没有得到一个合并提交)。 虽然关于如何保持历史上所有发展过程的观点是正确的,但这往往会导致历史混淆。
特别是在与其他人一起工作时,他们各自在自己的分支上工作,同时要求其他人做出某些改变(例如,A要求B执行某些事情,以便A可以在自己的开发中使用该function),这导致了很多合并。 比如像这样:
#--#--#--#--*-----*-----------------*---#---\ Branch B / / / / \ ---#-----#-----#-----#-----#-----#-----#-----#-----* Branch A
在这个例子中,我们有一个分支单独工作的时间,但不断从原来的分支(#是原始提交,*是合并)拉动变化。
现在,如果我们在合并之前在分支B上进行重新分配,则可以得到以下结果:
#--#--#--#--#---\ Branch B / \ ---#---#---#---#---#---#---#---#---------------* Branch A
这代表了相同的实际更改,但是B被重新初始化为A上的一些较旧的提交,因此不再需要在之前完成的B上的所有合并(因为这些更改已经在那个较旧的提交中存在)。 所有现在缺less的提交都是合并,通常不包含关于开发过程的任何信息。 (请注意,在这个例子中,你也可以稍后重新绑定A的最后一个提交,得到一条直线,有效地去除第二个分支的提示)
想象一下,你正在做一个世界统治的秘密计划。 这个阴谋有三个主谋:
- 天才
- 一般
- 电脑黑客
他们都同意在1周内到达他们的秘密基地,每个人都有一个详细的计划。
电脑黑客作为一个实用的程序员,build议他们使用Git来存储计划的所有文件。 每一个将分叉最初的项目回购,他们将在一周内合并。
他们都同意,在接下来的日子里,这个故事是这样的:
天才
他总共提交了70次提交,每天10次。
一般
他窥探同志的回购,并制定战略打败他们。 他最后一天做了3次提交。
电脑黑客
这个务实的程序员使用分支。 他做了4个不同的计划,每个计划都在一个分支上。 每个分支被重新devise只是一个提交。
七天过去了,小组再次会面,把所有的计划合并成一块。 他们都急于开始,所以他们都试图自己合并所有的东西。
这里是故事:
天才
他合并了General的repo和Computer Hacker的所有变更。 然后,作为一个逻辑爱好者,他看了一下日志。 他期望看到一个想法的逻辑演变,在这个过程中,事物是build立在以前的想法上的。
但是日志所显示的是在时间线上混杂着各种各样的想法。 有一位读者通过阅读提交时间线,不能真正理解提交的进化和推理。
于是他以一塌糊涂结束了,即使是一个天才也无法理解。
一般
将军思想:分而治之!
所以他把天才的回购合并在他的回购上。 他看了一眼日志,看到一连串天才想法的提交,直到最后一天。 将军和天才的想法最后一天是混合的。
他在暗中监视电脑黑客并了解Rebase解决scheme。 于是他对自己的想法进行了重新设定,再次尝试合并。
现在,日志每天都显示出合乎逻辑的进展。
电脑黑客
这个实用的程序员为Genius的想法创build了一个整合分支,另一个为总体思路创build了另一个分支,为他自己的想法创build了另一个分支。 他为每个分公司做了一次重组。 然后他把所有的东西都合并了。
所有队友都看到他的日志很棒。 这很简单。 这是一见钟情。
如果一个想法引入了一个问题,那么引入哪个提交就很清楚了,因为只有一个。
他们结束征服全世界,并且消灭了Subversion的使用。
而且都很开心。
你做一个rebase主要是为了在本地解决任何冲突(也就是在你把它推回到上游repo之前)在远程分支之上重做本地提交(你还没有推送的提交) )。
请参阅“ git工作stream和rebase vs合并问题 ”,并且相当详细:“ git rebase vs git merge ”。
但是rebase并不局限于这种情况,并且与“-interactive”相结合,它允许一些本地的重新sorting和清理你的历史。 另见“ 修剪GIT Checkins /压缩GIT历史 ”。
为什么你不希望回购历史反映代码开发的所有方式,包括在何处以及如何分歧
- 在一个集中的VCS中,永不丢失历史是非常重要的,它确实应该反映“代码开发的一切方式”。
- 在分布式VCS中,在将一些分支发布到上游之前,您可以进行所有types的本地实验,将所有内容都保存在历史logging中是没有意义的:不是每个人都需要克隆和查看所有分支,testing,备选scheme,等等。
如果您在公共存储库中犯了一个错误,而且还没有人将其分叉/合并/拉出,那么您可以保存面子和混乱:
git reset --hard [SHAnumber] git rebase -f master git push -f origin HEAD:master
清空垃圾箱:
git gc