如何在git repo中获取文件的“父版本”?

时间:2019-09-06 00:26:58

标签: git branch branching-and-merging

如何获得我在本地分支中更改过的文件的“原始”内容-很多次-并且多次与master合并。请注意,我并不是在寻找文件的主版本,本质上是要该文件减去本地分支中最后一次从另一个分支更改的时间点中的所有更改:

master   a---b---c---d
          \       \
branch1    e---f---M---g

因此,当我在branch1工作时,我需要一种快速的方法来获取c的内容。 d对我没有用(它将在我正在创建的健全性检查中创建可怕的假阳性,并破坏我的预提交钩子。)

由于上次合并到当前分支可能来自主分支以外的其他事实,这使情况变得很复杂-父分支和我合并成branch1的最后分支可能是任何东西。

1 个答案:

答案 0 :(得分:2)

您的分支标签在错误的一面,(我认为)这会使图形产生误导。请记住,Git总是从 end 开始并向 backwards 起作用,所以:

a---b---c---d   <-- master
 \       \
  e---f---M---g   <-- branch1

这强调指出,要查找branch1上的提交,Git将从g开始,然后查看M,然后同时查看c和{{1 }},fbe。提交aabc都在d上;提交masteraebfcM(但不是{{1} })都放在g上。

您想要查找d中出现的某个文件的版本,因此您只需要从branch1的尖端开始进行反向工作,直到找到一个提交也可以通过从c向后工作。该提交是两个分支技巧的合并基础。 (在某些复杂的情况下,它可能是其中之一;这里的图片更加模糊,并且不清楚您想要哪个提交。请参见下文。)

命令branch1,带有可选的master选项,用于查找一个或全部合并基本提交。将其与git merge-base配合使用可以使您放心,只有一个这样的合并库,因此您发现了提交--all

--all

这会发出每个合并基础提交的哈希ID,在这种情况下,它只是提交c。如果只有一个哈希ID:

git merge-base --all master branch1

将允许您在该提交中查看该文件的内容。

当有多个合并基础时

进入这种情况的原因是,两个分支都可以从两个分支提交两个或多个提交,而这两个分支的“距离相同”。最简单的方法是纵横交错:

c

在这里,提交git show <hash>:<path> 是通过执行...--A--B---E--G--H <-- master \ / X / \ ...--C--D---F--I--J <-- branch1 来完成的,其中E代表提交git checkout master; git merge branch1,而master代表提交B。大约在同一时间(可能在此之后,也许在一个尚不存在branch1的单独的Git存储库中),通过执​​行D或类似操作(例如,{{ 1}}放在单独的Git存储库中。

现在,提交EF是分支git checkout branch1; git merge <hash-of-B>git merge master两个合并基础。正在运行:

E

将显示两个哈希ID。哪个提交包含您要检查的文件?您将需要一些其他约束来解决这个问题。一个可能的约束条件(只要进行合并的人受到约束即可使用),它是使用 first parent 链接:F的第一父级是master,而branch1的第一个父级是git merge-base --all master branch1 。因此,第二父级可能是您想要的。但是,如果某人一直在使用E进行合并,或者做了一些其他棘手的事情,则在某些情况下,他们可能已经交换了第一和第二个父母,这样您可能会得到错误的提交。最好只检查两者。

特殊情况:B

如果您不介意查看所有路径,或愿意为F指定路径名,则可以让D为您找到合并基础。只要只有一个合并基础(这是通常的情况),这便使您的工作更加轻松。 1 git pull的工作方式是接管三个点的{{1} }语法:

git diff

在这种情况下,git diff执行合并基础搜索,以便找到提交git diff,然后将提交git diff与提交master...branch1({{ 1}},即git diff master...branch1 对中的第二个名称。 请注意,此处需要三个点:比较提交git diffc时,两个点c给出了完全不同的g。 / p>

添加branch1可将差异限制为您感兴趣的文件。 Git将仅向您显示一个文件。当然,这显示了文件的 diff master...branch1向您显示文件在提交master..branch1中出现的文件。


1 如果存在多个合并基数,diff会随机选择一个或多或少的一个基数,否则会放空并显示合并差异 ,这非常令人困惑。这些都不是好的行为。我相信d应该在这里产生一个错误,然后停止,而不要执行任何一个操作。