我可以将一个文件标记为待解决而不用一个命令将它添加到索引吗?
Can I mark a file for resolution without adding it to the index with one command?
发生冲突时,git status
显示为:
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: some_file
现在我可以 git add some_file
标记分辨率,正如命令所建议的那样,但这也会分阶段 some_file
,我可能不想这么做。
如何在不将文件添加到索引的情况下将其标记为待解决?简单两步:
git add some_file
git restore --staged some_file
但如果可能的话,我该如何一步完成呢?
如果最佳实践不推荐这样做,请告诉我。
How can I mark the file for resolution without adding it to the index?
Mu.(也就是说,这道题预设了不存在的东西。)
合并冲突表现为在索引/暂存区中有一个文件的多个副本。1也就是说,不仅仅是一个文件被暂存——这个文件要么匹配当前提交,Git 只是闭嘴,要么不匹配,Git 打印 staged for commit
关于它——有 三个 文件暂存提交。 Git实际上不能提交一个文件的三个副本并且不会让你提交,所以你必须解决这种情况。 .. 但解决的过程包括擦除 那些 三个文件并将 一个 文件放在适当的位置。
您放置的那个文件 已被 添加到索引中。它要么匹配当前提交的文件,Git 什么都不说,要么不匹配,Git 说 staged for commit
。该文件以任何一种方式存在。
如果你想让Git的索引包含当前提交中的副本作为文件的一个副本,你可以 去做。但这意味着您已经 添加了 文件的那个版本 作为准备提交的版本。
1这在技术上不太正确:合并冲突表示为索引中有 任何非零阶段条目。但是,当您遇到合并冲突时,最常见的是 您会得到一个或多个文件,每个文件都有三个条目。其他情况发生 add/add、modify/delete、rename/rename 和 rename/delete 冲突。这些也留下了多个代表“相同”文件的条目。
例子
让我们来说明一下。首先,让我们创建一个小型存储库并设置一个冲突:
$ 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
。 =50=]
现在我们将 运行 合并:
$ 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
的顶端开始,第 2 行显示为 foo
(我们的显示为 bar
)。
现在,文件 file
的 工作树 副本包含 Git 解决冲突的尝试。如果我们这样看,我们可以看到它进行得并不顺利。请注意,我将 merge.conflictStyle
配置为 diff3
,这样我也可以获得文本的合并基础版本:
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
我们现在return回答你的问题,我会再次引用
How can I mark the file for resolution
选择三个阶段中存在的三个副本之一,或者存在于 HEAD
提交或任何其他提交中的副本,并选择它作为副本进入 [= 中的槽零132=]的索引。擦除其他两个插槽。该文件现在已准备提交。
without adding it to the index?
它已经在索引中了。您正在 减去 两份或三份副本,可能会留下第三份并将其移至槽零;或者你减去所有三个副本并在索引中添加一个新副本。
您可以使用 git add
将 工作树 文件复制到索引中,或者您可以选择一些现有的 Git-ified 复制并移动它in. 假设您想将文件的 HEAD
副本粘贴到索引中,而不触及工作树副本。在这里,git restore
或 git reset
(两者都可以完成这项工作)是要走的路:
$ git restore --source HEAD -S file
$ git ls-files --stage
100644 7eafc9636afdf576278e921d7430598dd8754bdd 0 README
100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0 file
(注意这里的hash ID和我们之前在slot 2看到的一样。)
$ git show :0:file
fee file fo fum
bar
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
由于索引副本是 Git 将提交的文件,因此 git commit
现在将进行另一个与当前提交匹配的提交(文件 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 没有使用该副本来进行提交:它使用了索引副本。)
发生冲突时,git status
显示为:
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: some_file
现在我可以 git add some_file
标记分辨率,正如命令所建议的那样,但这也会分阶段 some_file
,我可能不想这么做。
如何在不将文件添加到索引的情况下将其标记为待解决?简单两步:
git add some_file
git restore --staged some_file
但如果可能的话,我该如何一步完成呢?
如果最佳实践不推荐这样做,请告诉我。
How can I mark the file for resolution without adding it to the index?
Mu.(也就是说,这道题预设了不存在的东西。)
合并冲突表现为在索引/暂存区中有一个文件的多个副本。1也就是说,不仅仅是一个文件被暂存——这个文件要么匹配当前提交,Git 只是闭嘴,要么不匹配,Git 打印 staged for commit
关于它——有 三个 文件暂存提交。 Git实际上不能提交一个文件的三个副本并且不会让你提交,所以你必须解决这种情况。 .. 但解决的过程包括擦除 那些 三个文件并将 一个 文件放在适当的位置。
您放置的那个文件 已被 添加到索引中。它要么匹配当前提交的文件,Git 什么都不说,要么不匹配,Git 说 staged for commit
。该文件以任何一种方式存在。
如果你想让Git的索引包含当前提交中的副本作为文件的一个副本,你可以 去做。但这意味着您已经 添加了 文件的那个版本 作为准备提交的版本。
1这在技术上不太正确:合并冲突表示为索引中有 任何非零阶段条目。但是,当您遇到合并冲突时,最常见的是 您会得到一个或多个文件,每个文件都有三个条目。其他情况发生 add/add、modify/delete、rename/rename 和 rename/delete 冲突。这些也留下了多个代表“相同”文件的条目。
例子
让我们来说明一下。首先,让我们创建一个小型存储库并设置一个冲突:
$ 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
。 =50=]
现在我们将 运行 合并:
$ 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
的顶端开始,第 2 行显示为 foo
(我们的显示为 bar
)。
现在,文件 file
的 工作树 副本包含 Git 解决冲突的尝试。如果我们这样看,我们可以看到它进行得并不顺利。请注意,我将 merge.conflictStyle
配置为 diff3
,这样我也可以获得文本的合并基础版本:
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
我们现在return回答你的问题,我会再次引用
How can I mark the file for resolution
选择三个阶段中存在的三个副本之一,或者存在于 HEAD
提交或任何其他提交中的副本,并选择它作为副本进入 [= 中的槽零132=]的索引。擦除其他两个插槽。该文件现在已准备提交。
without adding it to the index?
它已经在索引中了。您正在 减去 两份或三份副本,可能会留下第三份并将其移至槽零;或者你减去所有三个副本并在索引中添加一个新副本。
您可以使用 git add
将 工作树 文件复制到索引中,或者您可以选择一些现有的 Git-ified 复制并移动它in. 假设您想将文件的 HEAD
副本粘贴到索引中,而不触及工作树副本。在这里,git restore
或 git reset
(两者都可以完成这项工作)是要走的路:
$ git restore --source HEAD -S file
$ git ls-files --stage
100644 7eafc9636afdf576278e921d7430598dd8754bdd 0 README
100644 1f4f7a3f149c9b0e7740a5f2f801b1840f2d68f8 0 file
(注意这里的hash ID和我们之前在slot 2看到的一样。)
$ git show :0:file
fee file fo fum
bar
$ cat file
fee file fo fum
<<<<<<< HEAD
bar
||||||| a7a3f27
=======
foo
>>>>>>> branch
由于索引副本是 Git 将提交的文件,因此 git commit
现在将进行另一个与当前提交匹配的提交(文件 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 没有使用该副本来进行提交:它使用了索引副本。)