Git rebase 显示非快进。

3

我是一个深藏在git中的文件。

如何进入其中:

我不是一个git专家,请在我缺少任何细节时向我询问澄清。几天前,我运行了以下命令将我的更改推送到远程分支。

% git checkout master
% git pull
% git checkout redactor_changes <-- this is the branch that I made my changes 
% git commit -m "changes" # I added my changes previously
% git rebase master
% git push origin redactor_changes # pushed changes to remote branch

并不是每个人都有向主分支合并更改的写入权限。在远程仓库拥有写入权限的人告诉我存在冲突,要进行一次变基并重新提交。所以今天我按照以下确切顺序运行了这些命令。

vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git add oblog/static/css/styles-custom.css
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git add oblog/static/js/redactor.upload_image.js
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git add oblog/static/images/loading.gif
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git commit -m "Throw a toast when user upload an non-image file with image extension"
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git branch
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git checkout master
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git pull
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git checkout redactor_changes
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git rebase master
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git merge master
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git branch
vagrant@vagrant-ubuntu-trusty-64:~/oblog$ git push origin redactor_changes

看起来这组命令把我卷入了一个无法逃脱的漩涡。

症状:

上述代码的最后一行会抛出以下错误。

! [rejected]        redactor_changes -> redactor_changes (non-fast-forward)
error: failed to push some refs to 'https://git.<domain>.com/web/oblog.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

所以我遵循了来自 SO 社区的建议:

  1. https://dev59.com/i2Ij5IYBdhLWcg3wPy_H#20467414
  2. https://dev59.com/k2w05IYBdhLWcg3w_W1O#6897674

但问题仍然存在。

LABLE:

当我将我的分支本地与主分支进行 rebase 时,会出现一些冲突,然后我手动解决并继续执行 rebase --continue。Rebase 成功后,我再次将我的分支推送到 origin,但它显示相同的错误,! [rejected]。

像 git 和 SO 建议的那样,我拉取远程分支上的更改到我的本地分支(redactor_changes),然后执行:

git rebase master

这让我回到了标签上。这个问题一直存在。

请注意,如果我不将它与主分支进行rebase,我的push命令可以正常工作,但是当远程git的所有者尝试将我的分支(redactor_changes)合并到主分支时,仍然会看到冲突。


我发现的一个问题是,你在执行了 git rebase master 之后立即执行了 git merge master。你为什么这样做? - Tim Biegeleisen
我的意图是将更改与主分支合并,使我的分支保持最新状态,然后运行rebase将分支定位到主分支上。你认为这可能导致了所有这些问题? - printfmyname
1个回答

6
每次在master分支上重置您的redactor_changes分支时,您都会将后者分支的最新更改合并到前者分支中。通过以下方式来解释:

master:           A -- B -- D
redactor_changes: A -- B -- C

这个简单的图示假设你在 B 提交时从 master 分支分离出来。从那以后,你已经向 redactor_changes 分支提交了一个提交 (C),而其他人已经向 master 分支提交了一个提交 (D)。现在,如果你运行以下命令:
git checkout redactor_changes
git rebase master

您将得到以下图表。
master:           A -- B -- D
redactor_changes: A -- B -- D -- C'

重新基于主分支的提交成功地将新的提交合并到了master分支,但是这样做重写了你的redactor_changes分支的历史记录。这是一件好事(潜在地),因为这意味着审核人员可以只使用你的更改来快进master分支(没有合并提交)。但它确实有一个副作用,你无法再将redactor_changes推送到远程仓库。尝试以下命令:
git push origin redactor_changes

这将会给你看到的错误提示信息:

! [rejected] redactor_changes -> redactor_changes (non-fast-forward) error: failed to push some refs to 'https://git..com/web/oblog.git'
hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart...

因为你重写了 redactor_changes 分支的历史,Git 不再知道如何在远程分支上应用提交记录。

解决方案:

你可能想要的解决方案是:强制覆盖 远程仓库中的 redactor_changes 分支:

git checkout redactor_changes
git rebase master
git push --force redactor_changes

做这个操作后,错误信息应该会消失。这里假设redactor_changes是你个人的分支,并且你没有与任何人共享它。

我还注意到你的工作流程存在其他问题,例如在已经变基后将master合并到redactor_changes中。但进行强制推送至少可以改善你的情况。


我提交的更改旨在与主分支合并,因为它们应该进入生产环境。如果运行上述命令,让git将我的分支视为个人分支,那么当远程git的所有者尝试将其与主分支合并时,是否仍会出现错误?或者,现在删除我分支上的所有内容是否可能(或太晚了),即还原所有更改,以使我的分支与远程存储库完全匹配?我可以手动保存所有文件并稍后传输更改,因为更改集不是很大。 - printfmyname
我认为你没有理解Git的工作流程,因为你的评论对我来说毫无意义。 - Tim Biegeleisen
如果你没有权限进行强制推送,那么你可能不应该使用rebase工作流程。 - Tim Biegeleisen
1
@printfmyname,对于你的两个后续问题都是否定的回答。首先,合作者尝试合并你的更改时会获得简单快速的向前合并。其次,现在删除一切并重新开始还不算太晚,但那也可能是一个你无法逃脱的旋涡。 - Jeff Puckett
1
@Jaff 我刚刚做了那个。一切似乎都正常工作。对于有相同问题的人,我删除了远程分支并进行了git pull操作。然后,当我将redactor_changes上的变更合并到主分支上时(我也必须解决冲突),我执行了git push origin redactor_changes。感谢Tim提供的解决方案和可视化。即使可以将我带到更安全的地方,但使用--force标记执行命令仍让我有点担心。 - printfmyname
@printfmyname 你明智地谨慎使用 git push --force,不要过度使用。尽管在变基后更新远程分支是强制推送的合法用途之一。 - Tim Biegeleisen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接