我希望逐步查看文件中某个部分的提交历史记录。特别是,我感兴趣的有两行。我想看看几个月前这两行的变化,甚至是文件的来源。有没有快速的方法来使用命令行获取更改?我知道有git的GUI可以让你这样做,但我不愿意。如果我要这样做,我宁愿使用vim或sublime。
理想情况下,我想要提交哈希,日期,名称和更改。
34hi5u3k 4/13/2013 Someone Name (Line 408) $text = 'Something';
72wbedfj 4/05/2013 Someone Else (Line 408) $text = 'Something else';
827y3hrj 3/29/2013 Someone Nice (Line 408) $text = 'This one time...';
答案 0 :(得分:1)
显示$ filename中对第95-105行的所有更改:
git log -L 95,105:$filename
在$ filename中显示从regex开始的10行的所有更改:
git log -L /<regex>/,+10:$filename
产生的输出不是您提到的理想格式,但它确实显示了整个历史记录的指定部分的所有差异。
答案 1 :(得分:0)
是否可以使用命令行快速获取更改?
在Git 2.28(2020年第三季度)中,考虑到“ git log -L...
”现在利用了“此提交触及了哪些路径?”的优势,它甚至会更快。信息存储在提交图系统中。
请参见commit f32dde8的Derrick Stolee (derrickstolee
)(2020年5月11日)。
请参见commit 002933f之前的commit 3cb9d2b,commit 48da94b,commit d554672,SZEDER Gábor (szeder
)(2020年5月11日)。
(由Junio C Hamano -- gitster
--在commit c3a0282中合并,2020年6月9日)
line-log
:更具响应性的增量'git log -L'签名人:SZEDERGábor
签名人:Derrick Stolee当前的行级日志实现在
prepare_revision_walk()
中执行预处理步骤,在此期间,line_log_filter()
函数进行过滤并重写历史记录,以仅保留修改给定行范围的提交。此预处理会影响响应性和正确性:
在此预处理步骤中,Git不产生任何输出。
检查提交是否修改了给定的行范围会比较昂贵,因此,根据给定修订范围的大小,这种预处理可能会导致在显示第一个提交之前出现明显的延迟。限制显示的提交数(例如'
git log -3 -L...
')不会限制预处理期间的工作量,因为该限制在历史记录遍历期间会应用。
las,到那时,这个昂贵的预处理步骤已经遍历整个修订范围,以查找所有修改修订范围的提交,即使只需要显示其中的少数几个。它重写了父母,无法将其关闭。
没有用户明确请求父级重写的情况,显示的任何父级对象ID都应该是直接父级的ID,就像在没有父级重写的情况下遍历pathspec限制的历史记录一样。但是,在该预处理步骤重写了历史记录之后,随后的“常规”历史记录遍历(即循环中的
get_revision()
)仅会看到修改给定行范围的提交。
因此,它只能显示修改给定行范围的最后一个祖先的对象ID(可能恰好是直接父对象,但很多时候不是)。此修补程序通过将行级日志过滤集成到常规修订步行机制中,解决了正确性以及至少在通常情况下的响应性问题:
使
process_ranges_arbitrary_commit()
(“line-log.c
”中的静态函数)通过删除static关键字并添加“line_log_
”来决定提交是否修改了给定的行范围前缀,因此可以从修订步行机械的其他部分调用它。如果用户未明确要求重写父项(我认为这是最常见的情况):
在常规历史记录遍历期间(即从
get_commit_action()
调用此公开函数,以忽略任何未修改给定行范围的提交。
请注意,尽管此检查相对昂贵,但必须在其他便宜得多的条件之前执行,因为即使在最终提交将被其他条件忽略的情况下,也必须调整跟踪的行范围。在
line_log_filter()
中跳过prepare_revision_walk()
调用,即昂贵的预处理步骤,因为由于上述几点,修订步行机制现在能够过滤出未修改提交的提交。遍历历史记录时指定行范围。
这样,常规历史记录遍历就可以看到未修改的历史记录,因此可以打印所列提交的直接父级的对象ID。
取消的预处理步骤可以大大减少显示第一次提交之前的延迟,请参见下面的数字。但是,如果用户确实通过'
--parents
'或类似选项明确要求父代重写,则暂时坚持使用当前的实现,即在预处理中执行昂贵的过滤和历史记录重写就像我们之前一样,保持初始延迟。我尝试将行级日志过滤与父级重写集成到常规的历史记录遍历中,但是,不幸的是,一些微妙之处遭到了抵制... :)也许有一天我们会弄清楚如何做到这一点,但至少到那时简单而通用的(即无需父代重写)'
git log -L:func:file
'命令可以从减少的延迟中受益。当在较大修订版本范围的尖端附近修改行范围时,减少的延迟最明显:
# no parent rewriting requested, no commit-graph present $ time git --no-pager log -L:read_alternate_refs:sha1-file.c -1 v2.23.0 Before: real 0m9.570s user 0m9.494s sys 0m0.076s After: real 0m0.718s user 0m0.674s sys 0m0.044s
剩余延迟的很大一部分花费在读取和解析
limit_list()
中的提交对象上。借助提交图,我们可以消除大部分读取和解析开销,因此,这是与上述相同命令的计时结果,但是这次使用提交图:
Before: real 0m8.874s user 0m8.816s sys 0m0.057s After: real 0m0.107s user 0m0.091s sys 0m0.013s
下一个补丁将进一步减少剩余的延迟。
要清楚:此补丁实际上并没有优化行级日志,而只是将大部分工作从预处理步骤移至历史遍历,因此修改行范围的提交一经显示即可被处理,并且遍历可以在显示给定数量的提交后终止。
因此,列出行范围的完整历史记录(可能一直到根提交)将花费与之前相同的时间(但至少用户可能会更早开始阅读输出)。
此外,如果最近修改行范围的提交与起始修订版本相距甚远,那么该初始延迟仍然会很大。Derrick Stolee的其他测试:在Linux内核存储库中,在约915,000次提交中,
MAINTAINERS
文件已被更改了约3500次。
除了编辑频率外,文件本身也很大(〜18,700行)。
这意味着计算的很大一部分是通过计算文件的patch-diff
来进行的。该补丁大大提高了输出第一个结果所需的实时性:Command: git log -L 100,200:MAINTAINERS -n 1 >/dev/null Before: 3.88 s After: 0.71 s
如果我们在命令中添加“
-n 1
”,那么端到端的处理时间将没有变化。这是因为该命令仍然需要遍历整个提交历史记录,这否定了此补丁程序的要点。这是预期的。作为以后的参考注释,旧代码中的约4.3秒花费了约2.6秒的时间来计算补丁差异,而其余时间则是花在遍历提交和计算差异上,而这些差异在每次提交时都会改变路径。
更改路径的布隆过滤器可以改善端到端的计算时间(即命令中没有“-n 1
”)。