我刚刚了解到git push --force-with-lease。太棒了 但是,当然,我不经常使用武力,因此我担心下次需要时可能会忘记此漂亮功能。
有没有一种配置git的方法,除非我有意覆盖它,否则git push -f它将自动使用?--force-with-lease--no-force-with-lease
(我无法想象曾经想在没有租约的情况下使用武力!)
我刚刚了解到git push --force-with-lease。太棒了 但是,当然,我不经常使用武力,因此我担心下次需要时可能会忘记此漂亮功能。
有没有一种配置git的方法,除非我有意覆盖它,否则git push -f它将自动使用?--force-with-lease--no-force-with-lease
(我无法想象曾经想在没有租约的情况下使用武力!)
Answers:
AFAIK没有可用的配置来告诉git始终使用force-with-lease而不是force。这似乎是功能请求的一个很好的例子。如果您没有任何问题可以深入git代码库,则可以自己实现并提交以供审核。
编辑就目前而言,这在2019年4月仍然是正确的。
在那之前,我经常看到的唯一选择就是创建一个alias用于此目的的。
要创建别名,可以使用git config --global alias.<alias-name> <command>,在本例中,我建议使用类似的名称。
git config --global alias.pushf "push --force-with-lease"
这将在全局.gitconfig文件中创建一个条目(通常可以在主目录中找到该条目)。在此之后,你可以简单地使用git pushf,以强制与租赁。
如果您想自己实现该功能,但不确定从哪里开始,则首先应查看git存储库中的文档目录。在这里,您可以找到编码准则以及有关如何提交补丁的信息。
您可以在官方社区页面上找到所有这些链接以及更多内容。
pushf但始终仔细检查我没有使用push -f,因为它看起来与别名相似。push -f无论如何,一些团队成员一直在使用,以为别名只是它的装饰性简写。最终,我们将更安全的表单别名pushfl改为,并不再担心它。
我担心我下次需要它时可能会忘记此漂亮功能。
Git 2.13(2017年第2季度)解释了为什么没有“保护”来防止忽略此推送选项,因为即使您在一级没有忘记它git push,它仍然可能被忽略。
见提交f17d642通过(2017年4月19日)ÆvarArnfjörðBjarmason( )avar。
(由Junio C gitsterHamano合并--在commit 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包括:
关于安全的一般说明:提供此选项时没有期望的值,即 与隐式运行在遥控器上并在后台(例如 ,在cronjob中的存储库中)隐式运行的任何内容
--force-with-lease或--force-with-lease=<refname>与之交互非常差。git fetchgit fetch origin它提供的保护措施可以
--force确保您的工作所基于的后续更改不会被破坏,但是如果某些后台进程在后台更新引用,这将是微不足道的。除了远程跟踪信息以外,我们没有其他任何东西,可以启发您希望看到的参考文献,并愿意为之烦恼。如果您的编辑器或某些其他系统
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,为您已经看到并愿意覆盖的上游代码版本创建标签,然后重写历史记录,最后强制将更改推送到master远程版本是否仍处于的状态base,而不管您本地中的本地版本remotes/origin/master已更新为什么。背景。
我的解决方案是创建一个包装器脚本,并使用一个别名,以便始终使用它代替real 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是否会奏效。实施方法:
-fgit这些说明假定运行bash的Linux或Mac。我尚未在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现在当您尝试强制执行推送时应该会感到不适。
您可以创建一个bash函数替换git和使用--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。
rm到rm -i在你的.bashrc; 您有一天会忘记并删除服务器上的重要文件。使用您自己的别名不存在该问题:)