git rebase,承诺重复

时间:2016-03-04 07:03:57

标签: git rebase

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

$ 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

(为了简单起见,我已经更改了提交消息。尽管有四条“管道线”,但这里确实只显示了一个分支。)我在这个项目上做了几个rebase,我认为它们可以被跟踪而是简单地根据(比如)改变措辞1的重复次数。

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

当提交被重放时,它们会发生冲突(显然,将一个提交置于其自身之上是有问题的),因此我不得不进行交互式rebase,删除所有重复的提交。

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

1 个答案:

答案 0 :(得分:6)

为什么?

看起来您修改了旧的提交,其中另一个分支已经指向了rebase。所以发生了什么:

你有一个看起来像这样的匕首:

* 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做一些事情,但是你意识到你仍然遗留了一些Peter的垃圾代码,并想要删除它。作为优秀的程序员,您希望这些更改与其他更改一起处于提交348cc87。所以你做了一个rebase来回到那一点并修改了变化。

这看起来不错吧?事情是,你已经改变348cc87所以它不再是348cc87了。现在是111222,因为记住提交哈希值是从项目的树中计算出来的。其中一个是父提交哈希(000a0a)。因此,348cc87现在是111222,“192837”会重新计算为999999f00ba12会更改为ba12f00。所以现在你的HEAD日志看起来像是

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

这成为一个问题,因为abc123 仍然指向192837 ,这是有效的,因为提交对象192837仍然存在于git中。这是因为从git的角度来看192837abc123是截然不同的提交,恰好具有相同的日志消息。

所以现在你的git 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创建了特定功能的功能分支,因此我将分支foobarfizzbuzz作为单独的分支离开主人,而不是彼此关闭。这允许我独立工作。我通常不会分支功能分支,但是当我这样做时,我通常不会对提交历史进行任何编辑。那是因为我通常会在合并之前清理分支,所以我不需要。