15

我最初尝试像这样推送我的(第一次!)git repo:

$ git push helloworld

但我得到了这个:

To git-smichaels@free5.projectlocker.com:helloworld.git
 ! [rejected]        HEAD -> master (non-fast forward) error:
 failed to push some refs to 'git-smichaels@free5.projectlocker.com:helloworld
git'

所以我发现了另一个关于“修改的提交”的 StackOverflow 问题,并尝试了一个建议,但并不知道它是否对我有帮助:

KaiserSosa@SMICHAELS /c/test/helloworld (master)
$ git push helloworld +master:master

有效!

但我不知道为什么它解决了我的问题:(

有人可以解释为什么这行得通,但“ git push helloworld”不行吗?

4

1 回答 1

26

看来您已经在您的主分支中重写了您的历史记录(与您的提交相关的 SHA-1)。

这意味着,您不能再以快进模式进行推送。

+master 强制推送发生:
通过使用可选的前导 +,<dst>即使更新不是快进,您也可以告诉 git 更新 ref。

注意:如果其他人已经克隆了您的存储库,这可能会很糟糕,因为他们将不再能够在没有冲突的情况下拉出您的主分支。
另请参阅this SO answer了解更多信息


注意:如Junio C. Hamano所述:

有两种独立的安全机制:

  • 发送端安全可以被“ git push --force”和/或使用前缀为' +'的refspec覆盖;

  • 接收端安全可以被 receive.denynonfastworwards您推送到的存储库的配置变量覆盖。

后者默认为“不安全”,但如果在存储库中激活了安全性,则从发送方强制不会将其停用。IOW,两端需要同意允许不安全的行为。


正如Git FAQ中提到的,一个可能的行动方案是:

最可能的原因是您需要先从遥控器中拉出。您可以通过先获取然后检查日志来查看远程端的更改。例如,

 $ git fetch origin
 $ git log master..origin/master

将列出远程端具有而您端没有的所有更改。
如果您想要图形表示,请使用 gitk --left-right master...origin/master.
左侧的箭头是您要推送的更改,右侧的箭头是远程侧的更改。

其他解决方案(这就是你所做的):

$ git push origin +branchname

这将强制更新。如果您没有权限,那么有时这会起作用:

$ git push origin :branchname
$ git push origin +branchname

即,首先远程删除分支(这通常是允许的),然后重新推送“新”(或者可能是重绕)分支。

请注意,如果您倒回树枝,其他人可能会在拉动时遇到问题。
他们有可能会在他们获取的分支中与您发布的新分支合并,从而有效地保留您试图摆脱的更改。
但是,只有他们的副本有错误的修订。出于这个原因,倒带分支被认为是轻微的反社会行为。尽管如此,它通常是合适的。

于 2009-09-25T06:19:08.620 回答