如何在 git 日志图中显示相对提交数?

How to display relative commit number in git log graph?

我是 Mercurial 用户,正在探索 Git 存储库中的一些代码。在 Mercurial 中,我喜欢在提交图中上下移动,执行检出和 运行 代码以测试当我移动到 older/newer 提交时代码行为如何变化。这在 Mercurial 中很容易,因为它有本地相对修订号,当我在日志图中上下移动时,它们是 increment/decrement 的纯整数。我可以在 hg log.

中快速看到这些修订号

我需要在 Git 中进行这种类型的攀登 up/down 日志图。目前,我通过调用 git checkout master~1git checkout master~2git checkout master~3 等在 Git 中执行此操作。

这对于接近 master 的提交很好,但是当我低于 master 的 20 或 100 个提交时变得复杂。我觉得如果我能让 git loggit log --graph 向我显示相对提交号(从主提交的提交有多远)以及修订散列会更容易。

类似这样的事情(注意下面的 m~1m~2、数字):

$ git log --graph --oneline

*   7d49b65 2015-12-01 Merge pull request #538 from erwincoumans/master
|\  
| * 5da9e37 2015-11-26 add BT_DECLARE_ALIGNED_ALLOCATOR()
* |   0f8d94b (m~1) 2015-11-26 Merge pull request #536
|\ \  
| |/  
| * 4c88681 2015-11-26 joint trajectory curves use different colors
|/  
*   3463081 (m~2) 2015-11-24 Merge pull request #535
|\  
| * 0e24726 2015-11-24 use BT_ID_MAX as std::max is not portable
| * e387baf 2015-11-24 add collision and inverse dynamics
* |   a14a695 (m~3) 2015-11-24 Merge pull request
|\ \  
| |/  
| * 4205e97 2015-11-24 another fix for dynamic libs
* |   22e8dc9 (m~4) 2015-11-24 Merge pull request #533
|\ \  
| |/  
| * 5f97a56 2015-11-24 portability issues
* |   af142de (m~5) 2015-11-24 Merge pull request #532

是否可以在 git log 中获得此显示?关于如何实现这一目标的任何指示?

我不知道有什么方法可以用相对的 HEAD 修订来装饰 git 日志。

但另一种方法是,在 git log --graph 中看到要签出的提交后,使用其 SHA1

git checkout af142de # which is m~5

从那里,您可以进行与 SHA1 相关的额外检查:

git checkout af142de~1 # which is m~6

如果您使用的计算机可以使用 "nl" 和 "sed" 命令,请尝试以下操作:

git log --first-parent --pretty="%s - %ae" -50 |
        nl -v 0 |
        sed 's/\([0-9].*$\)/HEAD~/'

这是 运行 与 PHP 的 git 存储库相比的前 15 行输出:

 HEAD~0 Merge branch 'PHP-7.0' - ab@php.net
 HEAD~1 Merge branch 'PHP-7.0' - ab@php.net
 HEAD~2 Merge branch 'PHP-7.0' - ab@php.net
 HEAD~3 Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~4 Merge branch 'PHP-7.0' - ab@php.net
 HEAD~5 fix initializer for empty_fcall_info - ab@php.net
 HEAD~6 Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~7 Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~8 Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~9 Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~10    Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~11    Bump API numbers - nikic@php.net
 HEAD~12    Merge branch 'PHP-7.0' - nikic@php.net
 HEAD~13    unpack() function optional argument $offset. - dmitry@zend.com
 HEAD~14    Merge branch 'PHP-7.0' - ab@php.net
 HEAD~15    Removed zend_fcall_info.symbol_table - dmitry@zend.com

对于 Bash 可能会发现它有用的用户,这是一个简单的脚本,它以 git log 显示默认(完整)格式的 relative-to-HEAD 提交编号以及 --oneline 格式均支持 --graph 变体:

#!/bin/bash

fp="--first-parent"
if [[ "$*" =~ --graph ]]; then
    unset fp  # if --graph is among parameters '${fp:+$fp}' below yields nothing (no --first-parent to git log)
fi

n=0
git log --decorate=short --color=always ${fp:+$fp} "$@" |
while IFS="\n" read line; do
    if [[ "$line" =~ ^(\*.+)?.\[33m(commit|[0-9a-f]{7}) ]]; then
        line="$line HEAD~$n"  # append relative number at the end of line
        ((n+=1))              # increment number by 1
    fi
    echo "$line"   # print (either modified or untouched) line from git log to the output       
done

这个脚本可以放在例如到$HOME目录,我称它为:logn.sh。保存时(使用 chmod +x),可以在 ~/.gitconfig:

中声明引用它的 git 别名
...
[alias]
    logn = "!logn() { ~/logn.sh \"$@\" | less -r; }; logn"

| less -r 适用于喜欢在寻呼机中查看 git log 的用户(-r 用于保留颜色)。这可以删除。

该脚本依赖于以下正则表达式模式:^(\*.+)?.\[33m(commit|[0-9a-f]{7})。当谈到 --graph 格式时,带有 (\*.+)? 的部分是“偷偷摸摸的”,因为带有主要修订版(第一个 parent)的每一行都以星号 * 开头,因此我们可以利用它以这种方式匹配正确的修订。

\[33m 是确保我们在每个提交条目中处理 header(提交 SHA)行的技巧,因为它由 git 提供此颜色说明符(因此 --color=always 在脚本中)和模式的其余部分只是来自同一行的“commit”字或代表 --oneline 格式的直接 short-SHA。

如果不使用 --graph,脚本会强制使用 --first-parent 选项,因为顺序 HEAD 计数不正确/对 non-first-parent 提交(来自合并的分支)没有意义。

别名 (\"$@\") 和脚本 ("$@") 都将位置参数转发给 git log 命令,因此它可以与任何其他可能放置的参数一起使用,例如 -p-<n>(显示的提交数)、--name-only、提到的 --oneline--graph

如果我们过度篡改格式,正则表达式模式可能会停止匹配,并且不会附加相关数字。当然,如果我们通过 non-HEAD 修订版开始(例如 git logn HEAD^^git logn <non-HEAD-SHA1> 等),相对数字将无效。