如何在不将文件添加到索引的情况下标记文件以进行解析?
亩。 (换句话说,这个问题预设了一些不存在的东西。)
合并冲突由索引/暂存区域中的文件的多个副本表示。1 也就是说,不是只有一个文件被暂存——这个文件要么与当前提交匹配,Git 只是关闭它,或者不这样做,Git 打印staged for commit
它——有三个文件暂存用于提交。Git实际上不能提交一个文件的三个副本并且不会让你提交,所以你必须解决这种情况......但解决的行为包括擦除这三个文件并将一个文件放在适当的位置。
您放置的那个文件将添加到索引中。它要么匹配当前提交的文件,Git 什么都不说,要么不匹配,Git 说staged for commit
. 无论哪种方式,该文件都存在。
如果您想要让 Git 的索引包含当前提交中的副本作为文件的一个副本,您可以这样做。但这意味着您已将该文件版本添加 为暂存提交的版本。
1这在技术上不太正确:合并冲突由索引中的任何非零阶段条目表示。但是,当您确实遇到合并冲突时,通常会得到一个或多个文件,每个文件都有三个条目。其他情况发生在添加/添加、修改/删除、重命名/重命名和重命名/删除冲突。这些也留下了代表“相同”文件的多个条目。
例子
让我们来说明这一点。首先,让我们创建一个小型存储库并设置冲突:
$ mkdir test-resolve
$ cd test-resolve/
$ git init
Initialized empty Git repository in .../.git/
$ echo test conflict resolution > README
$ echo fee file fo fum > file
$ git add . && git commit -q -m initial
$ git checkout -b branch
Switched to a new branch 'branch'
$ echo foo >> file && git add file && git commit -q -m foo
$ git checkout -q master
$ echo bar >> file && git add file && git commit -q -m bar
$ git log --all --decorate --oneline --graph
* 8921373 (HEAD -> master) bar
| * 679121a (branch) foo
|/
* a7a3f27 initial
现在让我们看看 Git 的暂存区/索引中有什么:
$ git ls-files --stage
100644 7eafc9636afdf576278e921d7430598dd8754bdd 0 README
100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0 file
这些是 Git 暂存区中的文件,以及它们的暂存编号。阶段号为零表示没有合并冲突;这样的文件不能有任何其他条目。请注意,这两个文件都已准备好提交!他们只是匹配HEAD
提交版本,所以git status
没有说 staged for commit
。
现在我们将运行合并:
$ git merge branch
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
$ git ls-files --stage
100644 7eafc9636afdf576278e921d7430598dd8754bdd 0 README
100644 8fee5c26846ed992dc2dd912e224a2001a2b6820 1 file
100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 2 file
100644 af8330063fa2da41a81f8a789929fd87692adb2f 3 file
瞧!这是我们名为file
. 他们有非零分期号码;这些代表文件的合并基础副本(阶段 1)、ours
副本(阶段 2)和theirs
副本(阶段 3)。如果我们愿意,我们可以查看文件:git show :1:file
,git show :2:file
,等等:
$ git show :3:file
fee file fo fum
foo
“他们的”文件,从 branch 的尖端开始branch
,是第 2 行读取的文件foo
(我们的读取bar
)。
现在,文件的工作树副本file
包含 Git 解决冲突的尝试。如果我们看到这一点,我们可以看到它并不顺利。请注意,我已merge.conflictStyle
配置为diff3
使我也获得文本的合并基本版本:
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
我们现在回到你的问题,我将再次引用
如何标记文件以进行解析
选择三个阶段中存在的三个副本之一,或者存在于HEAD
提交或任何其他提交中的副本,然后选择该副本作为进入 Git 索引中插槽零的副本。擦除其他两个插槽。该文件现在已准备好提交。
不将其添加到索引中?
它已经在索引中。您要减去两个或三个副本,可能会留下第三个并将其移至零位;或者您减去所有三个副本并在索引中添加一个新副本。
您可以使用git add
将工作树文件复制到索引中,或者您可以选择一些现有的 Git 化副本并将其移入。假设您想HEAD
将文件的副本粘贴到索引中,而不接触工作-树副本。在这里,git restore
或者git reset
(两者都将完成这项工作)是要走的路:
$ git restore --source HEAD -S file
$ git ls-files --stage
100644 7eafc9636afdf576278e921d7430598dd8754bdd 0 README
100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0 file
(请注意,这里的哈希 ID 与我们之前在插槽 2 中看到的相同。)
$ git show :0:file
fee file fo fum
bar
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
由于索引副本是 Git 将提交的文件,因此 a git commit
now 将进行另一个与当前提交匹配的提交(文件README
仍然与当前提交匹配)。由于我处于合并中间,所有冲突都已解决,这将进行最终的合并提交,快照与我使用的快照匹配git merge -s ours
,git merge -s recursive -X ours
例如:
$ git commit -m 'resolved by keeping ours'
[master b896bc3] resolved by keeping ours
$ git log --all --decorate --oneline --graph
* b896bc3 (HEAD -> master) resolved by keeping ours
|\
| * 679121a (branch) foo
* | 8921373 bar
|/
* a7a3f27 initial
(当然,我的工作树仍然有点混乱,并且git status
会显示我的工作树副本file
与我的索引副本不同file
,因为工作树版本仍然存在未解决的冲突。但 Git 没有使用该副本,以进行提交:它使用了索引副本。)