如何使 git-log 向上滚动而不是向下滚动
Posted
技术标签:
【中文标题】如何使 git-log 向上滚动而不是向下滚动【英文标题】:How to make git-log scroll up instead of down 【发布时间】:2016-06-15 01:50:01 【问题描述】:每当我在终端模拟器中查看git log --all --graph --oneline --decorate
输出时,都会在终端屏幕顶部查看第一个提交。当我使用q
退出git log
输出视图时,其中的几行不再可见,因为屏幕底部附加了一些新行,用于下一个命令。
不过,通常情况下,最上面的那几行是最有趣的,因为它们类似于最近的 git 历史记录,所以我希望它们在我键入下一个 git 命令时仍然可见。
如何使git log
输出从屏幕底部开始出现,即在底部查看第一个提交?您必须向上滚动才能查看较旧的提交。
注意:--reverse
标志不是一个选项有两个原因。
-
每次您必须一直滚动到底部才能查看第一个
提交。那不应该是必要的。我想从底部开始。
它不与
--graph
标志结合使用:fatal: cannot combine --reverse with --graph
。
【问题讨论】:
你试过git log --reverse
吗?
Can I get git log to print the history in reverse order?的可能重复
@Jubobs 没有重复。 Git log --reverse 将从最后一次提交开始,这不是我想要的。此外,它不能与 --graph 结合使用。将更新问题以将其作为要求包含在内
When I have git log print out as oneline, how do I reverse it?的可能重复
@FarhadFaghihi 不,不,不。阅读问题。
【参考方案1】:
原来的答案,这不起作用,所以转到工作版本的编辑
如果直接从命令行使用,以下sed
解决方案对我有用。它不使用任何临时字符串通过sed
s y
命令切换\
和/
。
$ git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed 'h
s!\( *[0-9a-z]\7\ .*\)\0,1\$!\1!
y/\\\/_¯/\/\\¯_/
x
s!\(.*\)\( *[0-9a-z]\7\ .*\)\0,1\$!\2!
x
G
s/\n//' | less -X +G -r
它假定 SHA 代码长度为 7 个字符,并使用它来“识别”不是\
、/
、|
、_
、 *
和 <space>
,我无法将它们放在第一个 s
命令的搜索模式的开头,并在第二个 s
命令中代替第一个 .
。
我不知道为什么当所有 sed
命令都放在使用 sed
s -f
选项调用的脚本中时,我无法让它工作。
EDIT(上面的代码其实有问题)
正如@user1902689 所指出的,sed
脚本可以让任何人(包括我自己)眼睛流血,因为它们非常神秘。
在我看来,如果不使用--color=always
,则任务将很容易完成,在这种情况下,文本从git log
输出
会和我们在屏幕上看到的一样;使用--color=always
,相反,插入像^[[33m
这样的控制序列穿插在文本中来控制着色(不同的分支颜色不同,...)。
但是有一个彩色输出很好,所以我将git log --color=always ...
的输出定向到文件,并查看它,发现哈希总是出现在^[[33m
和^[[m
之间,其中^[
是按 Ctrl+V,然后按 Esc 可获得单个字符。这些本质上是 bash 解释为将颜色分别设置为黄色和变回白色的转义序列 (link)。
哈希值,它不是该行中唯一的 7 个字母数字字符串(eg thiswrd
可以在提交主消息中),几乎可以肯定是 first 一个,所以贪心表达式 (sed
has no non-greedy expressions) 可以安全地在 之后 使用,而 不能在之前 (.*
在哈希匹配正则表达式之前该正则表达式匹配该行的最后一个 7 字母数字字符串,例如,它可能是 anytext
,而哈希值会在 .*
的某处丢失)。为了允许以不吞噬散列的方式使用贪婪的.*
,我们可以将散列括在换行符\n
这不匹配 使用 .
中的 .*
(因此,它们必须显式键入)s
命令,以便我们可以在连续的 s
中“限制”.*
的贪婪通过在搜索模式中显式使用一些\n
命令。
我认为以下代码(稍后解释)不是确定的,因为它对用于获取彩色哈希字符串的着色转义序列进行硬编码,但只要我尝试过,它就可以工作。
$ git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed '
s/\(\(^[\[33m\)\([0-9a-z]\7\\)\(^[\[m\)\(.*\)\)/\2\n\3\n\4\5/
h
s/^.*\(\n[a-z0-9]\7\\n.*\|$\)/\1/
x
s/\n[a-z0-9]\7\\n.*$//
y/\\\/_¯/\/\\¯_/
G
s/\n\([a-z0-9]\7\\)\n/\1/
s/\n//' | less -X +G -r
每一行包含三个部分Graph OpeningColorTagHashClosingColorTag Message
,或者只包含第一部分Graph
。
sed
字符串由 9 个命令组成,这些命令执行我打算对原始答案执行的操作,但方式略有不同(尤其是某些命令的顺序颠倒了,以保存 x
命令)。
-
第一个
s
命令在Hash
字符串[0-9a-z]\7\
的每一侧放置一个换行符\n
(如果此行中没有散列,则不执行任何操作;请注意合并之前/之后的行/分歧没有散列或消息跟随它们)。这样做的目的是“隔离”Hash
。请注意,捕获组\(...\)
是根据打开标记\(
的出现顺序编号的,因此在替换字符串\2\n\3\n\4\5
中:†
\2
指的是^[\[33m
,即OpeningColorTag
(注意:^[
是通过按Ctrl+V,然后按 获得的单个字符Esc,而“真”[
必须使用反斜杠 \
);
\3
指的是Hash
,[0-9a-z]\7\
\4
指的是ClosingColorTag
、^[\[m
(这里所说的\2
也成立);
\5
是后面的任何内容,.*
(隐含到行尾)。
现在,模式空间(当前行,正如我们目前所编辑的那样)包含原始行,在散列 (Graph OpeningColorTag\nHash\nClosingColorTag Message
) 的每一侧都有两个嵌入的换行符,或者如果它不包含散列,则为未修改的原始行(Graph
)。
h
命令将模式空间“保存”到保持空间(将其视为抽屉)。
现在模式和保持空间具有相同的内容(Graph OpeningColorTag\nHash\nClosingColorTag Message
或 Graph
)。
-
第二个
s
命令捕获并替换,仅使用它自己 (/\1/
) 并丢弃它之前的所有内容 (^.*
, ie Graph OpeningColorTag
),或者 (\|
分隔捕获组中的替代品\(...\)
)
换行符封闭的散列及其后面的所有内容(即提交主消息)\n[a-z0-9]\7\\n.*
,
或行尾$
,
现在模式空间包含\nHash\nClosingColorTag Message
,如果没有散列,则为空字符串。
x
命令交换pattern和hold space的内容,使得多行\nHash\nClosingColorTag Message
(或空字符串)保存在hold space,多行Graph OpeningColorTag\nHash\nClosingColorTag Message
在pattern space,准备就绪重新编辑。
第三个s
命令从模式空间中去除\nHash
及其后面的所有内容。
现在模式空间包含Graph OpeningColorTag
。
y
将前两个非转义 /
之间的每个字符替换为第二个和第三个非转义 /
之间的对应字符。这里反斜杠和正斜杠都必须用反斜杠转义。 (这应该是安全的,因为OpeningColorTag
不应包含任何已翻译的字符。)
现在模式空间包含Hparg OpeningColorTag
,其中Hparg
是Graph
的“反转”版本(或仅Hparg
)。
G
命令获取保留空间的内容并将其附加到(因此大写的G
;小写的g
将复制到 而不是附加到)模式空间,中间有一个换行符\n
。
现在模式空间包含Hparg OpeningColorTag\n\nHash\nClosingColorTag Message
(或仅Hparg\n
),从现在开始我们不再关心保持空间。
-
第四个
s
命令捕获\nHash\n
部分并将其替换为Hash
。
现在模式空间包含Hparg OpeningColorTag\nHashClosingColorTag Message
或Hparg\n
。
-
最后一个
s
命令删除剩余的换行符\n
。
最后,模式空间包含Hparg OpeningColorTagHashClosingColorTag Message
或Hparg
。
步骤 8. 和 9. 不能融合在一起(eg s/\n\n\([a-z0-9]\7\\)\n/\1/
),因为只有当行包含哈希时,包含哈希的两个 \n
才存在(第一个 @987654436第 1 点的@。如果没有哈希,则不执行任何操作),而第一个 \n
始终存在,因为它带有 G
命令。
† 实际上最外部的组
\(
...\)
是不需要的(确实没有使用),因此可以将其删除,并且所有对其他捕获的数字引用组可以减1,eg s/\(\(^[\[33m\)\([0-9a-z]\7\\)\(^[\[m\)\(.*\)\)/\2\n\3\n\4\5/
可以改为s/\(^[\[33m\)\([0-9a-z]\7\\)\(^[\[m\)\(.*\)/\1\n\2\n\3\4/
;但我会在答案中保留不必要的组,因为它有机会提及不那么广为人知的捕获组编号。
【讨论】:
有没有机会对每一行进行快速评论,以帮助对sed
有所了解但看到此内容时眼睛模糊的读者?有点像接受的答案,这对我来说不能正常工作。
变成这样:| | * 2ac7376 将远程跟踪分支“grooverdan\gcc-power-tune”合并到 travis¯ppc64le
@user1902689,我想我已经修复了命令(前者仍在答案中,以防万一)。我试图解释清楚,但sed
脚本无论如何都非常神秘。如果您还有其他需要,请再次评论。
哇,我希望能添加几句话。我真的很感激你在那里所做的工作。不能感谢你。它不仅在这里帮助我,而且最终让我走出我的sed
舒适区。但是,我确实在复制/粘贴新的 less
时显示为空。删除less
给出:sed: -e expression #1, char 64: unterminated 's' command
。使用 GNU sed 4.5。我最终想在我的.gitconfig
中将其作为lg
的别名添加,所以在我可以在bash 中运行它之后,我会看看我是否可以找出sed -f
问题,或者如何重新逃避.gitconfig
中的一切。
新版本可以将其导出到文件(删除开始/结束单引号)和-f
,这使得将其添加到.gitconfig
变得微不足道。 (我从未尝试过-f
和原始版本。)lgnew = "!f() git --no-pager log --all --graph --decorate --oneline --color=always | tac | sed -f /etc/sed/gitGraphFlip.sed; ; f"
【参考方案2】:
这是一个似乎可以捕捉到大多数边缘情况的答案。未经彻底测试。
[alias]
rlog = !"git --no-pager log --all --graph --decorate --oneline --color=always | tac | awk -f ~/switchslashes.awk | less -X +G -r"
文件~/switchslashes.awk
包含的位置
match($0,/([[:space:][:cntrl:]|*\/\\]+)(.*)/,a) # find the segment of the graph
tgt = substr($0,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($0,RSTART+RLENGTH) # print tgt plus rest of the line
这是this script 的修改版本。它将下划线替换为上划线,将斜杠替换为反斜杠,反之亦然。这会在文本被 tac
反转后修复图形。
免责声明
我从来没有开始使用它,因为它在较大的存储库中速度很慢。它需要加载所有内容,然后应用替换,这对我来说太耗时了。
【讨论】:
在 OS X 上,tac 不可用。您可以安装 GNU coreutils 并改用 gtac。 用免责声明修改了答案。【参考方案3】:首先,您始终可以将-n
传递到日志以打印出您感兴趣的任意数量的提交。
如何使 git log 输出显示为反向
使用--reverse
标志:
--reverse
以相反的顺序输出提交。
git log --reverse
您可以在此处阅读有关 git log 的更多提示和标志:http://www.alexkras.com/19-git-tips-for-everyday-use/
【讨论】:
我不知道我对哪些行感兴趣,所以我不能-n
。另外,我已经更新了关于需要使用 --graph 参数的 OP,该参数不与 --reverse 一起使用。【参考方案4】:
一个接近预期结果的命令是
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"
【讨论】:
使用***.com/a/35754356/1546844中的awk替换脚本,可以改进斜线切换,使其仅适用于图形部分以上是关于如何使 git-log 向上滚动而不是向下滚动的主要内容,如果未能解决你的问题,请参考以下文章