我编写了一个名为
git_diff_parent
的 bash 脚本,当传递提交句柄时,会执行 git diff commit~1 commit
;换句话说,它与其祖先不同,而无需在命令行上指定 commit~1
。我通过解析 git 命令行,查找哪个参数是提交字符串(使用 git cat-file -t
),将其替换为 commit~1 commit
,然后将新参数列表传递给 git diff
来完成此操作。我已在 /etc/gitconfig
中为该脚本起了别名,因此我可以将此命令执行为 git diff-parent
:
[alias]
diff-parent = !git_diff_parent
这个几乎可以工作,除非我尝试从顶级存储库目录以外的位置比较单个文件,例如:
% pwd
/home/myhome/github/my-branch/rtl
% git diff-parent branch -- mycode.sv
<no output>
% git diff-parent branch -- rtl/mycode.sv
<diff output appears>
为了调试此问题,我将
pwd
添加到我的脚本中以查看脚本的工作目录。你瞧,它总是从顶级目录(/home/myhome/github/my-branch
)而不是我所在的子目录启动。我什至尝试过git -C . diff-parent ...
但无济于事。
那么有没有办法让我的别名从当前工作目录启动?
https://git-scm.com/docs/git-config#Documentation/git-config.txt-alias
请注意,shell 命令将从存储库的顶级目录执行,该目录不一定是当前目录。
是从原始当前目录设置的。GIT_PREFIX
(强调和剪切是我的 — phd)
所以你可以在
cd $GIT_PREFIX
shell 脚本中执行git_diff_parent
。
添加到phd的答案:
设置...从原始当前目录。GIT_PREFIX
Git 2.46(2024 年第 3 季度),第 12 批 为:
请参阅 commit 291ef5b、commit d35a743、commit 174443e(2024 年 5 月 27 日),作者:Ian Wienand (
ianw
)。gitster
-- 合并于 commit 718b50e,2024 年 6 月 10 日)
:Documentation
:添加有关外壳扩展的注释alias
签署人:Ian Wienand
为 shell 扩展别名编写内联 shell 时(即
以“”为前缀),关于参数解析有一些需要注意的警告。!
这一系列笔记试图更清楚地解释正在发生的事情。
git config
现在包含在其 手册页中:
- Shell 命令别名始终接收提供给 Git 命令行作为位置参数。
- 如果您的 shell 别名是“单行”脚本,则应小心 使用多个命令(例如在管道中),引用多个 参数,或者无法处理位置参数 添加在最后。
例如:调用为alias.cmd = "!echo $1 | grep $2"
将被执行为 'git cmd 1 2
',这不是你想要的。echo $1 | grep $2 1 2
- 处理这个问题的一个便捷方法是编写脚本 内联函数中的操作,然后用任何调用 来自命令行的参数。
例如!c() {echo $1 | grep $2 ; }; c`" 将正确执行前面的示例。alias.cmd = "
- 设置
可以帮助您调试正在运行的命令 你的别名。GIT_TRACE=1
最后一部分(调试跟踪)启用:
:显示准备好的命令run-command
签署人:Ian Wienand
这在
中添加了一个跟踪点,因此我们可以看到完整的命令调用,而不必求助于 strace/代码检查。start_command
例如:
$ GIT_TRACE=1 git test foo git.c:755 trace: exec: git-test foo run-command.c:657 trace: run_command: git-test foo run-command.c:657 trace: run_command: 'echo $*' foo run-command.c:749 trace: start_command: /bin/sh -c 'echo $* "$@"' 'echo $*' foo
之前的更改使有关别名命令执行内部结构的文档更加清晰,但我仍然发现正在运行的别名命令的详细视图有助于调试目的。