识别与先前 git 提交的位置对应的当前文件/行

Identify the current file / line that corresponds to a position from a previous git commit

假设我在 git 存储库中有一个分支。分支的历史可能看起来像这样:

A <- [...] <- Z

现在假设我有一个位置 P(例如 src/index.js:122),它引用 A 提交中的一行。

在提交 AZ 之间,提交可能会重构 hunk 引用的文件,稍微修改行(例如,向函数签名添加新参数),甚至移动文件本身到存储库树中的其他地方。我想确定反映该行在提交 Z.

中位置的位置 P'

是否有 git 命令可以帮助我确定这个新位置?

我会从 git log -S 开始。将这一行作为 -S 的参数。如果行没有改变,这应该能找到它。

来自“git 日志”手册页:

   -S<string>
       Look for differences that change the number of occurrences of the
       specified string (i.e. addition/deletion) in a file. Intended for
       the scripter’s use.

       It is useful when you’re looking for an exact block of code (like a
       struct), and want to know the history of that block since it first
       came into being: use the feature iteratively to feed the
       interesting block in the preimage back into -S, and keep going
       until you get the very first version of the block.

       Binary files are searched as well.

我建议的最简单的答案是:

检查

的输出
git diff A Z -- src/index.js

您可以手动检查它,或使用脚本处理输出,以发现第 122 行如何在 AZ 之间移动,从而了解差异。


如果所述线路的演变过于复杂,您可能需要检查:

git log A..Z -p -- src/index.js
# or :
git log A..Z --reverse -p -- src/index.js

您将看到所述文件的所有单独演化,同样,您可以计算初始行 122 如何演化到 Z

我使用 git blame 解决了我的问题,并按照 torek 的建议采取了相反的方法。这适用于我的用例,因为我试图在 git 存储库中的文件旁边显示元数据,所以我知道我想找到原始位置的行集。假设 AZ 的祖先提交,我们可以执行以下操作:

git blame -fns Z -- api/v3/views.py

这将为文件中的每一行提供提交哈希值、原始树路径和行号,例如

481daae85d6 api/v3/files/views.py   2   4) from rest_framework.response import Response
^           ^                       ^   ^
                                  

让我们将位置表示为 <hash>:<path>@<line>。这向我们表明 Z:api/v3/views.py@4 最初显示为 481daae85d6:api/v3/files/views.py:2

最后一步:我们在 A 中确定的位置 P 可能不是包含该行的原始提交,这将导致漏报。在导入这些元注解的时候,我们可以再做一次git blame for that specific line in the commit to determine the original commit:

git blame -fns -L <line>,<line> A -- <path>

然后我们可以将注释存储在返回的提交哈希上,而不是 A

这里的悬而未决的问题是这是否足够:即使一行被稍微修改,代码注释可能仍然相关,而这种方法将导致这些注释是“丢失”。