Git合并基类似于单个文件

Git合并基类似于单个文件,git,merge,git-merge,git-commit,Git,Merge,Git Merge,Git Commit,是否有任何命令可以在两个分支中查找文件的共同祖先 假设有一个文件在两个分支中被独立修改。我想找到两个分支共用的文件的最后版本。我相信这可以归结为在两个分支中找到文件的单亲提交 但是,merge base只允许查找提交的父提交,而不允许查找文件。我试图在各自的分支中指定修改文件的最后两次提交,但我得到的父提交不在任何分支中该文件的更改历史记录中,这可能是因为提交通常包含对多个文件的更改 是否有任何命令可以在两个分支中查找文件的共同祖先 不,或者是,或者可能:这取决于你的意思 假设有一个文件在两个分

是否有任何命令可以在两个分支中查找文件的共同祖先

假设有一个文件在两个分支中被独立修改。我想找到两个分支共用的文件的最后版本。我相信这可以归结为在两个分支中找到文件的单亲提交


但是,merge base只允许查找提交的父提交,而不允许查找文件。我试图在各自的分支中指定修改文件的最后两次提交,但我得到的父提交不在任何分支中该文件的更改历史记录中,这可能是因为提交通常包含对多个文件的更改

是否有任何命令可以在两个分支中查找文件的共同祖先

不,或者是,或者可能:这取决于你的意思

假设有一个文件在两个分支中被独立修改。我想找到两个分支共用的文件的最后版本。我相信这可以归结为在两个分支中找到文件的单亲提交

文件没有父提交。只有提交才有父提交

更糟糕的是,每次提交都会存储每个文件(即提交时作为临时区域一部分的每个文件)。因此,在某种意义上,这要么是每次提交,要么是常规的普通合并基。很明显这不是你的意思,让我们看看我们还能说些什么

让我们做一个思维实验。假设您有两个分支提示
br1
br2
,它们最终有一个共同的祖先提交:

       o--o--o--Y   <-- br1
      /
...--X
      \
       o--o--o--Z   <-- br2
假设路径
p
在提交
R
S
中的内容相同,但在
p
T
中的内容不同。两者都是从
X
Y
的相同图形距离。只要您只关心路径
p
,这可能无关紧要,但它确实表明不一定存在唯一的提交


在我开始讨论一些您想要使用的命令之前,这是一大堆的废话,以便解决您试图解决的问题

使您更接近解决方案的命令(甚至可能一直如此,这取决于您想要的是什么,尽管您可能需要使用其他命令,有些甚至不是git命令)是。这可以找到修改了特定路径的提交(与这些提交的父级相比;请注意,合并通常必须特别处理,因为它们有多个父级提交)。如果您确实使用一个或多个路径来限制git rev list所列的修订,请注意,它将执行“历史简化”,以便从其输出中省略一些提交。根据您希望DAG级分支(如更复杂的
X
-to-
Y
链中的分支)的处理方式,这可能是您想要的

基本上,
git rev list X..Y--path
将发现可从
Y
访问的提交,不包括可从
X
访问的、修改
path
的提交,其中“modify”表示“与父级的差异显示对该路径的更改”。(关于如何处理合并,请参阅文档。)提交的列出顺序取决于您选择的排序(有或没有拓扑约束;请参阅“提交顺序”部分)

如果用
X..Z
重复此操作,您可以找到修改路径的提交

这两个
git rev list
s实际上是将整个修订链从
X
移动到两个分支提示,但由于它们允许您将其输出限制为“修改某些路径的提交”,因此它们可以优化我在思考实验中概述的过程

您可能希望在此处包括提交
X
。默认情况下,
rev list
不会:您可以提前开始一次提交(在
X
的父级),但如果
X
本身是一次合并,则可能会失败;或者您可以使用
--boundary
,它指示
rev list
包含commit
X
的SHA-1(前缀为
-

要确定在两次不同的提交中存储在特定路径下的内容是否相同,显然,如果在此处使用相同的提交ID两次,则内容是相同的,但仍然有效,您可以比较存储的blob的SHA-1 ID:

path=dir/file
...
rev_a=...   # something from git rev-list, for instance
rev_b=...
if [ $(git rev-parse ${rev_a}:${path}) = $(git rev-parse ${rev_b}:${path} ]; then
    ... the contents match ...
else
    ... the contents differ (at least slightly) ...
fi

这些都不会检测到重命名;为此,必须使用全面的
git diff
(启用重命名检测)。

“merge base只允许查找两次提交的父提交”。。。您可以在合并基命令中指定2个以上的提交。足够公平,更正,谢谢。感谢您的全面回复!为了回答您的问题,我正在进行合并,git在一个文件中显示了冲突,因为该文件的某些部分在两个分支中都被修改了。然而,git没有将这些部分显示为修改过的部分,因为这些分支之间存在合并基提交。因此,我想找到commit X(其中两个分支中的文件都相同),以便查看在X和这两个分支中的最新提交之间修改该文件的所有提交。然后手动重新应用这些更改以解决冲突。在这种情况下,您可能需要查看设置
merge.conflictstyle=diff3
。看到了还谢谢你的提示,非常有用。直到现在我才知道diff3:)
         R
        / \
       P   T--o--Y   <-- br1
      / \ /
...--X   S
path=dir/file
...
rev_a=...   # something from git rev-list, for instance
rev_b=...
if [ $(git rev-parse ${rev_a}:${path}) = $(git rev-parse ${rev_b}:${path} ]; then
    ... the contents match ...
else
    ... the contents differ (at least slightly) ...
fi