这是一个常见的工作流程:
git commit -m 'add action buttons'
git rebase -i asdf123^
我想要一个别名来自动执行步骤 4-5,例如
git fixup add action buttons
。变基命令是:
$ git rebase -i 'HEAD^{/Add action buttons}^'
我认为这个别名应该有效,但它不起作用:
[alias]
fixup = !sh -c 'git rebase --interactive HEAD^{/$@}^'
奇怪的是,如果我这样做
git fum add action
,它就会起作用,但是git fum add action buttons
会抛出错误:fatal: invalid upstream 'HEAD^{/action'
。
我认为问题可能与引用有关,但我不知道如何转义别名中的引号。我试过这个:
[alias]
fixup = !sh -c 'git rebase --interactive \'HEAD^{/$@}^\''
但这会引发另一个错误:
fatal: bad config line 2 in file /home/dave/.gitconfig
。
来自
git-config(1)
手册页的这句话在这里很有用:
Shell 命令别名始终接收作为位置参数提供给 Git 命令行的任何额外参数。
- 如果您的 shell 别名是具有多个命令的“单行”脚本(例如在管道中)、引用多个命令,则应小心 参数,或者无法处理末尾添加的位置参数。例如:alias.cmd = "!echo $1 | grep $2" 称为 git cmd 1 2 将执行为 echo $1 | grep $2 1 2,这不是你想要的。
- 处理此问题的一个便捷方法是将脚本操作写入内联函数,然后使用任何参数调用该函数 从命令行。例如 `alias.cmd = "!c() { echo $1 | grep $2 ; }; c" 将正确执行前面的示例。
考虑到这一点,我们可以这样写你的别名:
[alias]
fixup = "!f() { git rebase -i \"HEAD^{/$*}^\" ; }; f"
如果我有这样的提交历史记录:
$ git log --oneline -8
423e981 (HEAD -> main) Reformat with gofmt
b9de0cb (origin/main) Refactor Makefile
be4ac65 Integrate options and common_options
042d122 Rename precommit workflow
d0f41ef Fully qualify package name
829bda3 Remove --exact-match from git describe command line
c8de23e Simplify pre-commit execution of golangci-lint
40b071a Update krew index manifest
然后我可以写:
git fixup precommit workflow
最终得到这样的选择列表:
pick 042d122 Rename precommit workflow
pick be4ac65 Integrate options and common_options
pick b9de0cb Refactor Makefile
pick 423e981 Reformat with gofmt
这就是你想要的。