将更改推送到远程存储库时,这个Git警告消息是什么?

描述有点简洁。 我只是在我的本地主分支添加一个文件,并将其推回到一个远程的回购。 任何想法,为什么这会来?

警告:更新当前分支
警告:更新当前签出的分支可能会导致混淆,
警告:由于索引和工作树不能反映在HEAD中的更改。
警告:因此,您可能会看到刚刚推入的更改
警告:当你在那里运行'git diff'时会恢复,你可能会想要
警告:在开始工作恢复之前运行'git reset --hard'。
警告: 
警告:您可以将“receive.denyCurrentBranch”configurationvariables设置为
警告:在远程存储库中“拒绝”禁止推入
警告:当前分支。
警告:要允许推入当前分支,可以将其设置为“忽略”。
警告:但是,除非您安排更新其工作,否则不build议这样做
警告:树匹配你以其他方式推送的东西。
警告: 
警告:要压制此消息,可以将其设置为“警告”。
警告: 
警告:请注意,未来版本的git中默认设置将会更改
警告:拒绝更新当前分支,除非你有
警告:configurationvariables设置为“忽略”或“警告”。   

实际上,这意味着几乎完全是这样的:有人在你所推送的存储库中工作,而且有人正在检查你正在推送的完全相同的分支。

这是非常令人困惑的,因为现在他认为他已经检查了最新版本的分支,而实际上,你刚刚更新了分支到一个更新的版本。 所以,当他现在运行git commit他的提交将基本上恢复您刚刚推送的所有提交。 而当他运行git diff时,即使他甚至没有改变任何东西,他也会看到与你刚推出的所有东西相反的东西。

出于这个原因,推到一个非裸仓库通常被认为是不好的做法。 你只能推到裸仓库,即没有附加工作副本的仓库。 至less你应该确保你不要推送到当前签出的分支,但是通常你不应该把你的代码推到别人的仓库中,而应该让他们从你那里撤离。

在一些特殊情况下,比如当你从一个Git仓库提供一个网站,并且想要通过推送来更新网站时,推送到当前已经签出的分支实际上是有意义的,但是在这种情况下,你必须确保你有一个安装的钩子,实际上更新检出的工作副本,否则您的网站将永远不会更新。

如果没有人在这个远程非裸回购工作,那么应该可以推到一个检出分支。

但是为了在这个操作中更安全一些,你现在可以(使用Git 2.3.0,2015年2月)在那个远程仓库中做:

 git config receive.denyCurrentBranch updateInstead 

它比configuration更安全receive.denyCurrentBranch=ignore :只有当你不重写正在进行的修改时,它才允许推送。

参见Johannes Schindelin( dscho )的 提交1404bcb :

receive-pack :为receive.denyCurrentBranch添加另一个选项

当在工作目录之间进行同步时,通过“ push ”而不是“ pull ”来更新当前分支可能比较方便,例如,当从虚拟机内部推送修补程序时,或者推送在用户计算机上进行修复时不能随便安装一个ssh守护进程,更别说知道用户的密码了)。

常见的解决方法 – 推入临时分支,然后在另一台机器上合并 – 不再需要使用此修补程序。

新的选项是:

 updateInstead 

相应地更新工作树,但如果有任何未提交的更改,则拒绝这样做。


提交4d7a5ce添加更多的testing,并提到:

前一个只testing一个情况,即通过push-to-deploy更新的path在已经添加到索引的目标工作树中有不兼容的变化,但是该特性本身想要求工作树是比testing的更清洁。

添加一些更多的testing来保护function免于未来的变化(从function的发明者的angular度来看)放松了清洁要求,即:

  • 只改变工作树,但不改变索引仍然是一个需要保护的变化;
  • 工作树中的未跟踪文件将被推送部署覆盖,需要加以保护;
  • 发生的变化使文件与被推送的内容相同仍然是要保护的变化(即,特征的清洁度要求比结帐要严格)。

此外,testing只对工作树进行统计变更不是拒绝部署推送的理由。

这是同样的问题, 这个问题 ,解决的办法是使用git init --bare或者git clone --bare