请教有关一个 git 历史提交的问题

没错,历史记录是很多:

⋊> pwd
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula

⋊> git hist | wc -l
   35933

但是没必要一次全部列出来,如果整个历史,全部输出到终端,屏幕滚半天,有什么意义,眼睛最终只能看到一屏。只关心最近的就好:

⋊> git hist -10
* 3fd7a855a  (HEAD -> master, origin/master, origin/HEAD) imagemagick@6: update 6.9.9-11 bottle. [BrewTestBot] 2017-09-05
* e8c11d312  imagemagick@6 6.9.9-11 [ilovezfs] 2017-09-05
* e81f29136  blockhash: update 0.2.1_3 bottle. [BrewTestBot] 2017-09-05
* 117618359  mgba: update 0.5.2_4 bottle. [BrewTestBot] 2017-09-05
* 275cb3c9d  imagemagick: update 7.0.7-0 bottle. [BrewTestBot] 2017-09-05
* 7aee6880f  zbar: update 0.10_7 bottle. [BrewTestBot] 2017-09-05
* a740e38bb  pqiv: update 2.9_2 bottle. [BrewTestBot] 2017-09-05
* 2ad14a63d  dmtx-utils: update 0.7.5_2 bottle. [BrewTestBot] 2017-09-05
* dbf495a41  zbar: revision for imagemagick [ilovezfs] 2017-09-05

或者要查找特定的提交:

⋊> git hist | grep mpv | head -10
* 6b43f46bc  mpv: add option to enable audio CD playback (#16549) [gtm87x] 2017-08-12
* cd2e72e09  mpv: update 0.26.0_1 bottle. [BrewTestBot] 2017-08-07
* 778edcaf6  mpv: revision for jpeg [ilovezfs] 2017-08-06
* 88924ce1e  mpv: update 0.26.0 bottle. [BrewTestBot] 2017-07-18
* 95e4094ac  mpv 0.26.0 [Zhiming Wang] 2017-07-18
* 14d8f964a  pv: update 1.6.6 bottle. [BrewTestBot] 2017-07-04
* c8a378844  pv 1.6.6 [ilovezfs] 2017-07-04
* 59f4e505c  mpv: update 0.25.0 bottle. [BrewTestBot] 2017-04-23
* 63f265e3b  mpv 0.25.0 [Zhiming Wang] 2017-04-22
* 1b718ab8c  mpv: update 0.24.0_1 bottle. [BrewTestBot] 2017-04-13

其实区区几万条数据消耗不了多少系统资源,例如把输出重定向到 /dev/null

⋊> time git hist > /dev/null
        0.76 real         0.53 user         0.04 sys

⋊> time git hist | grep mpv > /dev/null
        0.84 real         0.58 user         0.06 sys

根本不需要多少时间,真正耗时的是在显示/渲染到屏幕。

GUI 客户端我用的是 Fork.app,列出整个历史,拖滚动条,一点问题都没有,GUI 应该是很容易做到,屏幕之外的内容就只放在内存里,不进行熏染。

我不知道 magit 是怎么设计(我非 magit 用户),或者是这 emacs 本身的问题,无法避免对屏幕之外的内容进行渲染(加亮/着色…等等)。所以这就需要限制输出的 commit 数量啊,上边的 issue 链接已经提到,几年前就有的 feature,为什么不用呢

1 个赞

列出整个历史还是有用的,比如 magit 的卡顿问题就是这么发现的…… :laughing:

话说按网上指引跑去改 homebrew,当时正琢磨 magit 呢。OK,要搜索某 commit ID 是吧?magit buffer 本质还是文本,直接 ctrl-s !咦,没找到?拉到底部一看,哦,默认只显示几百条历史。提示 Type + 显示更多,那就多点几下吧。点着点着就发现问题了:当 magit 加载条数达到 4000 条,再继续点就有明显的卡顿。3 秒钟左右的那种卡顿。经过几次重启 emacs 终于确认:嗯,就是卡顿,不是我手抖误操作神马的。最终我也没耐心等 magit 加载到想要找的 commit ID,于是跑去换用 tig 了。哈,一搜就找到了。这就是当时的经过。

刚才用 git log 试了一下,确实读取历史不需要多少时间,估计大部分耗时是渲染到屏幕。可能 magit 点击后半天界面不动,给我造成一种读取很耗时的错觉吧,哈哈。


平时 git 使用场景比较简单,没怎么研究过 git 以及 GUI 客户端。刚才尝试了下你说的 Fork.app,确实读取和滚动都不卡。复制了一个 commit ID 搜索,也能搜得到。后来又尝试了一个 commit ID,这次就没那么幸运了,翻来覆去搜不到。拉到最低,和 tig 反复对照,终于确认:Fork.app 最多只能显示 25000 条历史!这就是为啥死活找不到的原因了,设置里也没找到最大历史选项,说是“列出整个历史”是不准确的。至于它为何这么限定就不清楚了。

顺便说下资源占用,虽然平时不怎么关心这个,但是 tig 的 6.8 MB 内存占用还是震惊了我 :scream: 作为对比,Fork.app 则是 189 MB。真是没有对比就没有伤害……感觉更爱 tig 了呢。

你说的限制输出的 commit 数量,个人感觉好像就是“默认显示几百条”那个,还是有别的选项呢?

从你的描述看,magit 已经启用了限制 commit 数量这个特性,不过它没做到像分页那样,始终维持限制的数量,而是不断累加,最终还是爆掉。看起来作者已经尽力了,但是依然没有完美方案。

Fork.app 这个 25k 限制还真没注意到,特意去 google 查了,没人抱怨问题,难道都不在乎?我用它主要是提交和查看最近的 commit。比较久远的记录一般是到终端 grep,然后 checkout 一个分支出来。

偶尔也用 tig,但是快捷键太多记不住,我这 60% 的键盘有很多键比如 <HOME>/<END> 都需要 fn 组合。所以平时还是 Fork.app + git 命令行,主要是命令行,各种魔法也只有命令行能做到,偷懒的是用客户端。

Fork.app 作为客户端还是不错的,可以比较方便列出单个文件的历史,diff 上下文数量调整也很容易(有时候上下文太少,只看到差异,不知道到底是属于那个函数/分支)。

确实一般 repo 很难达到 25K 的限制,我这个需求算是比较少见吧,哈哈。不过要是能加载全部还是极好的。

tig 虽然早就安装,但也是最近才算真正用起来,感觉看 log 看 diff 还是很好的。譬如想看之前某几次提交解决问题的思路,直接 /commit id OR commit message 搜索,n/N 跳转,回车。就能看 diff 了。diff 上下文数量调整我刚看了下,快捷键是 [/]

如果忘记快捷键的话,按下 h 调出 help 看看。tig 还有个外部命令模式,:!git checkout *** 类似这样的,理论上应该能处理所有可能的情况,不过我基本没用过。最新的进展是在 VimR 的内置 terminal 里打开 tig,这样有时候系统终端没开也能处理。

目前还没有细读过 tig 手册,懒呀……过两天计划大略扫一遍,看看有没有遗漏什么好东东