git别名,用于强制推送到分支

时间:2019-05-10 16:36:39

标签: git alias

我通常会执行以下命令来将更改强制推送到远程分支:

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:'

有什么想法可以实现我想要的吗?

2 个答案:

答案 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

,相应的分支将被强制推向远程。

注意:如果其他同事正在使用您的分支,则强制将分支推到远程可能不是一个好主意,因为如果您在本地重写历史记录并强制推送,则当您的同行尝试合并/重新设置基准时,他们将陷入噩梦与您的分支。

希望这会有所帮助!