推送一个基于变基的分支?

3

我在这里遇到了一个小问题。我将开发分支合并到主分支上,然后试图推送它,但被拒绝了(非快进)…由于我不知道原因,所以来找你帮忙解决。

我的操作步骤如下:

git checkout dev
git rebase G
# Here, I had to manually merge some files

# Result (in gitk) was :
#       A---B---C remote/dev   A'---B'---C' dev
#      /                      /
# D---E---F------------------G---H remote/master

git push remote dev

有什么想法,为什么我的推送是“非快进”的,因此被拒绝了?

尝试在之前拉取远程/dev分支之前,我认为你应该在本地合并,而不是远程合并(换句话说,远程分支应该被集成到你的分支中,而不是你的分支被合并到远程分支中)。 - Vince
@Vince:拉(合并)远程将合并旧历史记录。原始发起人可能想要摆脱的历史记录。 - knittl
是的,你说得对,但合并策略是可配置的。我想@knitl的解决方案无论如何都可以工作。 - Vince
@Vince:是的,它们是可配置的,但大多数(全部?)合并策略都会记录合并的两个父提交,因此旧的历史记录将记录在合并提交中。 - knittl
那有什么不好的呢?我认为有一种方法可以知道选择了哪个代码,而且重整之前的代码可能也很有趣(这可能只是一个不同的用例)。 - Vince
这很糟糕,因为它是死的/未使用的历史记录(而且可能是重复的!) - knittl
1个回答

10

这不是快进,因为您进行了 rebase 操作。rebase 操作会将一系列提交合并成新的提交(可能在提交 DAG 中的不同位置)。在实际执行 git rebase 命令之前,请确保您理解运行该命令的所有影响。无法快进就是其中之一。

重写已发布的历史记录通常被认为是一个坏主意。如果您确实需要 rebase 自己的分支并推送它,请传递 -f 标志给 git push,或在 refspec 前面加上 + (git push remote +dev)。

其他人克隆了您的存储库并在该分支上工作,他们也必须执行相同的 rebase 操作,否则下次从贡献者合并时,您将合并旧的历史记录。


关于快进的详细说明:

从您的图表中可以很容易地看到这一点。快进基本上只会将提交附加到历史记录中。每个提交都由其提交哈希唯一标识。提交哈希通过提交内容和提交历史记录计算得出。这意味着具有不同祖先/父级的提交必将根据定义具有不同的哈希。

如果您将一些提交插入 DAG 中的不同位置,则它们将描述不同的历史记录并获得新的提交哈希(提交时间也会更新,但这不是重点)。因此,无法快进,因为它不再是仅追加。此外,在 rebase 和推送结果后,您将无法访问旧的提交(除非回退到 reflog)。

另一种思考方式是:您的推送将不会将提交附加到旧的(remote/dev)分支,而是将提交附加在其他位置(提交 G)。


感谢您详细的回答。我想要的是将 F 和 G 应用到我的 dev 分支上。根据您所说,我理解最好是合并而不是变基,类似于从 dev 进行 git merge G。我是正确的吗? - Arnaud Courtecuisse
没错。如果你想要 G(以及它的所有历史记录),你必须从你的 dev 分支运行 git merge G - knittl

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