我刚刚了解了git push --force-with-lease
。这太棒了。但是,当然,我不经常使用武力,所以我担心下次需要时我会忘记这个漂亮的功能。
有没有办法配置git所以git push -f
会自动使用--force-with-lease
,除非我故意用--no-force-with-lease
覆盖它?
(我无法想象在没有租约的情况下想要使用武力!)
答案 0 :(得分:114)
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
强制租赁。
如果您想自己实现该功能,但不确定从哪里开始,则应首先查看documentation directory in the git repository。您可以在此处找到关于coding guidelines的how to submit patches和信息。
您可以在official community page上找到所有这些链接以及更多内容。
答案 1 :(得分:24)
我的解决方案是创建一个包装器脚本,并使用别名,以便我总是使用它来代替真实的git
。
每当我尝试git push -f
时,我都会看到以下内容:
⚡ git push -f
hey idiot, 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
这些说明假设运行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 "hey idiot, use this instead so you don't cause race conflicts in the repo: git push --force-with-lease"
exit 1
fi
done
git "$@"
通过这些更改,重新启动终端,当您尝试强制推送时,git
现在应该变得很高兴。
答案 2 :(得分:18)
我担心下次需要时我会忘记这个漂亮的功能。
Git 2.13(2017年第2季度)解释了为什么没有“保护”这个推送选项被遗忘,因为即使你不在git push
级别忘记它,它也可能仍然被忽视。
commit f17d642见Ævar Arnfjörð Bjarmason (avar
)(2017年4月19日)
(由Junio C Hamano -- gitster
--合并于commit 46bdfa3,2017年4月26日)
push
:文件&amp;使用多个遥控器测试--force-with-lease
文件&amp;测试有两个遥控器指向的情况 相同的网址和后台提取&amp;后续的
git push --force-with-lease
不应该破坏我们尚未提取的未更新的引用。像微软的VSC这样的编辑有一个可以自动获取的功能 背景,这绕过了
--force-with-lease
&amp;提供的保护措施。--force-with-lease=<refname>
,如此处添加的文档中所述。
所以documentation for 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
即。为您的上游代码版本创建
master
标记 看到并愿意覆盖,然后重写历史记录,最后强制推送更改为base
如果远程版本仍在remotes/origin/master
,无论您的本地mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi 1 | 1.5 | 2 | 3 | 4
已更新到哪个背景。
答案 3 :(得分:2)
对于使用OMYZSH的用户,您只需使用ggfl
。
答案 4 :(得分:1)
我想提醒我,我不应该使用-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
中。
答案 5 :(得分:0)
您可以创建一个替换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
中即可。