我将此问题/错误发布到GIT官方频道,但未得到任何回应。希望有人可以帮助我。
当 receive.denyCurrentBranch 设置为 updateInstead 时,以下行为对我来说似乎是不正确的 receive.denyNonFastForwards 设置为 true 。以下是步骤 重现场景。
步骤1-设置远程存储库(远程主机):
git config --global receive.denyCurrentBranch updateInstead
git config --global receive.denyNonFastForwards true
mkdir /tmp/hello
cd /tmp/hello
git init
echo hello > hello.txt
git add . && git commit -m "hello.txt"
步骤2-创建2个克隆(本地主机):
git clone ssh://REMOTEIP/tmp/hello /tmp/hello1
git clone ssh://REMOTEIP/tmp/hello /tmp/hello2
第3步-从克隆1推送提交
cd /tmp/hello1
echo hello1 > hello1.txt
git add . && git commit -m "hello1.txt"
git push
这时服务器工作树包含预期的hello1.txt
步骤4:尝试从克隆2强制推送提交
cd /tmp/hello2
echo hello2 > hello2.txt
git add . && git commit -m "hello2.txt"
git push
Remote拒绝,并显示一条消息,其中Remote包含我在本地没有有效的工作。现在我强行推动。
git push --force
远程再次拒绝并出现错误:拒绝非快进 裁判/负责人/大师(你应该先拉)
在这一点上,由于推送被拒绝,我希望服务器 工作树中不包含任何拒绝的更改。但是服务器 工作树已更新,可以删除hello1.txt并创建hello2.txt。 推送被拒绝,但不是真的。
当更新挂钩时,我也注意到了相同的行为(不正确) 拒绝服务器上的更改(但不拒绝预接收挂钩)。
答案 0 :(得分:4)
问题在于这两种配置存在冲突(尽管我同意原则上不应是):
receive.denyCurrentBranch
设置为updateInstead
在这种情况下,Git在接收期间会注意到目标是当前分支,因此Git会检查提交。
和
receive.denyNonFastForwards
设置为true
。
这是单独发生的:名称的更改被拒绝。提交已被执行,并且存储库签出发生,并且 now 对 name 的更改被拒绝。
当更新挂钩拒绝服务器上的更改(但不是预先接收挂钩)时,我也注意到了相同的行为(不正确)。
这是相同的问题:pre-receive挂钩在任何单个引用更新之前运行一次,并且可以拒绝整个推送。然后,如果预接收钩子清除了要继续的操作,则更新钩子可以拒绝任何单独的引用名更新。但是,updateInstead
与接受或拒绝分支名称更新是分开发生的。
对于Git,最好在内部审查工作表更改,直到之后审核参考更新。这将需要对Git的内部进行一些重做。如果这不是Git中的彻底错误,那至少是相当令人惊讶的。实际上,所有这些代码仍然需要一些工作,因为如果您使用git worktree add
,Git将无法将添加的工作树的HEAD视为当前分支。考虑到所有这些警告,我建议仅使用裸存储库作为推送目标,并使用后接收挂钩直接在其他存储库或工作树中进行更新。
放在一边(这是一条评论,但是太短了,无法很好地表达出来):
git config --global receive.denyCurrentBranch updateInstead git config --global receive.denyNonFastForwards true
尽管这与您观察到的特定行为无关,但这绝对是错误的做法。运行git config --global
会为您个人设置配置项目。也就是说,它们进入/home/rajesh
(或您的主目录配置所在的位置)。但是receive.*
的设置应为每个存储库 。
由于您自己使用ssh
进行推送,因此这些配置参数确实生效-但是,如果您曾经通过其他方法进行推送,则它们可能不会生效。使用git config
而不使用--global
进行的每个存储库设置仍将生效。
答案 1 :(得分:0)
我希望服务器的工作树中不包含任何拒绝的更改。但是服务器工作树已更新,可以删除hello1.txt并创建hello2.txt。
推送被拒绝,但不是真的。
从Git 2.20开始(2018年第四季度),该推送将确实被拒绝。
在此之前,receive.denyCurrentBranch=updateInstead
代码路径也会被踢入,即使在推送由于其他原因而被拒绝的情况下,例如它没有快进或更新挂钩也已将其纠正。
请参见commit b072a25的Junio C Hamano (gitster
)(2018年10月19日)。
(由Junio C Hamano -- gitster
--在commit 4c7f544中合并,2018年10月30日)
receive
:denyCurrentBranch=updateinstead
不应盲目更新
receive.denyCurrentBranch=updateInstead
的处理已添加到 一个处理该变量其他值的switch语句,但是 其他所有案件仅检查条件以拒绝 尝试推送,或让同一功能中的后续逻辑仍然 进行干预,以使推送不会快速前进(即 在有问题的switch语句后检查)。但是
updateInstead
的处理错误地立即生效, 而没有给予其他支票干预的机会。而不是调用会引起副作用的
update_worktree()
立即,请注意我们需要致电 稍后再运行,然后先给其他支票一个拒绝的机会 请求。
在update-hook
有机会拒绝推送之后(发生在一系列检查的最后一步),请在我们较早发现需要这样做时致电update_worktree()
。
在您的情况下,考虑到您的推送被拒绝,按预期,您的工作树将不包含任何被拒绝的更改。