如何使 git-log 向上滚动而不是向下滚动

How to make git-log scroll up instead of down

每当我在我的终端仿真器中查看 git log --all --graph --oneline --decorate 输出时,第一个提交就会显示在终端屏幕的顶部。当我使用 q 退出 git log 输出视图时,来自 的几行不再可见,因为屏幕底部附加了一些新行,用于下一个命令。

不过,通常情况下,这些顶行是最有趣的,因为它们类似于最近的 git 历史记录,所以我希望在我键入下一个 git 命令时它们仍然可见。

如何使 git log 输出从屏幕底部开始显示,即在底部查看第一个提交?您必须向上滚动才能查看较旧的提交。

注意:--reverse 标志不是一个选项,原因有两个。

  1. 每次您必须一直滚动到底部才能查看第一个 提交。那应该没有必要。我想从底部开始。
  2. 它不与 --graph 标志结合:fatal: cannot combine --reverse with --graph

首先,您可以随时将 -n 传递给日志,以打印出您感兴趣的任意数量的提交。


How can I make the git log output appear reversed

使用--reverse标志:

--reverse

Output the commits in reverse order.

git log --reverse

您可以在此处阅读有关 git 日志的更多提示和标志:
http://www.alexkras.com/19-git-tips-for-everyday-use/

接近预期结果的命令是

git --no-pager log --all --graph --decorate --oneline --color=always | tac | less -r +G -X

但是,这仍然使图形有点混乱,因为斜线没有正确反转。

更新

此命令还负责将斜杠与反斜杠交换,反之亦然。

git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed -e 's/[\]/aaaaaaaaaa/g' -e 's/[/]/\/g' -e 's/aaaaaaaaaa/\//g' | less -r +G -X

对应的git别名是

[alias]
    rlog = !"git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed -e 's/[\]/aaaaaaaaaa/g' -e 's/[/]/\\\\/g' -e 's/aaaaaaaaaa/\\//g' | less -r +G -X"

这个答案似乎适用于大多数极端情况。未彻底测试。

[alias]
    rlog = !"git --no-pager log --all --graph --decorate --oneline --color=always | tac | awk -f ~/switchslashes.awk | less -X +G -r"

其中文件 ~/switchslashes.awk 包含

