在当前git上,git push --force-with-lease origin +somebranch
、git push --force-with-lease origin somebranch
和git push origin +somebranch
之间是否存在实质性差异(不带加号)?三个人似乎都做了同样的事。
我试着找文件。我试图查看refspecin documentation,但不知道是否存在差异,如果存在差异,例如,当我想通过git pull --rebase origin master
拉入工作分支时,默认情况下应该选择哪个。
最佳答案
这是一个很好的问题;文档有点模棱两可,而且源代码非常混乱(force标志的实际应用非常分散)。
有一个答案很清楚。下面是the git push
documentation所说的,加上我的黑体字:--[no-]force-with-lease
--force-with-lease=<refname>
--force-with-lease=<refname>:<expect>
____________
__否则“git push”将失败。
想象一下,你必须改变你已经出版的东西。您必须绕开“必须快进”规则,才能将最初发布的历史记录替换为重新调整的历史记录。如果有人在你重新定位的时候建立在你原来的历史之上,那么远程分支的尖端可能会随着她的承诺而前进,盲目地推动——武力将失去她的工作。
____________如果远程引用仍然指向您指定的提交,则可以确保没有其他人对该引用执行任何操作。这就像在未显式锁定引用的情况下对该引用执行“租约”,并且仅当“租约”仍然有效时才更新远程引用。
______________
__——force with lease=在不指定预期值的情况下,将保护命名的ref(单独的),如果它将被更新,则要求其当前值与我们对它的远程跟踪分支相同。
__--强制使用lease=:将保护命名ref(单独),如果它将被更新,则要求其当前值与指定值相同(允许与我们对refname的远程跟踪分支不同,或者在使用此表单时,我们甚至不必有这样的远程跟踪分支)。
请注意,除了--force with lease=:明确指定ref的预期当前值之外的所有形式仍然是实验性的,它们的语义可能会随着我们对这个特性的体验而改变。
“--no force with lease”将取消命令行上所有先前的--force with lease。
因此,如果传输支持比较和交换选项1,并且您已写入--force-with-lease
而未写入--no-force-with-lease
,则所有更新(无论是否强制)都使用租用模式。
但是,--no-force-with-lease
清除了stored uppush_cas_option
结构,当那些已存储的值应用于每个refspec时,对我来说并不是很明显。
使用显式<refname>
也可以明显地只保护一个引用,而不管为它设置了什么强制标志。
当底层传输缺少对比较和交换的支持时,究竟会发生什么,我也不清楚。幸运的是,github的git服务器支持它,如果您特别提到github,这只会让您分心。
1内部,git源代码使用宏CAS_OPT_NAME
:force with lease函数的灵感来自现代cpu的比较和交换指令,这些指令原子性地测试某个变量是否设置为预测值,如果设置为预测值,则将其替换为新值,并以某种形式返回在变量中找到的实际值。
如果CPU体系结构使用条件代码,这可能会设置条件代码,但在大多数情况下(如果不是所有情况下),您都会得到旧值,以便在适当时可以重试比较和交换。例如,要实现atomic add one,可以循环使用:load r1,(r0); label: add r1,1,r2; cas r1,r2,(r0); bne label
;以实现atomic test和位2的设置:load r1,(r0); label: or r1,4,r2; cas r1,r2,(r0); bne label
;等等。例如,这种方法在英特尔奔腾和SPARC系统上使用。
一些CPU使用缓存机器。如果最接近CPU的缓存具有共享与独占模式(例如,mesi或moesi),我们可以使用“加载链接”或“加载锁定”指令,然后使用“存储条件”指令。条件存储只有在缓存线仍由当前CPU独占时才成功。在这种情况下,我们必须重新执行变量的初始锁定负载,我们的循环看起来更像:label: ll r1,(r0); add 1,r1; sc (r0),r1; bne label
。这在powerpc和mips架构上使用。
2典型地,所讨论的变量是内存位置,通常带有对齐约束,甚至在名义上支持未对齐内存的CPU上也是如此。例如,在intel haswell上,比较和交换8字节指令将在4字节边界上运行到完成,但它实际上不是原子的。当一个同事的内存分配器只提供4字节对齐时,我发现这是一个困难的方法。:-)