Git rebase后修复冲突,再推送会被拒绝。

15

当我进行变基并且出现冲突需要解决时,我会收到以下消息:

提示:更新被拒绝,因为当前分支的尖端落后于


我们有2个分支:

  • master是我们的基础
  • feature/fix-input-height (要合并到主分支中的新功能)

我正在准备通过对主分支进行变基来解决冲突,以使 feature/fix-input-height 分支准备就绪。

git checkout master
git pull origin master

git checkout feature/fix-input-height
git pull origin feature/fix-input-height

git rebase master

  • 冲突产生
  • 我解决了它们
  • 然后尝试推送新的功能分支

git push origin feature/fix-input-height

最后却收到了拒绝的错误消息

提示:更新被拒绝,因为您当前分支的顶端落后于...


在stackoverflow上每个人都建议:

git push origin -f feature/fix-input-height

但强行推动只会感觉不对劲


2
只有强制才能帮助你。 - Alexan
1
如果你的分支落后了,就必须使用强制操作。仅仅创建一个新的分支并忘记旧的是无法使用强制操作的。 - antonio yaphiar
4个回答

20

变基通过 复制 提交来工作。 例如,您可以从以下内容开始:

...--o--o--o   <-- master
      \
       A--B--C   <-- feature/fix-input-height (HEAD)

最终得到:

             A'-B'-C'  <-- feature/fix-input-height
            /
...--o--o--o   <-- master
      \
       A--B--C   [previous feature/fix-input-height, now abandoned]

但是另一个仓库——不是你自己的那个,你让 Git 去 git push 的那个——仍然有原来的提交记录。你已经没有这些提交了。你有新的和改进过的提交,但是它们不知道这一点。他们只知道你要求他们抛弃掉三个完美的提交。

所以他们说:不,除非你用一个强制命令而不是礼貌的请求。

这就是为什么你需要 --force,或者更好的做法是使用 --force-with-lease,虽然人们不怎么使用它。无论哪种方式,你都告诉他们:是的,我意味着你应该放弃你的提交。这两者之间的区别在于,--force 只是说:扔掉你的提交!使用这个代替!而使用 --force-with-lease 则表示:我认为你的 feature/fix-input-height 命名的提交是 C。如果是这样的话:抛弃那些提交!使用这个代替!如果有人添加了你没有包含在重组中的提交 D,它将失败。


写得非常好,我现在对变基有更好的理解了。谢谢! - dimwittedanimal

3

Torek's answer毫无疑问是这里最有见地的答案,但考虑到你提出的问题和之后添加的评论,你的问题更多是政治而非技术方面的,你担心是正确的。

在这里主要关注的应该是“是否有其他人正在处理feature/fix-input-height或者这是一个私有分支?”

如果这个“特征”分支是共享的,那么你不应该进行变基,因为其他人仍然会尝试将更改应用到以前的参考中。如果它是完全私有的(这是分支的目的之一),那么你可以自由移动它。

然而,为了使Git更加满意,并避免你的同事手动重置他们自己的本地分支副本,我可能会执行以下操作:保留从旧版本到新版本的传递路径。即:

  • master上合并你的分支,但在解决冲突时仅选择左侧的修改,实际上会丢弃来自你的功能分支的所有内容并保持master不变。但这仍会引入一个合并点;
  • 重播你实际上想要移动到新的feature分支上的所有提交。

2

为什么不合并?

如果你经常使用--force命令感觉不对劲,也许你需要切换到一种“快进式工作流”:在这种工作流中,推送的提交永远不会改变。

这种工作流要求永远不要使用任何历史重写命令,比如rebase

当你想把主分支的更改合并到你的分支时,只需执行以下操作:

最初的回答:

git checkout master # Go on your local master branch
git pull            # Make sure is up to date
git checkout -      # Go back to the previous branch (you can use git checkout mybranch instead)
git merge master    # Merge master into your branch
git push            # Push the fast-forward changes to the repository

这将永远不会触发“non-fast-forward”错误或需要“--force”标志,因为您使用这些命令所做的唯一事情就是添加提交而不是重写它们。
如果您担心所有这些合并会使您的git日志输出混乱,请记住有一个选项“--no-merges”可以添加它们,对于快进式工作流程来说,它非常出色。

0

以下是我的想法,如果我有错,请指正。

如果你非常讨厌--force,那么我猜你可以从你的特性分支创建一个额外的分支,这个分支只用于rebase和解决冲突。例如:git checkout -b feature/fix-input-height-rebase

现在你可以执行git rebase master,解决冲突并推送:git push --set-upstream origin feature/fix-input-height-rebase

我认为这种方法唯一的问题(或者烦恼)就是你必须放弃之前的pull request,并创建另一个以rebase分支作为源分支,master作为目标分支的pull request。


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