本文介绍了Git - 在分支中使用+与force(+ ref)(refspec)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在当前的Git中, git push --force-with-lease origin + somebranch , git push --force -with-lease origin somebranch git push origin + somebranch (没有加号)?三者似乎都做同样的事情。



我试图寻找文档。我试图在文档中查看refspec 说,加上我的黑体字:

因此,如果,支持compare-and-swap选项你已经写了 - force-with-lease 而不是 - no-force-with-lease 然后所有更新,强制与否,使用租赁模式。



- no-force-with-lease ,但是,清除了存储的 push_cas_option 结构,并且当这些存储值应用于每个refspec时,它对我来说并不是显而易见的。 / p>

使用显式的< refname> 也清楚地只保护一个引用,而不管为它设置了任何强制标志



当底层传输不支持比较和交换对我来说也是不清楚的。幸运的是,GitHub的Git服务器支持它,如果你特别指的是GitHub,这只是一个分心。






在内部,Git源代码使用宏 CAS_OPT_NAME :force-with-lease的功能受现代CPU的比较和交换指令的启发,它自动测试某些变量是否设置为预测值,如果是,则用新值替换它,并以某种形式返回变量中找到的实际值。



如果CPU架构使用条件代码,则可以设置条件代码,但在大多数情况下(如果不是全部),您将获得旧值,以便在适当的情况下重试比较和交换。例如,要实现原子加法,你可以循环: load r1,(r0); label:add r1,1,r2; cas r1,r2,(r0);标签标签;实现位2的原子测试和设置: load r1,(r0);标签:或r1,4,r2; cas r1,r2,(r0);标签标签;等等。例如,此方法用于Intel Pentium和SPARC系统。



有些CPU使用缓存机制。如果最接近CPU的高速缓存具有共享和独占模式(例如MESI或MOESI),我们可以使用加载链接或加载锁定指令,然后是存储条件指令。只有当高速缓存行仍由当前CPU独占时,条件存储才能成功。在这种情况下,我们必须重新执行变量的初始锁定加载,并且我们的循环看起来更像: label:ll r1,(r0);加1,r1; sc(r0),r1;标签标签。这在PowerPC和MIPS体系结构上使用。
$ b

通常,所讨论的变量是一个内存位置,通常具有对齐约束,即使在CPU上名义上支持未对齐的内存。例如,在Intel Haswell上,比较和交换8字节指令将在4字节边界上运行完成,但实际上它不会是原子的。当一个同事的内存分配器只提供4个字节的队列时,我发现这很难。 : - )

On current Git, is there a material difference between git push --force-with-lease origin +somebranch, git push --force-with-lease origin somebranch and git push origin +somebranch (without a plus)? All three seem to do the same thing.

I tried to look for documentation. I tried to look at refspec in documentation, but I don't know if there is a difference and if so, which would one should prefer by default when I like to pull to work branch via git pull --rebase origin master, for instance.

解决方案

This is a good question; the documentation is a bit ambiguous, and the source is very confusing (the actual application of force flags is widely scattered).

One answer is clear enough. Here is what the git push documentation says, with my boldface added:

Hence, if the compare-and-swap option is supported by the transport, and you have written --force-with-lease and not --no-force-with-lease, then all updates, forced or not, use the lease mode.

The --no-force-with-lease, however, clears out stored-up push_cas_option structure, and it's not immediately obvious to me when those stored-up value are applied to each refspec.

Using an explicit <refname> also clearly protects only the one reference, regardless of any force flag set for it.

Precisely what happens when the underlying transport lacks support for compare-and-swap is also not clear to me. Fortunately GitHub's Git servers support it, making this just a distraction if you're specifically referring to GitHub.


Internally, the Git source code uses the macro CAS_OPT_NAME: the function of force-with-lease is inspired by modern CPUs' compare-and-swap instructions, which atomically test whether some variable is set to a predicted value, replacing it with a new value if so, and also returning, in some form, the actual value found in the variable.

This may set condition codes, if the CPU architecture uses condition codes, but in most if not all cases you get the old value so that you can retry the compare-and-swap if appropriate. For instance, to implement atomic add-one, you can loop with: load r1,(r0); label: add r1,1,r2; cas r1,r2,(r0); bne label; to implement atomic-test-and-set of bit 2: load r1,(r0); label: or r1,4,r2; cas r1,r2,(r0); bne label; and so on. This method is used on Intel Pentium and SPARC systems, for instance.

Some CPUs use the cache machinery instead. If the closest-to-CPU cache has shared vs exclusive modes (e.g., MESI or MOESI) we can use a "load linked" or "load locked" instruction followed by a "store conditional" instruction. The conditional store succeeds only if the cache line is still exclusively owned by the current CPU. In this case, we must re-do the initial locked-load of the variable, and our loops look more like: label: ll r1,(r0); add 1,r1; sc (r0),r1; bne label. This is used on PowerPC and MIPS architectures.

Typically the variable in question is a memory location, often with alignment constraints, even on CPUs that nominally support unaligned memory. For instance, on the Intel Haswell, a compare-and-swap-8-byte instruction will run to completion on a 4-byte boundary, but it will not actually be atomic. I discovered this the hard way when a colleague's memory allocator provided only 4-byte alignment. :-)

这篇关于Git - 在分支中使用+与force(+ ref)(refspec)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 02:15