如何使 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
标志不是一个选项,原因有两个。
- 每次您必须一直滚动到底部才能查看第一个
提交。那应该没有必要。我想从底部开始。
- 它不与
--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
解决方案对我有用。 \
和 /
不使用任何临时字符串,依靠 sed
s 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
命令都放在使用 sed
s -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
,或仅包含第一部分 Graph
。
sed
字符串由 9 个命令组成,这些命令执行我打算对原始答案执行的操作,但方式有点不同(特别是一些命令的顺序是颠倒的,以保存 x
命令).
- 第一个
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
)。
h
命令 "saves" 将模式 space 放入容器 space(将其视为抽屉)。
现在模式和保持 space 具有相同的内容(Graph OpeningColorTag\nHash\nClosingColorTag Message
或 Graph
)。
- 第二个
s
命令捕获并替换,只用它自己 (//
) 并丢弃它之前的所有内容 (^.*
, 即 Graph OpeningColorTag
),或者(\|
分隔捕获组中的备选方案 \(...\)
)
- newline-enclosed 哈希及其后的所有内容(即 提交主消息)
\n[a-z0-9]\{7\}\n.*
,
- 或end-of-line
$
,
现在模式 space 包含 \nHash\nClosingColorTag Message
,如果没有散列则为空字符串。
x
命令交换pattern和holdspaces的内容,使得多行\nHash\nClosingColorTag Message
(或空字符串)保存在holdspace,并且多行 Graph OpeningColorTag\nHash\nClosingColorTag Message
在模式 space 中,准备 re-edited.
- 第三个
s
命令从模式 space. 中剥离 \nHash
及其后的所有内容
现在模式 space 包含 Graph OpeningColorTag
.
-
y
将前两个 non-escaped /
之间的每个字符替换为第二个和第三个 non-escaped /
之间的相应字符。这里的反斜杠和正斜杠都必须用反斜杠转义。 (这应该是安全的,因为 OpeningColorTag
不应该包含任何翻译的字符。)
现在模式 space 包含 Hparg OpeningColorTag
,其中 Hparg
是 Graph
的 "inverted" 版本(或仅 Hparg
)。
G
命令获取保留 space 的内容并将其附加到(因此大写 G
;小写 g
将 复制到而不是附加到)模式space,中间有一个换行符\n
。
现在模式 space 包含 Hparg OpeningColorTag\n\nHash\nClosingColorTag Message
(或仅 Hparg\n
),从现在开始我们不关心保留 space。
- 第四个
s
命令捕获\nHash\n
部分并将其替换为Hash
。
现在模式 space 包含 Hparg OpeningColorTag\nHashClosingColorTag Message
或 Hparg\n
.
- 最后一个
s
命令删除剩余的换行符 \n
。
最后,模式 space 包含 Hparg OpeningColorTagHashClosingColorTag Message
或 Hparg
。
第 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 编号。
每当我在我的终端仿真器中查看 git log --all --graph --oneline --decorate
输出时,第一个提交就会显示在终端屏幕的顶部。当我使用 q
退出 git log
输出视图时,来自 的几行不再可见,因为屏幕底部附加了一些新行,用于下一个命令。
不过,通常情况下,这些顶行是最有趣的,因为它们类似于最近的 git 历史记录,所以我希望在我键入下一个 git 命令时它们仍然可见。
如何使 git log
输出从屏幕底部开始显示,即在底部查看第一个提交?您必须向上滚动才能查看较旧的提交。
注意:--reverse
标志不是一个选项,原因有两个。
- 每次您必须一直滚动到底部才能查看第一个 提交。那应该没有必要。我想从底部开始。
- 它不与
--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
解决方案对我有用。 \
和 /
不使用任何临时字符串,依靠 sed
s 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
命令都放在使用 sed
s -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
,或仅包含第一部分 Graph
。
sed
字符串由 9 个命令组成,这些命令执行我打算对原始答案执行的操作,但方式有点不同(特别是一些命令的顺序是颠倒的,以保存 x
命令).
- 第一个
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
)。
h
命令 "saves" 将模式 space 放入容器 space(将其视为抽屉)。
现在模式和保持 space 具有相同的内容(Graph OpeningColorTag\nHash\nClosingColorTag Message
或 Graph
)。
- 第二个
s
命令捕获并替换,只用它自己 (//
) 并丢弃它之前的所有内容 (^.*
, 即Graph OpeningColorTag
),或者(\|
分隔捕获组中的备选方案\(...\)
)- newline-enclosed 哈希及其后的所有内容(即 提交主消息)
\n[a-z0-9]\{7\}\n.*
, - 或end-of-line
$
,
- newline-enclosed 哈希及其后的所有内容(即 提交主消息)
现在模式 space 包含 \nHash\nClosingColorTag Message
,如果没有散列则为空字符串。
x
命令交换pattern和holdspaces的内容,使得多行\nHash\nClosingColorTag Message
(或空字符串)保存在holdspace,并且多行Graph OpeningColorTag\nHash\nClosingColorTag Message
在模式 space 中,准备 re-edited.- 第三个
s
命令从模式 space. 中剥离
\nHash
及其后的所有内容
现在模式 space 包含 Graph OpeningColorTag
.
-
y
将前两个 non-escaped/
之间的每个字符替换为第二个和第三个 non-escaped/
之间的相应字符。这里的反斜杠和正斜杠都必须用反斜杠转义。 (这应该是安全的,因为OpeningColorTag
不应该包含任何翻译的字符。)
现在模式 space 包含 Hparg OpeningColorTag
,其中 Hparg
是 Graph
的 "inverted" 版本(或仅 Hparg
)。
G
命令获取保留 space 的内容并将其附加到(因此大写G
;小写g
将 复制到而不是附加到)模式space,中间有一个换行符\n
。
现在模式 space 包含 Hparg OpeningColorTag\n\nHash\nClosingColorTag Message
(或仅 Hparg\n
),从现在开始我们不关心保留 space。
- 第四个
s
命令捕获\nHash\n
部分并将其替换为Hash
。
现在模式 space 包含 Hparg OpeningColorTag\nHashClosingColorTag Message
或 Hparg\n
.
- 最后一个
s
命令删除剩余的换行符\n
。
最后,模式 space 包含 Hparg OpeningColorTagHashClosingColorTag Message
或 Hparg
。
第 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 编号。