如何记录使用旧路径重命名/移动的文件的整个git历史记录?

问题描述 投票:1回答:1

如果文件A被编辑了一次或多次,则重命名/移动到B并编辑一次或多次B,使用其新名称/路径发出以下git命令...

git log --follow -- B

......展示了它的整个历史。

但是,当我正在查看同一个项目的旧(已发布/维护)分支时,该文件仍然名为A,并且我想在master中对其进行后退更改,我可能会认为在master上发布以下内容。 。

git log --follow -- A

......会告诉我所有的变化。但事实并非如此。日志中显示的最新提交是对应于从AB的重命名的更改。未显示对B所做的更改。

--follow只跟随从较新的名称“向后”重命名为旧名称,而不是“转发”。

此时,我必须首先确定显示的最新提交是重命名,找到更新的名称,然后再次使用新名称发出git log --follow(如果文件移动了几次,可能会重复几次,因为保持释放。

如何在不必多次手动发布git log --follow的情况下找到整个历史记录?

git version-control
1个回答
2
投票

不幸的是,git log本身严格地向后工作,就像Git一样。 Git确实无法正常工作,因为Git存储的内容是向后的:每个提交都会记住其父提交的哈希ID,但由于所有提交在创建时都会及时冻结,因此无法记住其子项的哈希ID,后来创建。

什么git log(和它的大姐姐/主力管道命令git rev-list)可以做的一次反向遍历,找出哪些提交在其他提交之前,然后反向打印。 git log --reverse命令执行此操作。但是,重命名检测仅在向后(对于Git向前)遍历期间发生,并且不能楔入后面的向前(向Git向后)打印输出。

它不是内置于Git中,但您可以使用git rev-list进行反转,保存结果,然后在每个提交对上运行git diff --name-status时进行自己的前进行走,寻找重命名操作。请注意,这仍然有点棘手,因为现在分支真正分支和合并真正合并Git的内部向后遍历,合并分支,而分支合并。 :-)也就是说,假设我们有:

  tag:abc
     |
     v
...--o--o--*--o--o--o   <-- tip1
         \
          o--*--o----o   <-- tip2

你想从标签abc开始,它位于左侧,并且“向前工作”。 Git想要从tip1开始,沿着顶线向右移动,或者tip2,向右边的提交开始。

标记为*的提交将您的文件A重命名为一些新名称。在顶部的一个新名称是B,在底部的一个名称是C

如果你在tip2开始Git,你必须寻找C。 Git注意到在*重命名,从那时起,向左,寻找A。如果你在tip1开始Git,你必须以同样的方式寻找B

如果你通过从tip1倒退到标记abc之前的某个点来建立一个“前锋”列表,你会没事的:因为没有包含导致tip2的提交,所以在该列表中没有分支。但是后来假设有人向tip1添加了一个合并,并且另一个提交:

  tag:abc
     |
     v
...--o--o--*--o--o--o--M--o   <-- tip1
         \            /
          o--*--o----o   <-- tip2

现在从abctip1的路径包括重命名。如果你从tip1开始,你必须给git log --follow这个合并的人选择保留的名称,无论是B还是C。因为git log -- Bgit log -- C(无论哪个是正确的名称)进行历史简化,Git只会走M后面两条腿中的一条 - 无论是顶行还是底行,具体取决于哪一个具有匹配文件 - 以及当你向前工作时从abc你必须选择两个分支中的一个来工作,或做一些奇特的事情,以便你知道检查A-become-B沿着顶部,同时还检查A-become-C沿底部。 (Git没有做任何花哨的事情。)

© www.soinside.com 2019 - 2024. All rights reserved.