提前感谢您的所有帮助。
这是一种情况,我试图了解git是否提供了解决此问题的方法:
两个用户(U1和U2)各自拥有一个与提示同步的本地仓库。
U1进行更改并提交此更改并将其推送到远程。 U2进行完全相同的更改和提交。但是当他试图推动时,他却做不到。 所以他做了git pull(没有rebase)。现在git已经添加了一个" merge branch master'信息。 现在如果U2现在推动,他的提交(这是由U1完成的确切更改)再次被推送到遥控器。
有没有办法避免这种情况?我在这里错过了一些关键命令吗?
答案 0 :(得分:3)
首先,解决方案(有潜在危险)。其次,关于如何使用git可能不必要的警告:
(难度:中等---危险:中等)
使用命令git rebase -i <something>
,其中<something>
表示提交,如提交SHA或HEAD~4(将4替换为交互式rebase的提交数)。该命令打开一个编辑器,其中包含几个段落,说明如何使用交互式rebase。您可以非常轻松地从那里删除重复提交,但为了安全起见,您应该将分支机构保存到另一个分支机构。 git rebase -i
是一个非常有用的命令/开关,可以学习如何使用。
(难度:低---危险:高)
git push origin <branch name> --force
推动您的更改。这很危险,因为任何从该分支拉出的人都将不同步,并且需要删除他们的分支并重新获取它。他们应该遵循步骤2a 。如果没有其他人使用除你之外的那个分支,强制推动是安全的。
(难度:中等---危险:中等)
git branch -D yourbranch # Delete your branch
git checkout origin/yourbranch # Check out the remote-tracking branch
git checkout -b yourbranch # Recreate the branch
与GitHub集成的CI工具应该不受影响。
您应该使用git-flow
或类似的过程。您的两个用户不应该推送到同一个分支,否则您将始终遇到合并冲突。此外,不要重新绑定任何已合并到主服务器或多人将从中提取的提交。如果强制推送,那么您需要将步骤2a 应用于每个已重新组合到其中的重新提交提交的计算机上的每个存储上的每个分支。如果你改变主人的提交,那就是噩梦。
答案 1 :(得分:2)
更改是否完全相同无关紧要,因为git的提交对象(及其SHA1)不仅基于实际的diff,而且还基于作者,提交者,提交消息,提交的时间戳创建等等。
由于U2执行pull
(即获取+合并)而不是pull --rebase
(即fetch + rebase),您将获得新的合并提交,这仍然是一个变化(即使它不涉及工作树本身的状态的任何变化),因此将被推到遥控器。下图应该准确显示您的案例中发生的事情。
State of remote(say origin)
U1C1 -- U2C2
State of U1 on start
U1C1 -- U2C2
State of U2 on start
U1C1 -- U2C2
U1 after creating a new commit
U1C1 -- U2C2 -- U1C3
U2 after creating a new commit
U1C1 -- U2C2 -- U2C3'
Remote after U1 pushes the change
U1C1 -- U2C2 -- U1C3
U2 after git pull (Merging origin/master into master)
U1C1 -- U2C2 -- U2C3' -- U2C3"
\ /
\ U1C3 --/
Remote after U2 does a git push
U1C1 -- U2C2 -- U2C3' -- U2C3"
\ /
\ U1C3 --/
如果U2改为git pull --rebase
,U2至少会注意到冲突,因此会放弃他/她的提交。
用户可以使用git-flow
等工具来管理git工作流程。如果你在遥控器的裸仓库上使用像gitolite这样的东西,那么可能会有一些设置可以控制或拒绝push
操作,只有少数情况。
您可以通过重写历史来一次性修复此问题,但是一旦提交公开,重写历史记录是一个坏主意,因为可能会有用户可能仍然拥有较旧的历史记录并且他们会启动看到分歧的历史。