【问题标题】:Finding SHA1 in git for file version containing a given line containing a given string在 git 中查找包含给定字符串的给定行的文件版本的 SHA1
【发布时间】:2013-12-09 19:20:28
【问题描述】:

我正在尝试跟踪使用 valgrind 的测试人员向我报告的内存泄漏,它报告内存泄漏并回溯分配的时间。不幸的是,他们报告的文件自测试以来发生了重大变化。我试图找出他们测试的版本。为此,我想在 linux / bash 系统上使用 git 查找文件在给定行号(来自 valgrind 报告)处有给定函数调用的时间。

换句话说,valgrind 报告在回溯中有这样的内容:

   function1 (file1.c:line1)
   function2 (file2.c:line2)

假设行号是正确的(即:函数没有包含在宏或可能会混淆 valgrind 的内联中),我正在寻找 file2.c 的版本,其中 line2 包含字符串“function1”。

我的尝试是首先使用“git log --follow file2.c | grep ^commit”。作为快速测试,我收集了该输出:

commit f267c7671a8af8a4c97b5c4938bab3a7099d50ea
commit 3f45349afc39b5c3ed6a6517ee4a2008d21f9047
commit 09e489d88ecc9e0adee326d68f18834753ddbcdd
commit 14ae0ab236bea453a9e2af81b507fe8243813b34
commit e1c1b28671a5c957c77ce54a45ce7e1694a64592
commit 7a45c4761c7f0d2263934d254c50052941d0c9e7
commit db9e61c3253a8c6966ecf334ff9c394e17966188
...about a hundred SHA1 labels...

进入编辑器,搜索/替换每一行:

show f267c7671a8af8a4c97b5c4938bab3a7099d50ea:file2 | sed -n(line2)p
show 3f45349afc39b5c3ed6a6517ee4a2008d21f9047:file2 | sed -n(line2)p
show 09e489d88ecc9e0adee326d68f18834753ddbcdd:file2 | sed -n(line2)p
show 14ae0ab236bea453a9e2af81b507fe8243813b34:file2 | sed -n(line2)p
show e1c1b28671a5c957c77ce54a45ce7e1694a64592:file2 | sed -n(line2)p
show 7a45c4761c7f0d2263934d254c50052941d0c9e7:file2 | sed -n(line2)p
show db9e61c3253a8c6966ecf334ff9c394e17966188:file2 | sed -n(line2)p
...

但我没有找到匹配项。我做了更多检查,确实找到了一个匹配的“非一”行号(我发现 valgrind 行号在我们的系统上通常是准确的,但也许它可能是非一的)。

所以我的第一个问题是,“git log”真的会显示该文件的所有版本吗?假设没有人在存储库中重写历史。我想知道我是否错过了使用这种方法的版本。

我的第二个问题是,有没有一种自动化的好方法?理想情况下,我正在考虑使用文件名和行范围(lineA 到 lineC)并报告每个版本的脚本:

(shaX) lineA : contentsXA
(shaX) lineB : contentsXB
(shaX) lineC : contentsXC
(shaY) lineA : contentsYA
(shaY) lineB : contentsYB
(shaY) lineC : contentsYC
(shaZ) lineA : contentsZA
(shaZ) lineB : contenstZB
(shaZ) lineC : contentsZC

我可以为我正在寻找的字符串 grep 的输出,并且我会看到包含该字符串的版本的 SHA。还是有更好的方法来解决这个问题?

【问题讨论】:

    标签: git


    【解决方案1】:

    使用 git 存储库并从 sha1_file.c 中选择 check_sha1_signature 作为具体示例,您可以看到定义该函数的行

    git log --format=format:%H -- sha1_file.c | \
      xargs -I SHA1 env GIT_PAGER=cat \
      git grep --word-regexp --line-num check_sha1_signature SHA1 -- sha1_file.c
    

    因为源文件的名称在git grep 命令中是硬编码的,所以这不会跟随重命名。

    【讨论】:

    • 我没用过“--format=format:%H”,这很有帮助。不幸的是,git 报告:error: unknown open 'line-num' 是来自较新版本的 git 吗?我在 Suse linux 上使用 1.7.3.4。
    • 我在我的 git 版本中看到它是“-n”而不是“--line-num”。打印出所有匹配的行,并显示行号可能比我尝试做的更好(仅在匹配时打印它们)。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-05-13
    • 2015-12-27
    • 2011-09-03
    • 2020-07-04
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    相关资源
    最近更新 更多