2009-09-25 75 views
9

我试图把我的(第一次!)混帐回购协议是这样开始:为什么“git push helloworld + master:master”而不是“git push helloworld”?

$ git push helloworld 

但我得到这个回:

To [email protected]:helloworld.git 
! [rejected]  HEAD -> master (non-fast forward) error: 
failed to push some refs to '[email protected]:helloworld 
git' 

所以我发现another StackOverflow question关于“修订提交”,并尝试了建议从那里不知道它是否会帮助我:

[email protected] /c/test/helloworld (master) 
$ git push helloworld +master:master 

它的工作!

但我不知道为什么它固定我的问题:(

有人能解释为什么这个工作,但“git push helloworld”不?

+1

针对您的评论添加了另一种解决方案。 – VonC 2009-09-25 06:41:54

回答

18

您似乎改写自己的历史记录(SHA-1 。您的提交)在你的主分支

这意味着,你可以不再推快进模式

的+主力对应的推送发生:
通过有可选的前导+,你可以告诉git更新<dst>裁判,即使更新不是快进。

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


注:如所提到的by 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 

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

被警告,如果您倒带分支,其他人可能会在拉动时出现问题。
他们可能会合并到分支中,并与您发布的新分支进行合并,从而有效地保留您试图摆脱的更改。
但是,它只会是他们的副本,具有不良的修订。出于这个原因,重绕分支被认为是轻度反社会的。尽管如此,它通常是合适的。

+0

这是一个私人git存储库,只是为了学习绳索 - 所以我不担心与他人的冲突。我想要做的是删除这个存储库,并在下次正确执行。我收到“[rejected]”消息后应该怎么做而不是“+ master:master”? – 2009-09-25 06:31:34

+0

就是这样。非常感谢!我从零开始重新编写它,但是这次我首先进行了拉取,然后运行。多奇怪的怪癖!在Mercurial中,我在创建新项目时从来不需要这样做。 – 2009-09-25 06:52:14

+0

由于相同的原因,hg push有一个强制标志。如果你改变历史(通过mq或其他),你将不得不强制推送。 – Dustin 2009-09-25 23:20:43