【问题标题】:Git --force-with-lease with + in branch (refspec)Git --force-with-lease with + in branch (refspec)
【发布时间】:2016-10-07 18:51:07
【问题描述】:

在当前的 Git 上,git push --force-with-lease origin +somebranchgit push --force-with-lease origin somebranchgit push origin +somebranch(没有加号)之间是否存在实质性区别?这三个似乎都在做同样的事情。

我试图寻找文档。我试图查看 refspec in documentation,但我不知道是否有区别,如果有,例如,当我想通过 git pull --rebase origin master 拉到工作分支时,默认情况下应该更喜欢哪个。

【问题讨论】:

    标签: git github


    【解决方案1】:

    当我想通过git pull --rebase origin master拉到工作分支时,默认情况下应该更喜欢哪个

    我在2013 for git 1.8.5, and March 2016 for git 2.8 中报告了force-with-lease

    我会说......他们都没有。
    pull --rebase 是为了避免强制推送(有或没有租约)任何东西。

    我只是设置(since git 2.6

    git config pull.rebase true
    git config rebase.autoStash true
    

    这让我可以做一些简单的git pull,然后是简单的git push(不涉及强制推送)

    【讨论】:

    • 好点,我忘了解决工作流程问题。使用--force-with-lease 可以防止通过强制推送故意删除“复活”提交,但如果您的协作者一开始不同意此类删除,则不需要它。因此,只有在您做一些不寻常的事情时才需要这种高级选项。
    • 为更多信息投票。实际上对我来说有一个分心,因为我并不总是隐藏但我提交,然后用之前的提交压缩它(假设我正在处理“相同的逻辑集”),这首先导致了这个问题。我没有过多考虑自动存储,但也许我应该考虑。
    • @Veksi 是的,我什至不再考虑存储或变基:如果需要,git 会为我做。
    【解决方案2】:

    这是个好问题;文档有点模棱两可,来源也很混乱(force flags的实际应用非常分散)。

    一个答案就足够清楚了。 the git push documentation 是这样说的,加了我的粗体字:

    --[no-]force-with-lease
    --force-with-lease=<refname>
    --force-with-lease=<refname>:<expect>

          通常,“git push”拒绝更新不是用于覆盖它的本地引用的祖先的远程引用。

          如果远程引用的当前值是预期值,则此选项会覆盖此限制。否则“git push”会失败。

          想象一下,您必须对已发布的内容进行变基。您必须绕过“必须快进”规则才能将您最初发布的历史记录替换为重新设置的历史记录。如果在你变基时其他人在你的原始历史之上构建,远程分支的尖端可能会随着她的提交而前进,而盲目地使用 --force 推送将失去她的工作。

          此选项允许您说您希望您正在更新的历史记录是您重新定位并想要替换的内容。如果远程 ref 仍然指向您指定的提交,您可以确定没有其他人对 ref 做任何事情。这就像在没有显式锁定它的情况下对 ref 进行“租用”,并且只有在“租用”仍然有效时才会更新远程 ref。

          --force-with-lease 单独,不指定详细信息,将通过要求其当前值与远程跟踪分支相同来保护将要更新的所有远程引用我们为他们准备了。

          --force-with-lease=,如果不指定预期值,将保护 命名的 ref(单独),如果它要被更新,通过要求它的当前值与我们拥有的远程跟踪分支相同。

          --force-with-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 清除了存储的 push_cas_option 结构,当这些存储的值应用于每个 refspec 时,对我来说并不是很明显。

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

    当底层传输缺乏对比较和交换的支持时会发生什么我也不清楚。幸运的是 GitHub 的 Git 服务器支持它,如果您专门指的是 GitHub,这只会分散您的注意力。


    1在内部,Git 源代码使用了宏 CAS_OPT_NAME:force-with-lease 的功能灵感来自现代 CPU 的 compare-and-swap 指令,它原子地测试是否有一些variable2 设置为预测值,如果是,则将其替换为新值,并以某种形式返回在变量中找到的实际值。

    如果 CPU 架构使用条件代码,这可能会设置条件代码,但在大多数情况下,如果不是所有情况,您都会获得旧值,以便您可以在适当的情况下重试比较和交换。例如,要实现原子加一,您可以循环使用:load r1,(r0); label: add r1,1,r2; cas r1,r2,(r0); bne label;实现第 2 位的原子测试和设置:load r1,(r0); label: or r1,4,r2; cas r1,r2,(r0); bne label;等等。例如,这种方法用于 Intel Pentium 和 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 字节对齐时,我发现了这一点很困难。 :-)

    【讨论】:

    • 伙计,这真的是深入调查此事。不仅是问题本身,还有一些潜在的问题,还有一些可以提供给搜索引擎的东西。
    猜你喜欢
    • 2021-01-22
    • 2020-04-06
    • 2015-08-13
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多