我是否可以标记一个文件以进行解析,而无需使用一个命令将其添加到索引中?

Enr*_*lis 5 git git-add git-index git-stage git-merge-conflict

当发生冲突时,git status显示如下:

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
    both modified:   some_file
Run Code Online (Sandbox Code Playgroud)

现在我可以git add some_file按照命令的建议标记解决方案,但这也会阶段化some_file,我可能不想这样做。

如何标记文件以进行解析而不将其添加到索引中?只需两步即可轻松完成:

git add some_file
git restore --staged some_file
Run Code Online (Sandbox Code Playgroud)

但如果可能的话,我该如何一步完成呢?

如果最佳实践不建议这样做,请告诉我。

tor*_*rek 8

\n

如何标记文件以进行解析而不将其添加到索引中?

\n
\n

亩。 (换句话说,这个问题预设了一些不可能存在的东西。)

\n

合并冲突表现为索引/暂存区域中存在文件的多个副本。1 也就是说,不是只有一个文件被暂存\xe2\x80\x94,这个文件要么与当前提交匹配,Git 就会对此闭嘴,要么不,Git 会在此处打印有关它的内容\ staged for commitxe2\x80\x94是三个准备提交的文件。Git 实际上无法提交一个文件的三个副本,并且不会让您提交,因此您必须解决这种情况......但是解决的行为包括删除三个文件并放入一个文件文件放在适当的位置。

\n

您放置的那个文件添加到索引中。它要么与当前提交的文件匹配,Git 什么也不说,要么不匹配,Git 说staged for commit。无论哪种方式该文件都存在。

\n

如果您想要使 Git 的索引包含当前提交中的副本作为文件的唯一副本,您可以这样做。但这意味着您已将该版本的文件添加 为暂存的提交版本。

\n
\n

1这在技术上不太正确:合并冲突由索引中具有任何非零阶段条目来表示。但是,当您确实遇到合并冲突时,最常见的是会得到一个或多个文件,每个文件都有三个条目。其他情况发生在添加/添加、修改/删除、重命名/重命名和重命名/删除冲突中。这些还留下多个代表“同一”文件的条目。

\n
\n

例子

\n

让我们来说明一下这一点。首先,让我们创建一个小型存储库并设置冲突:

\n
$ mkdir test-resolve\n$ cd test-resolve/\n$ git init\nInitialized empty Git repository in .../.git/\n$ echo test conflict resolution > README\n$ echo fee file fo fum > file\n$ git add . && git commit -q -m initial\n$ git checkout -b branch\nSwitched to a new branch \'branch\'\n$ echo foo >> file && git add file && git commit -q -m foo\n$ git checkout -q master\n$ echo bar >> file && git add file && git commit -q -m bar\n$ git log --all --decorate --oneline --graph\n* 8921373 (HEAD -> master) bar\n| * 679121a (branch) foo\n|/  \n* a7a3f27 initial\n
Run Code Online (Sandbox Code Playgroud)\n

现在让我们看看 Git 的暂存区/索引中有什么:

\n
$ git ls-files --stage\n100644 7eafc9636afdf576278e921d7430598dd8754bdd 0       README\n100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0       file\n
Run Code Online (Sandbox Code Playgroud)\n

这些是 Git 暂存区域中的文件,及其暂存编号。阶段编号为零表示不存在合并冲突;此类文件不能有任何其他条目。请注意,这两个文件都已暂存以供提交!它们只是匹配HEAD提交版本,所以这git status并没有说明 staged for commit

\n

现在我们将运行合并:

\n
$ git merge branch\nAuto-merging file\nCONFLICT (content): Merge conflict in file\nAutomatic merge failed; fix conflicts and then commit the result.\n$ git ls-files --stage\n100644 7eafc9636afdf576278e921d7430598dd8754bdd 0       README\n100644 8fee5c26846ed992dc2dd912e224a2001a2b6820 1       file\n100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 2       file\n100644 af8330063fa2da41a81f8a789929fd87692adb2f 3       file\n
Run Code Online (Sandbox Code Playgroud)\n

瞧!这是名为 的文件的三个副本file。他们有非零的暂存编号;它们代表文件的合并基础副本(第 1 阶段)、ours副本(第 2 阶段)和theirs副本(第 3 阶段)。如果愿意,我们可以查看文件:git show :1:filegit show :2:file等等:

\n
$ git show :3:file\nfee file fo fum\nfoo\n
Run Code Online (Sandbox Code Playgroud)\n

“他们的”文件,从分支 的顶端开始branch,是第 2 行读取的文件foo(我们的文件读取的是bar)。

\n

现在,文件的工作树file副本包含 Git 解决冲突的尝试。如果我们看到这一点,就会发现进展并不顺利。请注意,我已merge.conflictStyle进行配置,diff3以便我也获得文本的合并基础版本:

\n
$ cat file\nfee file fo fum\n<<<<<<< HEAD\nbar\n||||||| a7a3f27\n=======\nfoo\n>>>>>>> branch\n
Run Code Online (Sandbox Code Playgroud)\n

现在我们回到您的问题,我将再次引用该问题

\n
\n

如何标记文件以进行解析

\n
\n

选择三个阶段中存在的三个副本之一,或者提交HEAD或任何其他提交中存在的副本,然后选择该副本作为要进入 Git 索引中的插槽 0 的副本。擦除另外两个插槽。该文件现已暂存以供提交。

\n
\n

而不将其添加到索引中?

\n
\n

它已经在索引中了。您要减去两个或三个副本,可能会留下第三个并将其移动到插槽 0;或者您减去所有三份副本并向索引添加一份新副本。

\n

您可以使用将工作树git add文件复制到索引中,或者您可以选择一些现有的 Git 化副本并将其移入。假设您希望将文件的副本粘贴到索引中,而不需要触摸工作树副本。这里,或者(两者都会完成这项工作)是要走的路:HEADgit restoregit reset

\n
$ git restore --source HEAD -S file\n$ git ls-files --stage\n100644 7eafc9636afdf576278e921d7430598dd8754bdd 0       README\n100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0       file\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,此处的哈希 ID 与我们之前在槽 2 中看到的哈希 ID 相同。)

\n
$ git show :0:file\nfee file fo fum\nbar\n$ cat file\nfee file fo fum\n<<<<<<< HEAD\nbar\n||||||| a7a3f27\n=======\nfoo\n>>>>>>> branch\n
Run Code Online (Sandbox Code Playgroud)\n

由于索引副本是 Git 将提交的文件,因此git commitnow 将进行与当前提交匹配的另一个提交(文件README仍与当前提交匹配)。由于我正处于合并过程中,所有冲突都已解决,这将进行最终的合并提交,快照与我使用或使用时得到的快照相git merge -s ours匹配git merge -s recursive -X ours时得到的快照相匹配,例如:

\n
$ git commit -m \'resolved by keeping ours\'\n[master b896bc3] resolved by keeping ours\n$ git log --all --decorate --oneline --graph\n*   b896bc3 (HEAD -> master) resolved by keeping ours\n|\\  \n| * 679121a (branch) foo\n* | 8921373 bar\n|/  \n* a7a3f27 initial\n
Run Code Online (Sandbox Code Playgroud)\n

(当然,我的工作树仍然有点混乱,并且git status会显示我的工作树副本file与我的索引副本不同file,因为工作树版本仍然存在未解决的冲突。但是 Git 没有使用该副本进行提交:它使用了索引副本。)

\n