【发布时间】:2015-08-13 01:58:32
【问题描述】:
我刚刚了解了git push --force-with-lease。这真是太棒了。但是,当然,我不经常使用武力,所以我担心下次需要这个漂亮的功能时我可能会忘记它。
有没有办法配置 git,所以 git push -f 会自动使用 --force-with-lease,除非我故意用 --no-force-with-lease 覆盖它?
(我无法想象没有租约就想使用武力!)
【问题讨论】:
标签: git
我刚刚了解了git push --force-with-lease。这真是太棒了。但是,当然,我不经常使用武力,所以我担心下次需要这个漂亮的功能时我可能会忘记它。
有没有办法配置 git,所以 git push -f 会自动使用 --force-with-lease,除非我故意用 --no-force-with-lease 覆盖它?
(我无法想象没有租约就想使用武力!)
【问题讨论】:
标签: git
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 guidelines 和how to submit patches 的信息。
您可以在official community page 上找到所有这些链接以及更多信息。
【讨论】:
rm 别名为 rm -i 一样;有一天你会忘记并删除服务器上的一个重要文件。使用你自己的别名没有这个问题:)
pushf,但总是仔细检查我没有使用push -f,因为它看起来与别名相似。一些团队成员无论如何都在使用push -f,认为别名只是它的装饰性简写。最终,我们将更安全的表单别名为 pushfl 并不再担心它。
我担心下次需要这个漂亮的功能时我可能会忘记它。
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引用 onorigin-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在后台更新到什么。
【讨论】:
我的解决方案是创建一个包装脚本,并使用别名,以便我始终使用它来代替真正的 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 将起作用。如何实现:
-f 除外
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 现在应该会在您尝试强制推送时感到高兴。
【讨论】:
对于使用 OMYZSH 的人,您可以简单地使用 ggfl。
【讨论】:
gpf(注意:需要确保在~/.zshrc中启用了git插件)
您可以创建一个替换 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'* ]]; then
echo Hey stupid, use --force-with-lease instead
else
command git "$@"
fi
}
添加到您的.bash_profile、.bashrc 或.zshrc。
【讨论】: