如何让重新分支回到原点?

时间:2013-09-27 04:28:06

标签: git git-rebase

我的同事和我最近实施了git,并且刚刚尝试实施变基。所以,我们有一个远程master分支,在本地克隆,我有一个名为changes的本地(和远程)分支。在本地,我们已经在changes上完成了一些工作,所以它看起来像这样:

master: A
        \
changes: B-C-D

因此,通过与其他地方无关的合并,master升级了,所以我们有:

master: A-E
        \
changes: B-C-D

所以,我做了一个改变:

git checkout changes
git rebase E (via a tag)

所以,在我当地的回购中,我有:

master: A-E
           \
changes:    B-C-D

所以,我试着推动,但得到了:

remote: error: denying non-fast-forward refs/heads/changes (you should pull first)

看起来,传统的智慧就是强行推动我的工作changes回到origin/changes

git push -f origin changes

回应:

remote: error: denying non-fast-forward refs/heads/changes (you should pull first)
To /opt/git/online.git
 ! [remote rejected] changes -> changes (non-fast-forward)
error: failed to push some refs to '/opt/git/online.git'

所以,我现在有点困惑。我假设工作流程是在对我的本地changes进行重组后,我可以让origin/changes排队。我误解了这个吗?

2 个答案:

答案 0 :(得分:1)

问题是你的最后一张图不是很准确,如B,C和& D都是新的提交,因此它们更像B',C'和& d':

        master: A-E
                |\
       changes:  \ B′-C′-D′
origin/changes:   B-C-D

从这个新的正确图表中可以看出,changes(D')不是origin/changes(D)的孩子。您可以通过查看git merge-base origin/changes changes是A,git merge-base --is-ancestor origin/changes changes返回1(错误)来验证这一点。

答案 1 :(得分:1)

使用push -f命令请求Git客户端尝试推送ref,即使它不是当前远程分支的后代。但是,上游存储库仍然可以拒绝该请求。

您可以通过更改上游存储库config文件中的配置选项来允许此操作:

[receive]
        denyNonFastforwards = false

Git book对此选项有以下说法:

  

<强> receive.denyNonFastForwards
  如果您重新提交已经推送的提交然后尝试再次推送,或者尝试将提交推送到不包含远程分支当前指向的提交的远程分支,那么您将被拒绝。这通常是好政策;但是对于rebase,您可以确定您知道自己在做什么,并且可以使用-f标志强制更新远程分支到您的推送命令。