为什么"git push helloworld + master:master"而不仅仅是"git push helloworld"?

S. *_*els 9 git git-push

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

$ git push helloworld
Run Code Online (Sandbox Code Playgroud)

但我得到了回报:

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'
Run Code Online (Sandbox Code Playgroud)

所以我找到了另一个关于"修改提交"的StackOverflow问题,并从那里尝试了一个建议而不知道它是否会对我有所帮助:

KaiserSosa@SMICHAELS /c/test/helloworld (master)
$ git push helloworld +master:master
Run Code Online (Sandbox Code Playgroud)

有效!

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

有人可以解释为什么这有效,但" git push helloworld"不是吗?

Von*_*onC 22

您似乎已在主分支中重写了您的历史记录(与提交相关联的SHA-1).

这意味着,您无法再进入快进模式.

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

注意:如果其他人已经克隆了您的存储库,这可能会很糟糕,因为他们将不再能够在没有冲突的情况下拉动您的主分支.
另请参阅此SO答案.


注意:如Junio C. Hamano所述:

有两种独立的安全机制:

  • 发送端安全可以通过" git push --force"和/或使用前缀为' +' 的refspec 来覆盖;

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

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


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

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

 $ git fetch origin
 $ git log master..origin/master
Run Code Online (Sandbox Code Playgroud)

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

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

$ git push origin +branchname
Run Code Online (Sandbox Code Playgroud)

这将强制更新.如果您没有权限,那么有时这会有效:

$ git push origin :branchname
$ git push origin +branchname
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果你倒带分支,其他人可能会在拉动时遇到问题.
他们有可能在他们发布的分支中合并你已经发布的新分支,有效地保留你试图摆脱的变化.
但是,只有他们的副本才会有不好的修改.出于这个原因,重绕分支被认为是轻微的反社会.尽管如此,它通常是合适的.