繁体   English   中英

默认推送 --force-with-lease

[英]push --force-with-lease by default

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

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

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

目前没有办法将 git 配置为始终使用force-with-lease而不是force 因此,下一个最佳可用选项通常是创建一个用于此目的的别名。

编辑这在 2022 年 5 月仍然是正确的。但是git 2.30添加了一个额外的选项force-if-includes这使得force-with-lease更加安全; 如果您想了解其中的原因,请查看这个深入的答案

创建别名

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

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

这将在你的全局.gitconfig文件中创建一个条目(你通常可以在你的主目录中找到它)。 在此之后,您可以使用git pushfwl强制使用租赁

弄脏你的手

或者,您可以决定自己实现此功能! 如果您不确定从哪里开始,您可能需要查看git 存储库中的文档目录 在这里您可以找到有关如何提交补丁编码指南和信息。

您可以在官方社区页面上找到所有这些链接以及更多信息。

我的解决方案是创建一个包装脚本,并使用别名,以便我始终使用它来代替真正的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现在应该会变得很高兴。

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

Git 2.13 (Q2 2017) 解释了为什么没有“保护”来防止这个推送选项被遗忘,因为即使你没有git push级别忘记它,它仍然可能被忽略。

请参阅Ævar Arnfjörð Bjarmason ( avar )提交 f17d642 (2017 年 4 月 19 日)。
(由Junio C Hamano -- gitster --提交 46bdfa3中合并,2017 年 4 月 26 日)

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

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

像 Microsoft 的 VSC 等一些编辑器具有在后台自动获取的功能,这绕过了--force-with-lease--force-with-lease=<refname>提供的保护,如在此处添加的文档中所述.

所以git push的文档现在包括:

关于安全性的一般注意事项:提供此选项时没有预期值,即--force-with-lease--force-with-lease=<refname>与在要推送的远程上隐式运行git fetch的任何内容交互非常糟糕在后台,例如git fetch origin在您的存储库中的 cronjob 中。

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

如果您的编辑器或其他系统正在后台运行git fetch ,那么缓解这种情况的一种方法是简单地设置另一个远程:

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

现在,当后台进程运行git fetch origin时, 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标记,然后重写历史记录,最后如果远程版本仍然在base ,则强制将更改推送到master ,无论您的本地remotes/origin/master是什么remotes/origin/master已在后台更新。

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

您可以创建一个替换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即可。

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

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

添加到您的.bash_profile.bashrc.zshrc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM