【问题标题】:push --force-with-lease by default默认推送 --force-with-lease
【发布时间】:2015-08-13 01:58:32
【问题描述】:

我刚刚了解了git push --force-with-lease。这真是太棒了。但是,当然,我不经常使用武力,所以我担心下次需要这个漂亮的功能时我可能会忘记它。

有没有办法配置 git,所以 git push -f 会自动使用 --force-with-lease,除非我故意用 --no-force-with-lease 覆盖它?

(我无法想象没有租约就想使用武力!)

【问题讨论】:

    标签: git


    【解决方案1】:

    AFAIK 没有可用于告诉 git 始终使用 force-with-lease 而不是 force 的配置。这似乎是功能请求的一个很好的例子;如果您对 git 代码库没有任何问题,您可以自己实现它并提交以供审核。

    编辑就目前而言,到 2021 年 2 月仍然如此。

    在那之前,我看到的唯一选择是,像往常一样,创建一个用于此目的的alias

    创建别名

    要创建别名,可以使用git config --global alias.<alias-name> <command>,在我们的例子中,我会建议类似的东西。

    git config --global alias.pushfwl "push --force-with-lease"
    

    这将在您的全局.gitconfig 文件中创建一个条目(您通常可以在您的主目录 中找到该条目)。在此之后,您可以简单地使用git pushfwl force-with-lease

    弄脏你的手

    如果您想自己实现该功能但不确定从哪里开始,您应该首先查看documentation directory in the git repository。在这里您可以找到coding guidelineshow to submit patches 的信息。

    您可以在official community page 上找到所有这些链接以及更多信息。

    【讨论】:

    • 关于这不是一项功能的说明:反对重写标准命令(“push --force”)的常见论点是您习惯了它们,忘记了它们的起源,并且有一天不小心使用了它们以这种方式在一个新系统上。就像在 .bashrc 中将 rm 别名为 rm -i 一样;有一天你会忘记并删除服务器上的一个重要文件。使用你自己的别名没有这个问题:)
    • 个人轶事/注意事项:我尝试将其别名为pushf,但总是仔细检查我没有使用push -f,因为它看起来与别名相似。一些团队成员无论如何都在使用push -f,认为别名只是它的装饰性简写。最终,我们将更安全的表单别名为 pushfl 并不再担心它。
    【解决方案2】:

    我担心下次需要这个漂亮的功能时我可能会忘记它。

    Git 2.13(2017 年第二季度)解释了为什么没有“保护”以防止忘记此推送选项,因为即使您不要git push 级别忘记它,它可能仍然是忽略。

    参见Ævar Arnfjörð Bjarmason (avar)commit f17d642(2017 年 4 月 19 日)。
    (由 Junio C Hamano -- gitster -- 合并到 commit 46bdfa3,2017 年 4 月 26 日)

    push:使用多个遥控器记录和测试 --force-with-lease

    记录和测试有两个遥控器指向 相同的 URL,后台获取和后续的 git push --force-with-lease 不应破坏我们尚未获取的未更新引用。

    一些编辑器,比如微软的 VSC,在 背景,这绕过了--force-with-lease--force-with-lease=<refname> 提供的保护,如在此处添加的文档中所述。

    所以documentation for git push 现在包括:

    关于安全的一般说明:提供此选项时没有预期 值,即 --force-with-lease--force-with-lease=<refname> 与任何隐式运行 git fetch 的东西交互非常糟糕 要在后台推送到的遥控器,例如git fetch origin 在 cronjob 中的存储库中。

    它对--force 提供的保护是确保您的工作不是基于的后续更改不会被破坏,但是如果某些后台进程正在后台更新引用,这将被微不足道地破坏。除了远程跟踪信息之外,我们没有任何其他信息可以作为您希望看到并愿意破坏的裁判的启发式。

    如果您的编辑器或其他系统正在运行git fetch 背景为您减轻这种情况的一种方法是简单地设置另一个 远程:

    git remote add origin-push $(git config remote.origin.url)
    git fetch origin-push
    

    现在当后台进程运行时git fetch origin 引用 on origin-push 不会更新,因此命令如下:

    git push --force-with-lease origin-push
    

    除非您手动运行git fetch origin-push,否则将失败。
    这个方法当然完全被运行git fetch --all的东西打败了,在这种情况下,你需要禁用它或做一些事情 更乏味的是:

    git fetch              # update 'master' from remote
    git tag base master    # mark our base point
    git rebase -i master   # rewrite some commits
    git push --force-with-lease=master:base master:master
    

    即为您已使用的上游代码版本创建一个 base 标记 看到并愿意覆盖,然后重写历史记录,最后强制推送更改到master,如果远程版本仍然在base,不管你的本地remotes/origin/master在后台更新到什么。

    【讨论】:

      【解决方案3】:

      我的解决方案是创建一个包装脚本,并使用别名,以便我始终使用它来代替真正的 git

      每当我尝试git push -f 时,我都会看到以下内容:

      ⚡ git push -f
      use this instead so you don't cause race conditions in the 
      repo: git push --force-with-lease
      

      这个脚本的一些优点是:

      • 它训练我习惯性地使用--force-with-lease,所以当我弄错时我不会被唠叨
      • 如果出于某种原因,我们确实需要强制推送,git push --force 将起作用。

      如何实现:

      1. 创建一个自定义脚本,它将通过任何参数传递给 git,-f 除外
      2. 为该脚本命名,因此我们使用它而不是git

      这些说明假定 Linux 或 Mac 运行 bash。我没有在 zsh 或 Windows 上尝试过这个,但我认为它也可以在那里工作。

      ~/.bash_profile:

      alias git=~/.git_wrapper.sh
      

      ~./git_wrapper.sh:

      #!/bin/bash
      for arg in "$@"; do
          if [ "$arg" = "push" ]; then
              ispush=1
          elif [ "$ispush" = 1 -a "$arg" = '-f' ]; then
              echo "use this instead so you don't cause race conflicts in the repo: git push --force-with-lease"
              exit 1
          fi
      done
      
      git "$@"
      

      通过这些更改,重新启动您的终端,git 现在应该会在您尝试强制推送时感到高兴。

      【讨论】:

      • 这看起来很方便。 +1。也许用“嘿,你温柔而简单的灵魂”或类似的东西代替“嘿白痴”;)
      【解决方案4】:

      对于使用 OMYZSH 的人,您可以简单地使用 ggfl

      【讨论】:

      • gpf(注意:需要确保在~/.zshrc中启用了git插件)
      【解决方案5】:

      您可以创建一个替换 git 的 bash 函数并使用 --force-with-lease 代替 --force

      # replaces `git push --force` with `git push --force-with-lease`
      git() {
        if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then
          command git push --force-with-lease
        else
          command git "$@"
        fi
      }
      

      或者,在一行中:

      git() { if [[ $@ == 'push -f'* || $@ == 'push --force'* ]]; then command git push --force-with-lease; else command git "$@"; fi; }
      

      只需将其添加到您的 ~/.bashrc~/.zshrc

      【讨论】:

        【解决方案6】:

        我想提醒我不应该使用-f,但我不想被愚弄相信-f 意味着--force-with-lease。所以这是我的看法:

        git() {
          if [[ $@ == 'push -f'* ]]; then
            echo Hey stupid, use --force-with-lease instead
          else
            command git "$@"
          fi
        }
        

        添加到您的.bash_profile.bashrc.zshrc

        【讨论】:

          猜你喜欢
          • 2016-10-07
          • 2021-01-22
          • 2020-04-06
          • 2016-09-05
          • 2019-09-02
          • 1970-01-01
          • 1970-01-01
          • 2011-11-01
          • 1970-01-01
          相关资源
          最近更新 更多