我正在处理我的仓库的另一个分支,需要从主分支引入更改。我习惯做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本身的访问权限,这是我工作流程的问题吗?是否表明分支机构存在其他问题?
答案 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”会重新计算为999999
,f00ba12
会更改为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的角度来看192837
和abc123
是截然不同的提交,恰好具有相同的日志消息。
所以现在你的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
创建了特定功能的功能分支,因此我将分支foo
,bar
,fizz
和buzz
作为单独的分支离开主人,而不是彼此关闭。这允许我独立工作。我通常不会分支功能分支,但是当我这样做时,我通常不会对提交历史进行任何编辑。那是因为我通常会在合并之前清理分支,所以我不需要。