Git非快进被拒绝

时间:2011-04-14 17:58:48

标签: git version-control

我觉得这个问题已被多次询问,但解决方案通常是“我删除了目录并重新完成了我的工作。”我做了提交和推送,但意识到我在提交消息中提到了错误的票号。所以我快速查看了SO solution并最终在终端中键入以下内容:

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."

唯一的问题是我收到以下错误消息:

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

我正在使用git-flow模型并正在开发分支。我怎样才能将东西重新合并以使git再次开心?

4 个答案:

答案 0 :(得分:172)

如果您将提交推送到服务器,然后在本地重写该提交(使用git resetgit rebasegit filter-branch或任何其他历史操作),然后推送重写提交回服务器,你会搞砸任何其他人。这是一个例子;说你已经提交了A,并将其推送到服务器。

-*-*-A <-- master

-*-*-A <-- origin/master

现在你决定以你提到的方式重写A,重置和重新提交。请注意,这会留下一个悬空提交,A,最终将被垃圾收集,因为它无法访问。

-*-*-A
    \
     A' <-- master

-*-*-A  <-- origin/master

如果其他人,让我们说Fred,在你这样做时从服务器上下来master,他们会引用A,他们可能会开始工作:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B <-- fred/master

现在,如果你能够将你的A'推向原点/主人,这将创造一个非快进,那么它的历史就不会有A.因此,如果弗雷德试图再次拉动,他突然必须合并,并将重新引入A提交:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B-\ 
    \     * <-- fred/master
     A'--/

如果Fred碰巧注意到了这一点,那么他就可以做一个rebase,这会阻止提交A再次出现。但他必须注意到这一点,并记得这样做;如果你有多个人将A拉下来,他们都必须进行重组,以避免在树中获得额外的A提交。

因此,改变其他人从中撤出的回购的历史通常不是一个好主意。但是,如果您碰巧知道没有其他人从该回购中获取(例如,它是您自己的私人回购,或者您只有另一个开发项目的开发人员可以轻松协调),那么您可以强制通过运行更新:

git push -f

git push origin +master

这些都会忽略对非快进推送的检查,并将服务器上的内容更新为新的A'版本,放弃A版本,以便最终进行垃圾回收。

使用receive.denyNonFastForwards配置选项可能会完全禁用强制推送。默认情况下,在共享存储库上启用此选项。在这种情况下,如果您确实想要强制推送,最好的选择是删除分支并使用git push origin :master; git push origin master:master重新创建它。但是,由于某种原因启用了denyNonFastForwards选项,如上所述;在共享存储库中,这意味着现在每个使用它的人都需要确保他们重新登录新历史记录。

在共享存储库中,通常最好只在顶部推送新的提交来解决您遇到的任何问题;您可以使用git revert生成将撤消先前提交更改的提交。

答案 1 :(得分:52)

强制git push

git push origin +develop

答案 2 :(得分:14)

您可能需要执行git pull,可以自动为您合并内容。然后你可以再次提交。如果您有冲突,它会提示您解决它们。

请记住,如果您没有更新gitconfig以指定...,则必须指定要从哪个分支中提取...

例如:

git pull origin develop:develop

答案 3 :(得分:7)

我使用的是EGit,我也遇到了这个问题。刚尝试rebase当前的分支,它发挥了作用。