2016-03-04 1212 views
3

我正在处理我的回购的另一个分支,并需要从主分支中引入更改。我习惯做git rebase master,并且一切正常。然而,在最近的几个项目中,我看到提交在日志中重复,和垫底倾向于(大声地)抱怨:git rebase,提交重复

$ git log --graph --abbrev-commit --decorate ... 
* 4988d49 - (2 hours ago) Merge branch 'branchname' of ... 3 
|\ 
| * e979be1 - (2 days ago) change verbiage 10 
| * 93a1c80 - (2 days ago) Merge branch 'branchname' of ... 2 
| |\ 
| | * 4e4e790 - (2 weeks ago) Merge branch 'branchname' of ... 1 
| | |\ 
| | | * 87cc232 - (8 weeks ago) change verbiage 3 
| | | * 3d5cf09 - (8 weeks ago) change verbiage 2 
| | | * aea4cbd - (9 weeks ago) change verbiage 1 
| | * | a7043ef - (2 weeks ago) change verbiage 6 
| | * | fa3413b - (2 weeks ago) change verbiage 5 
| | * | be038a7 - (2 weeks ago) change verbiage 4 
| | * | 37cb1e6 - (8 weeks ago) change verbiage 3 
| | * | 1ab71c6 - (8 weeks ago) change verbiage 2 
| | * | c4560f4 - (9 weeks ago) change verbiage 1 
| * | | d3211fd - (2 weeks ago) change verbiage 6 
| * | | 72a2a4a - (2 weeks ago) change verbiage 5 
| * | | ae1c123 - (2 weeks ago) change verbiage 4 
| * | | 8328c08 - (8 weeks ago) change verbiage 3 
| * | | e52588f - (8 weeks ago) change verbiage 2 
| * | | 114cbec - (9 weeks ago) change verbiage 1 
* | | | 38bd6ce - (2 hours ago) change verbiage 9 
* | | | 5aaf360 - (2 hours ago) change verbiage 8 
* | | | 2745790 - (2 days ago) change verbiage 7 
* | | | 7bb613f - (2 weeks ago) change verbiage 6 
* | | | 726a312 - (2 weeks ago) change verbiage 5 
* | | | 771dd7f - (2 weeks ago) change verbiage 4 
* | | | b451926 - (8 weeks ago) change verbiage 3 
* | | | 484d5dc - (8 weeks ago) change verbiage 2 
* | | | 630df34 - (9 weeks ago) change verbiage 1 

(我已经改变了提交信息为简单起见,这里真的是只尽管有四条“管线”,但我在这里展示了一个分支)。我已经在这个项目上做了一些改版,我认为它们可以根据重复(比如说)改变措词1的次数来描述。

我以为我正在通过重新合并来完成项目工作流程中的“最佳实践”。我以为至少有一个以前的rebase是用-no-ff完成的,但是我看不到行为上的差异。

当提交重播时,它们发生冲突(显然,将一个提交置于其本身之上是有问题的),所以我不得不做一个交互式重定位,删除所有重复的提交。

缺乏对回购本身的访问,这是我的工作流程的问题吗?这是否表明分支机构存在其他问题?

回答

6

为什么?

它看起来像你修改了旧的提交与其他分支已经指出了。那么,什么情况是:

你有一个DAG,看起来像这样:

* abc123 (master) Most recent commit 
| 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
|/ 
* 192837 Fix the things 
| 
* 348cc87 Remove Peter's garbage code 
| 
* 000a0a WOOOORRRDDDDDSSSS 

所以您目前所foo做一些事情,但你知道你仍然有一些彼得的垃圾代码遗留下来的希望将其删除。作为一名优秀的程序员,您希望将这些更改与其他更改一起提交到348cc87。所以你要做一个基准重新回到这一点,并修改其中的变化。

这看起来不错吧?事情是,你已经改变了348cc87,所以它不再是348cc87了。现在它的111222,因为记住提交散列是从项目的树中计算出来的,除此之外。其他事情之一是父母提交散列(000a0a)。因此,由于348cc87现在为111222,'192837'重新计算为999999f00ba12更改为ba12f00。所以,现在你的日志,从头部看起来像

* ba12f00 (foo, HEAD) Some feature you're working on 
| 
| 
* 999999 Fix the things 
| 
* 111222 Remove Peter's garbage code 
| 
* 000a0a WOOOORRRDDDDDSSSS 

这将成为因为abc123仍然在192837指向一个问题,它的工作原理是因为commit对象192837在Git中仍然存在。这是因为从git的角度来看,192837abc123是明显不同的提交,它们恰好具有相同的日志消息。

所以,现在你的混帐DAG的样子:

* abc123 (master) Most recent commit 
| 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
| * 999999 Fix the things 
* | 192837 Fix the things 
| | 
| * 111222 Remove Peter's garbage code 
* | 348cc87 Remove Peter's garbage code 
|/ 
* 000a0a WOOOORRRDDDDDSSSS 

现在,当你完成的工作在你的foo分支,并准备合并你

* 5f93da (master) Merge 'foo' into 'master' 
|\ 
* | abc123 Most recent commit 
| | 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
| * 999999 Fix the things 
* | 192837 Fix the things 
| | 
| * 111222 Remove Peter's garbage code 
* | 348cc87 Remove Peter's garbage code 
|/ 
* 000a0a WOOOORRRDDDDDSSSS 

这样做了很多,你最终会在目前的情况下。

但凯尔,我该如何解决这个问题?抓住你的马r2evans,我到了那里。

如何解决

有几个方法,你可以解决这个问题,所有我知道的是温和的纷繁复杂给予一定的情况下,那些的。

  • 你可以把很多东西压在一起,这样提交的次数就会减少,但是你失去了一些我不喜欢的历史。

  • 你可以做一些更多的重新镶嵌魔术来改变你的'abc123'提交,让新的999999作为它的父项提交。你可以使用--onto参数。取决于这种情况下的提交次数,这可能是具有挑战性的。

  • 您可以保持原样。只要主人的提示处于正确的状态,这不是可怕的,但让您回顾历史相当困难。

这是一个问题?

是的。这看起来像是您的工作流程的问题。出于这个原因,编辑历史往往不是一个好主意,你通常应该避免它。

对我而言,master追踪什么是公开的。这是我自己和我的队友都将我们的变更建立在基础之上的代码。我从不修改master中的提交。首先是因为我们的内部git repo不会允许我推动这样的变化(即使使用--force),其次是因为这会混淆我的队友的代码(并将它们放到您的位置)。

我创造过的master特定功能特性分支,所以我将有分支机构foobarfizz和关老爷的buzz都作为单独的分支,不交相辉映。这使我可以独立工作。我通常不会从功能分支中分支出来,但是当我这样做时,我通常不会对提交历史进行任何编辑。这是因为我通常会在合并之前清理分支,所以我不需要。

+0

非常好的答案,谢谢凯尔。另一个问题(我忘了提及)是我在repo服务器上有分支,所以'git push origin'几乎总是需要强制性提交才能推送。也许我提出的Dag最大的“问题”是它只有一个时显示四个分支;我宁愿保持一个“干净”的DAG,而不显着重复提交消息。知道这是“正常行为”有帮助。 – r2evans

+1

如果整个历史已经出现在世人眼前,而人们正在消费它,那就留下吧。这不是很好或者什么,但是你不应该因为伤害其他开发者而混淆公共回购。所以一旦你推动起源,你应该做出新的提交,而不是变成旧的提交。 –