代码之家  ›  专栏  ›  技术社区  ›  Alexander Mills

git push—租赁强制vs.—强制

  •  15
  • Alexander Mills  · 技术社区  · 6 年前

    我试着去理解

    git push -f
    

    git push --force-with-lease
    

    我的猜测是后者只会推到远处 如果远程没有本地分支没有的提交 ?

    如果有更好的方式来表达这个问题,lmk,但希望它是明确的。

    4 回复  |  直到 6 年前
        1
  •  52
  •   chevybow    6 年前

    force 用本地分支覆盖远程分支。

    --force-with-lease 是一个更安全的选项,如果向远程分支添加了更多提交(由其他团队成员或同事或您所做的操作),则不会覆盖远程分支上的任何工作。它可以确保你不会用强迫的方式覆盖别人的工作。

    我认为你对这个命令的总体看法是正确的。如果远程分支与本地计算机上的远程分支具有相同的值,则将覆盖远程分支。如果它没有相同的值-它表示在您处理代码时其他人对远程分支所做的更改,因此不会覆盖任何代码。显然,如果在远程中有其他提交,那么值将不相同。

    我只是想到 --租赁强制 当我想确保我没有覆盖任何队友代码时使用。我公司的很多团队 --租赁强制 作为故障保护的默认选项。在大多数情况下这是不必要的,但是如果你碰巧覆盖了其他人贡献给remote的内容,就会省去很多麻烦。

    我相信你看过这些文档,但这里可能包含了一些更为冗长的解释:

    https://git-scm.com/docs/git-push

        2
  •  18
  •   Shakil    6 年前

    git推力 是破坏性的,因为它无条件地用本地拥有的内容覆盖远程存储库。吉特 推力 强烈建议这样做,因为它可以销毁已推送到共享存储库的其他提交。力推的一个最常见的原因是当我们被迫改变分支的位置时。

    例如。我们有一个项目有一个特性分支,Alice和Bob都将致力于此。他们都克隆了这个存储库并开始工作。 Alice最初完成了她的部分功能,并将其推送到主存储库。这一切都很好。鲍勃也完成了他的工作,但在把它推高之前,他注意到一些更改已经合并到master中。为了保持一棵干净的树,他在主枝上做了一个回扣。当然,当他去推动这个再平衡的分支,它将被拒绝。然而,他并没有意识到爱丽丝已经推动了她的工作,而是执行了一种推动力。不幸的是,这将删除Alice在中央存储库中的所有更改记录。

    什么 --租赁强制 does拒绝更新分支,除非它是我们期望的状态;即没有人更新上游分支。实际上,这是通过检查上游ref是否符合我们的期望来实现的,因为ref是散列,并且隐式地将父链编码为它们的值。

    Here 是一篇关于git push——force和git push——force with lease的好文章。

        3
  •  16
  •   Sergey Sergey    5 年前

    从可靠和/或官方渠道寻求答案。

    中提到的“比较和交换” torek 在里面 the comments his other answer 更进一步的例子是 sources of Git itself .

    后者只在远程没有本地分支没有的提交时推送到远程?

    这个功能是在 this commit (2013年12月,Git v1.8.5-rc0)

    --force-with-lease 将通过要求其当前值与某些合理的默认值相同来保护将要更新的所有远程引用,除非另有规定;

    目前,“一些合理的违约”暂时定义为 我们拥有的远程跟踪分支的值,用于更新远程的ref “,如果我们没有这样的远程跟踪分支,则这是一个错误。

    因此,“租赁”是指:

    " force-with-lease “:您假设在获取以确定应为重设基准的历史记录时,您对ref执行了租约,并且只有在租约未被破坏的情况下才能推后。

    消息人士仍然提到“cas”:

    • 此选项最初称为“ cas (用于“比较和交换”),这个名字没人喜欢,因为它太专业了。
    • 第二次尝试称之为“lockref”(因为它在概念上类似于在获取锁之后进行推送),但是“lock”这个词被痛恨,因为它暗示它可能会拒绝其他人的推送,而这不是该选项的工作方式。
    • 这一轮称之为“租赁强制”。
      您假设您在获取时对ref进行了租用,以决定应该是什么样的重设历史记录,并且只有在 租约没有被破坏。

    所以:“ git push --force-with-lease 与。 --force "

    正如我在“中提到的” push --force-with-lease by default “,正如Git 2.13(2017年第二季度)所提到的,选择 --租赁强制 可以是 忽略 如果一个后台进程(比如在带有Git插件的IDE中找到的进程)运行 git fetch origin .
    在这种情况下, --武力 占上风。

        4
  •  5
  •   G. Sylvie Davies    6 年前

    假设服务器上的任何预接收挂钩都接受推送,则始终会成功:

    git push --force
    

    然而,这在继续之前运行特定的客户端检查:

    git push --force-with-lease
    

    您可以手动运行特定的检查。以下是“租约检查”算法:

    1. 找出你现在的分店。

    2. 跑步 git for-each-ref refs/remotes . 注意git客户机认为与当前分支的上游状态相对应的提交id。

    例如,如果您在分支“foo”上,请注意与“refs/remotes/origin/foo”相关联的提交id。

    1. 立即确定上游git服务器上远程分支的实际提交id。

    2. 只有当从第2步和第3步提取的提交id一致时,才让“git push”继续。换句话说,只有当本地git克隆的上游概念与实际的上游一致时,才能继续。

    这里有一个悲伤的暗示:因为 git fetch 将“refs/remotes/origin/*”下的所有ref更新为其最新版本,此命令组合基本上与 git push --force :

    git fetch
    
    # The command below behaves identically to "git push --force"
    # if a "git fetch" just happened!
    
    git push --force-with-lease
    

    克服内在的弱点 git push --force-with-lease 我尽量不跑 git获取 . 相反我总是跑 git pull --rebase 每当我需要与上游同步时 git pull 只更新refs/remotes下的一个ref,保持 --force-with-lease 有用。

        5
  •  2
  •   Fish    6 年前

    租借的武力不一定安全。就像西尔维说的那样。注意:在git中,分支只是提交的指针。提交指向零个或多个父提交。即使你完全用一个硬git重置和一个强制的push或者一个不需要的force-with-lease来改变分支,这也不一定是个大问题。您可以使用本地git reflog查看分支上的本地提示(当时的头部在哪里?)已更改并重新设置并再次推动分支。然后,您只会丢失远程分支上的新提交,但即使它们也可能由团队成员还原。