另一位开发人员将他的更改推送到远程存储库,当我想要推送时,我收到以下错误:
error: failed to push some refs to 'xxx@yyy'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
如何上传我的更改?
总结(假设你在
master
):如果您不介意创建合并提交,那么这就足够了:
如果您希望避免合并提交:
解释
在git中,提交是给定时间整个存储库的状态。此外,每个开发人员都有一份所有内容的副本,并且(如果他们使用github之类的东西)还有一个中央存储库。在这种情况下,所有开发人员都
git pull
进入git push
中央存储库,这是唯一的远程存储库。因此,让我们想象一下,您的远程存储库的初始状态是:而且你没有
git pull
问题。您的本地存储库与远程存储库具有完全相同的内容。你工作得很愉快,但 Martín(团队中的另一位开发人员)确实
git push
......所以远程存储库的状态变成了这样:你完成了你正在修复的 bug 的工作并做
git commit
......此时,在你的本地存储库中,你有以下内容:到目前为止,一切都很完美......但是当你这样做时
git push
,它会失败并显示问题的错误消息。发生这种情况是因为git不知道如何处理提交 4……它应该在提交 2 之后,但在远程存储库中,它是 3 在 2 之后。普通版
一种选择是:
这样做是将远程存储库中的更改带到您的计算机并尝试进行合并。如果没有冲突,您团队的最终状态如下:
下一步是通过执行以下操作将您的更改上传到遥控器:
如果烦人的 Martin 没有上传另一个更改,那么它会正常工作。如果由于同样的原因失败,只需重复该过程。
反合并小队版本
我们中有几个人不喜欢有很多合并提交。为什么?因为他们不添加信息。幸运的是,对于像我这样的疯子,有一种方法可以做几乎相同的事情,但更整洁。
首先我们运行:
git fetch
从远程获取更改但不触及分支......一旦你这样做git fetch
了,这就是你的存储库中剩下的内容:这意味着:
master
(您通常工作的分支)仍然指向您的提交origin/master
) 指向提交 3所以......神奇的一步是:
当您编写该代码时,git在(提交 3)处停止
origin/master
并重复在提交 4 中所做的更改。如果没有冲突,则输出如下:重要的是要注意不再有提交 4……我们有一个提交 5,它“几乎”像 4,但不同(因为它指向提交 3,它有另一个父级……这就足够了让它成为另一个)。
如果存在冲突,您将不得不纠正它们(控制台告诉您哪些文件是要修复的文件),添加它们(使用
git add
),最后继续使用变基(使用git rebase --continue
)。最后,有必要将更改上传到遥控器(这是您从一开始就想做的,对吧?)。为了那个原因:
准备好了!
冲突存在并且将永远存在(无论您是否进行合并提交)。就个人而言,我更愿意不惜一切代价避免合并提交。
我会给你留下最后一张图片,这样你就可以明白为什么避免合并提交可能会很好......没有合并提交,分支结构会变得更加清晰:
这些图形是用draw.io制作的,可以在这里找到