git结帐:"theirs"和"ours"的详细含义

git checkout: detailed meaning of "theirs" and "ours"

git checkout documentation 说:

--ours --theirs When checking out paths from the index, check out stage #2 (ours) or #3 (theirs) for unmerged paths.

"stage #2" 和 "stage #3" 在合并、变基和 cherry-pick 过程中的含义是什么?有没有办法在 运行 命令之前查询这些 "stages" 以确保它将检索正确的版本?

这些记录在 the gitrevisions documentation:

中(虽然我认为不是很清楚)

A colon, optionally followed by a stage number (0 to 3) and a colon, followed by a path, names a blob object in the index at the given path. A missing stage number (and the colon that follows it) names a stage 0 entry. During a merge, stage 1 is the common ancestor, stage 2 is the target branch’s version (typically the current branch), and stage 3 is the version from the branch which is being merged.

对于这些,您需要添加有关 git rebasegit cherry-pick 工作原理的知识。

正常的 cherry picking 是明确定义的:“ours”是 HEAD 版本,即你曾经(现在仍然)所在的分支,而“他们的”是你正在积极挑选的提交.当您挑选单个提交时,一切都非常明显:阶段 #1 是所谓的共同祖先提交,1 阶段 #2 是当前分支顶端的版本,第 3 阶段是您正在挑选的版本。

如果您挑选一系列提交,这仍然是正确的,它只是迭代地正确。例如,假设您正在挑选三个提交。 Git 一次只做三个。在第一个 cherry-pick 期间,stage #2 是分支的顶端,stage #3 是第一个提交被 cherry-pick 的版本。一旦提交 cherry-pick 完成,git 进行新的提交,推进你的分支的尖端。然后,在第二次 cherry-pick 期间,stage #2 是分支的尖端,这是您第一次 cherry-pick 所做的提交,stage #3 是来自第二次提交的版本。这对最终提交再次重复。每一次,第 3 阶段都是“他们的”版本。

然而,Rebase 有点棘手。在内部,它首先让您进入一个新的匿名分支(“分离的 HEAD”)。然后它运行 git cherry-pick 从您的原始分支中选择每个提交。这意味着“我们的”是分离的 HEAD 版本,而“他们的”是您原始分支的版本。就像 cherry-pick 一样,这会迭代地重复每个要选择的提交(字面意思是在交互式变基的情况下,您可以在其中编辑 pick 行)。一旦 rebase 完成,git 简单地打乱分支标签,这样你刚刚创建的新匿名分支就是你的代码。

简而言之,您可以将 rebase 视为“反转 ours/theirs 设置”——但这有点夸张。更准确地说,阶段 2 是新的、融合的代码,阶段 3 是旧代码。


第 1 阶段 根据定义是合并基础。对于真正的合并,这是最好的共同祖先提交,但是 cherry-pick 将其强制为被 cherry-picked 的提交的父级。 (还原以类似的方式工作,除了被“复制”的提交是父提交,而“合并基础”是被还原的提交。)

Git documentation for merge(以及其他一些地方)解释了索引文件最多记录三个版本或阶段:

For conflicting paths, the index file records up to three versions: stage 1 stores the version from the common ancestor, stage 2 from HEAD, and stage 3 from MERGE_HEAD (you can inspect the stages with git ls-files -u). The working tree files contain the result of the "merge" program; i.e. 3-way merge results with familiar conflict markers <<< === >>>.

这是一个图表,显示了典型 Git 合并中的三个阶段:

Common Ancestor -> C1  --- C2         <- MERGE_HEAD (Stage 3)
(Stage 1)             \
                        --- C3 --- C4 <- HEAD (Stage 2)

这假设 HEADC4 的分支正在合并回以 C2 结尾的分支。

如文档所述,您实际上可以通过键入以下内容查看阶段:

git ls-files -u