{
    match([=11=],/([[:space:][:cntrl:]|*\/\]+)(.*)/,a) # find the segment of the graph
    tgt = substr([=11=],RSTART,RLENGTH)     # save that segment in a variable tgt
    gsub(/\//,RS,tgt)                   # change all /s to newlines in tgt
    gsub(/\/,"/",tgt)                  # change all \s to /s in tgt
    gsub(RS,"\",tgt)                   # change all newlines to \s in tgt
    gsub(/_/,"¯",tgt)                   # change all _ to ¯ in tgt
    print tgt substr([=11=],RSTART+RLENGTH) # print tgt plus rest of the line
}

这是 的修改版本。它将下划线替换为上划线,并将斜杠替换为反斜杠,反之亦然。这修复了文本被 tac.

反转后的图形

免责声明

我从来没有开始使用它,因为它在较大的存储库中速度很慢。它需要加载所有内容然后应用替换,这对我来说太花时间了。

原始答案,不起作用,因此请转到工作版本的编辑

如果直接从命令行使用,以下 sed 解决方案对我有用。 \/ 不使用任何临时字符串,依靠 seds y 命令

$ git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed 'h
s!\( *[0-9a-z]\{7\} .*\)\{0,1\}$!!
y/\\/_¯/\/\¯_/
x
s!\(.*\)\( *[0-9a-z]\{7\} .*\)\{0,1\}$!!
x
G
s/\n//' | less -X +G -r

它假定 SHA 代码的长度为 7 个字符,并将其用于 "recognize" 什么是 而不是 \、[=14] 的前导序列=]、|_*<space>,我无法将其放在第一个 s 命令的搜索模式的开头,并且代替第二个 s 命令中的第一个 .

我不知道为什么当所有 sed 命令都放在使用 seds -f 选项调用的脚本中时我无法让它工作。

编辑(上面的代码实际上是错误的)

正如@user1902689 所指出的,sed 脚本可以让任何人的眼睛流血,包括我自己,因为它们非常神秘。

在我看来,如果不使用 --color=always,任务将很容易完成,在这种情况下,文本会从 git log 中输出 会和我们在屏幕上看到的一样;使用--color=always,相反,插入像^[[33m这样的控制序列穿插在文本中以控制着色(不同分支不同颜色,...)。

但是有彩色输出很好,所以我将 git log --color=always ... 的输出定向到文件,并查看它,发现散列总是出现在 ^[[33m 和 [=36= 之间],其中 ^[ 是单个字符,可通过按 Ctrl+V,然后按 Esc.这些本质上是由 bash 解释为将颜色分别设置为黄色和返回白色的转义序列 (link)。

散列,它不是行中唯一的 7 个字母数字 characters-string(例如 thiswrd 可以在提交主消息中),几乎可以肯定是第一个,所以贪心表达式(sed has no non-greedy expressions)可以安全地使用after,并且不在 之前(在 hash-matching 正则表达式之前的 .* 将使该正则表达式匹配该行的最后 7 个字母数字 characters-string,可能是 anytext,例如,散列将丢失在 .* 中的某处)。为了允许以不吞噬散列的方式使用贪婪 .*,我们可以将散列包含在换行符 \n 之间,即 not.* 中的 . 匹配(因此,它们必须显式输入) 使用 s 命令,以便我们"limit" 可以通过在搜索模式中显式使用一些 \n.* 在连续 s 命令中的贪婪。

认为以下代码(稍后解释)不是确定的,因为它硬编码了用于获取彩色哈希字符串的着色转义序列,但只要我试过了。

$ git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed '
s/\(\(^[\[33m\)\([0-9a-z]\{7\}\)\(^[\[m\)\(.*\)\)/\n\n/
h
s/^.*\(\n[a-z0-9]\{7\}\n.*\|$\)//
x
s/\n[a-z0-9]\{7\}\n.*$//
y/\\/_¯/\/\¯_/
G
s/\n\([a-z0-9]\{7\}\)\n//
s/\n//' | less -X +G -r

每行包含三个部分 Graph OpeningColorTagHashClosingColorTag Message,或仅包含第一部分 Graphsed 字符串由 9 个命令组成,这些命令执行我打算对原始答案执行的操作,但方式有点不同(特别是一些命令的顺序是颠倒的,以保存 x 命令).

  1. 第一个 s 命令在 Hash 字符串 [0-9a-z]\{7\} 的每一侧放置一个换行符 \n (如果该行中没有散列,则不执行任何操作;请注意 before/after a merge/diverge 行后面没有散列或消息)。这样就有了"isolating"Hash的目的。请注意,捕获组 \(...\) 是根据开始标记 \( 的出现顺序编号的,因此在替换字符串中 \n\n:
    • </code>指的是<code>^[\[33m,即OpeningColorTag(注:^[是按Ctrl[=228得到的单个字符=]+V,然后 Esc,而 "true" [ 必须用反斜杠转义 \);
    • </code>指的是<code>Hash[0-9a-z]\{7\}
    • </code>指的是<code>ClosingColorTag^[\[m</code>的说法在这里也成立);</li> <li><code> 是后面的任何内容,.*(隐含地高达 end-of-line)。

现在模式 space(当前行,正如我们到目前为止所编辑的那样)包含原始行,散列的每一侧都有两个嵌入的换行符 (Graph OpeningColorTag\nHash\nClosingColorTag Message),或者未修改的原始行,如果它不包含散列 (Graph)。

  1. h 命令 "saves" 将模式 space 放入容器 space(将其视为抽屉)。

现在模式和保持 space 具有相同的内容(Graph OpeningColorTag\nHash\nClosingColorTag MessageGraph)。

  1. 第二个 s 命令捕获并替换,只用它自己 (//) 并丢弃它之前的所有内容 (^.*, Graph OpeningColorTag),或者(\| 分隔捕获组中的备选方案 \(...\)
    • newline-enclosed 哈希及其后的所有内容( 提交主消息)\n[a-z0-9]\{7\}\n.*
    • 或end-of-line $,

现在模式 space 包含 \nHash\nClosingColorTag Message,如果没有散列则为空字符串。

  1. x命令交换pattern和holdspaces的内容,使得多行\nHash\nClosingColorTag Message(或空字符串)保存在holdspace,并且多行 Graph OpeningColorTag\nHash\nClosingColorTag Message 在模式 space 中,准备 re-edited.
  2. 第三个 s 命令从模式 space.
  3. 中剥离 \nHash 及其后的所有内容

现在模式 space 包含 Graph OpeningColorTag.

  1. y 将前两个 non-escaped / 之间的每个字符替换为第二个和第三个 non-escaped / 之间的相应字符。这里的反斜杠和正斜杠都必须用反斜杠转义。 (这应该是安全的,因为 OpeningColorTag 不应该包含任何翻译的字符。)

现在模式 space 包含 Hparg OpeningColorTag,其中 HpargGraph 的 "inverted" 版本(或仅 Hparg)。

  1. G 命令获取保留 space 的内容并将其附加到(因此大写 G;小写 g复制到而不是附加到)模式space,中间有一个换行符\n

现在模式 space 包含 Hparg OpeningColorTag\n\nHash\nClosingColorTag Message(或仅 Hparg\n),从现在开始我们不关心保留 space。

  1. 第四个s命令捕获\nHash\n部分并将其替换为Hash

现在模式 space 包含 Hparg OpeningColorTag\nHashClosingColorTag MessageHparg\n.

  1. 最后一个 s 命令删除剩余的换行符 \n

最后,模式 space 包含 Hparg OpeningColorTagHashClosingColorTag MessageHparg

第 8 步和第 9 步不能融合在一起(例如 s/\n\n\([a-z0-9]\{7\}\)\n//),因为包含哈希的两个 \n 只有在行包含哈希(第 1 点的第一个 s。如果没有哈希,则不执行任何操作),而第一个 \n 始终存在,因为它带有 G 命令。


其实最外部的组\(...\)不需要(确实没用),可以去掉,所有对其他捕获组的数字引用都可以减1,例如 s/\(\(^[\[33m\)\([0-9a-z]\{7\}\)\(^[\[m\)\(.*\)\)/\n\n/可以更改为s/\(^[\[33m\)\([0-9a-z]\{7\}\)\(^[\[m\)\(.*\)/\n\n/;但我会在答案中保留不必要的组,因为它有机会提及捕获组的 not-so-widely-known 编号。