我通常会执行以下命令来将更改强制推送到远程分支:
git push --force origin head:{remote-branch}
我想创建一个git别名,以便我可以键入
git pfr {remote-branch}
并达到相同的效果。
我尝试将其添加到我的.gitconfig
文件中:
pfr = push --force origin head:
但是当我运行git pfr {remote-branch}
以使用别名时,出现了此错误:
fatal: invalid refspec 'head:'
有什么想法可以实现我想要的吗?
答案 0 :(得分:1)
这里的问题是别名被扩展,然后附加的参数作为分开的单词出现。也就是说,prf
扩展为:
push --force origin head:
使命令git pfr foo
变为:
git push --force origin head: foo
不是您想要的命令,它是:
git push --force origin head:foo
(请注意,这里没有空格-分支名称foo
与字符串head:
作为一个单词结合在一起。)
这种花哨的别名扩展需要比Git的别名处理功能更强大的功能。您可以放弃它,也可以使用shell别名。
这有点棘手。为了说明这一点,下面是一个带有别名echo
的shell别名,该别名打印出将要执行的操作,而不是执行以下操作:
prf = !echo git push --force origin head:$1
运行此命令时,它揭示了第一次尝试的问题:
$ git prf asdf
git push --force origin head:asdf asdf
$1
扩展到第一个参数,并将其作为组合的单个单词表达式的一部分放入其中,因此它变为head:asdf
。但是,然后重复$1
参数!这是因为Git传递了命令 git push --force origin head:$ 1 作为外壳程序应运行的命令,然后将 asdf 作为该命令的第一个参数。外壳程序将$1
扩展到适当的位置,然后也将参数保留在适当的位置,因此现在asdf
被重复。
要解决此问题,我们需要让shell调用 shell函数:
prf = "!f() { echo git push --force origin head:$1; }; f"
(因为它包含其他特殊字符,所以我们也需要引用整个内容。)运行 this 会产生:
$ git prf asdf
git push --force origin head:asdf
这表明如果删除echo
,它将做正确的事。
请注意,如果您不为$1
提供一个参数,则Shell仍将其扩展为空字符串。如果提供其他参数(将变为$2
,依此类推),它们将被丢弃。因此,总的来说,这种别名非常脆弱,并且整个方法通常都不是一个好方法。只要记住它的局限性,它就可以满足您的特定用例,但总的来说,您应该编写Git scripts ,而不是编写奇特的别名,在其中编写完整的程序(用sh / bash编写) )来检测并处理其所有 all 参数,检查使用不当,等等。
最后,请注意,您永远不要使用小写的head
来引用当前的提交或分支。您应该始终将其写为大写字母,例如HEAD
。您可以在Windows和MacOS上使用小写变体逃脱,但是事实证明,即使在这种情况下,如果使用git worktree add
,小写变体的表现也很差。如果您发现输入HEAD
太麻烦了,请记住@
是有效的同义词,因此您不必输入HEAD
或它的表亲head
,而只需输入一个字符@
。
答案 1 :(得分:0)
在您的仓库中,打开终端并输入
git config --local --replace-all alias.pfr "push origin -f"
如果您希望别名在全局存在,则可以使用--global选项。
git config --global --replace-all alias.pfr "push origin -f"
--replace-all
仅替换以前在配置中存在的任何其他名为pfr的别名。
在此之后,您将可以执行以下操作:
git pfr branchName
,相应的分支将被强制推向远程。
注意:如果其他同事正在使用您的分支,则强制将分支推到远程可能不是一个好主意,因为如果您在本地重写历史记录并强制推送,则当您的同行尝试合并/重新设置基准时,他们将陷入噩梦与您的分支。
希望这会有所帮助!