默认情况下,推送--force-with-lease

Dan*_*ich 119 git

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

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

(我无法想象在没有租约的情况下想要使用武力!)

Sas*_*olf 131

AFAIK没有可用的配置告诉git总是使用force-with-lease而不是force.这似乎是功能请求的一个很好的例子; 如果您没有问题可以深入了解git代码库,您可以自己实现并提交以供审核.

编辑目前,2018年2月仍然如此.

在那之前,我看到的唯一选择就是创建一个alias用于此目的的选项.

创建别名

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

git config --global alias.pushf "push --force-with-lease"
Run Code Online (Sandbox Code Playgroud)

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

弄脏你的手

如果您想自己实现该功能但不确定从哪里开始,您应该首先查看git存储库中的documentation目录.您可以在此处找到编码指南以及有关如何提交补丁的信息.

您可以在官方社区页面上找到所有这些链接等.

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

Von*_*onC 27

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

Git 2.13(2017年第二季度)解释了为什么没有"保护"来防止这个推送选项被遗忘,因为即使你没有git push关卡中忘记它,它仍然可能会被忽略.

提交f17d642通过(2017年4月19日)ÆvarArnfjörðBjarmason( )avar.
(由Junio C gitsterHamano合并- -46bdfa3承诺中,2017年4月26日)

push:--force-with-lease使用多个遥控器进行文档和测试

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

像微软的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,则这很容易被忽略.除了远程跟踪信息之外,我们没有任何东西可以作为你希望看到并且愿意破坏的refs的启发式.

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

git remote add origin-push $(git config remote.origin.url)
git fetch origin-push
Run Code Online (Sandbox Code Playgroud)

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

git push --force-with-lease origin-push
Run Code Online (Sandbox Code Playgroud)

除非你手动运行,否则会失败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
Run Code Online (Sandbox Code Playgroud)

base即为您已经看到并愿意覆盖的上游代码的版本创建标记,然后重写历史记录,最后强制推送更改,master如果远程版本仍在base,无论您的本地remotes/origin/master更新到什么背景.


Cor*_*ght 26

我的解决方案是创建一个包装器脚本,并使用别名,以便我总是用它代替真实的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
Run Code Online (Sandbox Code Playgroud)

该脚本的一些优点是:

  • 它训练我习惯性地使用--force-with-lease,所以当我弄错时我不会被唠叨
  • 如果由于某种原因,我们真的需要强制推动,git push --force将会奏效.

如何实现它:

  1. 创建一个自定义脚本,通过任何参数传递给git,除了 -f
  2. 别名该脚本,所以我们使用它而不是 git

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

~/.bash_profile:

alias git=~/.git_wrapper.sh
Run Code Online (Sandbox Code Playgroud)

~./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 "$@"
Run Code Online (Sandbox Code Playgroud)

通过这些更改,重新启动终端,git当您尝试强制推送时,现在应该变得高兴.

  • 这似乎很方便.+1.也许用"嘿,你温柔而简单的灵魂"取代"嘿白痴"或者像那样的人;) (14认同)

neu*_*242 8

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

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

添加到您的.bash_profile,.bashrc.zshrc.


Nic*_*las 5

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


pau*_*ani 5

您可以创建一个 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
}
Run Code Online (Sandbox Code Playgroud)

或者,在一行中:

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

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

  • 这个很危险:它会删除“git push -f”的所有参数 (7认同)
  • 人们可以想象一个更安全的版本,它会迭代参数,将“-f”或“--force”替换为“--force-with-lease”,并传播所有其他参数。 (2认同)