git rebase,提交重复
我正在处理回购协议的另一个分支,需要从主分支引入变更。我有做git rebase master的习惯,一切都很好。然而,在最近的几个项目中,我看到在日志中重复提交,重定基址往往会抱怨(大声): (为了简单起见,我更改了提交消息。尽管有四条“管道”,但这里实际上只显示了一个分支。)我在这个项目上做了一些重定,我认为可以非常简单地根据(比如)更改措辞1的重复次数来跟踪它们 我以为我是在用项目工作流做“最佳实践”的事情,通过重定基来合并。我认为之前的一次调整中至少有一次是用git rebase,提交重复,git,rebase,Git,Rebase,我正在处理回购协议的另一个分支,需要从主分支引入变更。我有做git rebase master的习惯,一切都很好。然而,在最近的几个项目中,我看到在日志中重复提交,重定基址往往会抱怨(大声): (为了简单起见,我更改了提交消息。尽管有四条“管道”,但这里实际上只显示了一个分支。)我在这个项目上做了一些重定,我认为可以非常简单地根据(比如)更改措辞1的重复次数来跟踪它们 我以为我是在用项目工作流做“最佳实践”的事情,通过重定基来合并。我认为之前的一次调整中至少有一次是用-no ff完成的,但我看不
-no ff
完成的,但我看不出行为上有什么不同
当重放提交时,它们会发生冲突(显然,将一个提交放在其上是有问题的),因此我被迫执行交互式重新基址,删除所有重复的提交
无法访问回购协议本身,这是我的工作流程中的问题吗?这是否表明分支机构存在其他问题?为什么?
看起来您用另一个分支已经指向的重基修改了旧的提交。所以发生的事情是:
你有一个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
操作,但您意识到仍有一些Peter的垃圾代码遗留下来,希望将其删除。作为一名优秀的程序员,您希望这些更改与其他更改一起提交到commit348cc87
。因此,您需要重新设置基础以回到这一点,并修改中的更改
这看起来不错吧?问题是,你已经改变了348cc87,所以它不再是348cc87了。现在它的111222
,因为记住提交散列是从项目的树中计算出来的。其中一个是父提交散列(000a0a
)。因此,由于348cc87
现在是111222
,“192837”重新计算为999999
,f00ba12
更改为ba12f00
。现在你头上的日志看起来像
* 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
经常这样做,你就会陷入目前的处境
但是凯尔,我该怎么解决这个问题??慢点,埃文斯,我马上就到
如何修复
有几种方法可以解决这个问题,我所知道的所有方法在特定情况下都稍微复杂一些
- 你可以把很多东西挤在一起,这样就可以减少提交,但是你会失去一些你的历史,我不喜欢
- 您可以执行更多的重定基法来更改“abc123”提交,以使较新的
commit作为其父级。您可以使用--on参数来实现这一点。根据这种情况下的提交数量,这可能是一个挑战999999
- 你可以保持原样。只要大师的提示处于正确的状态,这并不可怕,但会让回顾你的历史变得相当困难
master
跟踪什么是公共的。这是我自己和我的队友所依据的代码。我从不修改master中的提交。首先是因为我们的内部git回购协议不允许我推动这样的更改(即使使用--force),其次是因为这样会弄乱我的队友的代码(并将他们放到你的位置)
我为特定功能创建了
master
的功能分支,因此我将有foo
、bar
、fizz
和buzz
这些分支作为master的独立分支,而不是彼此分离。这使我能够独立地处理每一个问题。我通常不会从功能分支分支出来,但当我分支时,我通常不会对提交历史进行任何编辑。这是因为我通常会在合并之前清理分支,所以我不需要这样做。非常好的回答,谢谢Kyle。另一个问题(我忘了提到)是我在repo服务器上有分支,因此git push origin
几乎总是需要强制提交才能推送。也许我提出的dag最大的“问题”是,当只有一个分支时,它显示了四个分支;我希望保持一个“干净”的dag,而不明显重复提交消息。知道这是“正常的行为”会有所帮助。如果整个历史已经为世人所知,而人们正在消费它,那就别管它了。这不是什么好事情,但你不应该干扰公共回购协议,因为这会伤害其他开发者。所以,一旦您推到源代码,您应该进行新的提交,而不是重新基址到旧的提交。
* 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