无法挑选提交更改不存在的文件
Cannot cherry-pick commit changing not-existing file
我想知道为什么 git 不允许挑选对不存在的文件进行更改的提交。
我的理解是提交代表工作目录的完整快照。因此,挑选一个包含当前不存在的文件的提交应该简单地创建该文件 - 但我可以看到情况并非如此。
下面是重现我正在谈论的情况的几个命令。
$ git init
Initialized empty Git repository in /home/mzakrze/workspace/tmp/.git/
$ echo "Hello world!" > first_file; git add first_file; git commit -m "Init commit"
[master (root-commit) 7f9478a] Init commit
1 file changed, 1 insertion(+)
create mode 100644 first_file
$ echo "Fox jumps over the layz dog" > test; git add test; git commit -m "Commit with a typo"
[master 776387b] Commit with a typo
1 file changed, 1 insertion(+)
create mode 100644 test
$ echo "Fox jumps over the lazy dog" > test; git add test; git commit -m "Fix typo"
[master 9ea19df] Fix typo
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log
commit 9ea19dfe2597b28eb576e2682e745de3da74733f
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 17:01:13 2021 +0200
Fix typo
commit 776387b563edba9df2a12c5d1a2fd5bffb10c643
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 17:00:53 2021 +0200
Commit with a typo
commit 7f9478a83e3938bf57552c1b90ddc7322b1bf315
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 16:59:04 2021 +0200
Init commit
$ git reset --hard 7f9478a83e3938bf57552c1b90ddc7322b1bf315
HEAD is now at 7f9478a Init commit
$ git cherry-pick 9ea19 # cherry-pick "Fix typo"
error: could not apply 9ea19df... Fix typo
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
INB4:我不是在寻找“解决方案”,我只是想了解为什么 git 认为这是一个冲突。
如果您查看 cherry-pick
命令的文档(参见 git cherry-pick --help
),描述是“应用一些现有提交引入的更改”。换句话说,这会查看选定的提交及其父项,计算两者之间的差异,并尝试将该更改应用到当前分支。
您尝试提交的更改cherry-pick
影响了一个不存在的文件,因此无法应用。
如果您只是想要源代码提交中存在的文件,您可以:
git checkout 9ea19 test
请记住,cherry-pick 在技术上是一种三向合并。您 运行 git cherry-pick C
,对于某些提交 C
——通常由哈希 ID 指定——并且 Git 找到提交 C
的父级 P
:
- 提交
P
现在是 合并基础;
ours
提交是 当前 (HEAD
) 提交;和
theirs
提交是提交 C
。
P
和HEAD
的区别在于,有问题的文件已被完全删除。 P
和C
的区别是修改了文件内容
对于标准合并算法(git-merge-recursive
),这是一个高级别或树级别冲突:一个modify/delete冲突。这是无法用 -X ours
或 -X theirs
解决的合并冲突。因此,合并在中间停止,给您留下必须解决的合并冲突。
解决合并冲突,运行git cherry-pick --continue
完成cherry-pick。解决此合并冲突的方式取决于您; 中的git checkout
命令就可以了,或者你可以使用git checkout --theirs test
和git add test
。请注意,当使用 git checkout --ours
(在这种情况下不适用)和 git checkout --theirs
时,Git 不会标记冲突已解决,但是当使用 git checkout CHERRY_PICK_HEAD
(或原始哈希 ID)时, Git 是否 标记冲突已解决。这是由于 git checkout
.
的实现中的一个怪癖
我想知道为什么 git 不允许挑选对不存在的文件进行更改的提交。 我的理解是提交代表工作目录的完整快照。因此,挑选一个包含当前不存在的文件的提交应该简单地创建该文件 - 但我可以看到情况并非如此。
下面是重现我正在谈论的情况的几个命令。
$ git init
Initialized empty Git repository in /home/mzakrze/workspace/tmp/.git/
$ echo "Hello world!" > first_file; git add first_file; git commit -m "Init commit"
[master (root-commit) 7f9478a] Init commit
1 file changed, 1 insertion(+)
create mode 100644 first_file
$ echo "Fox jumps over the layz dog" > test; git add test; git commit -m "Commit with a typo"
[master 776387b] Commit with a typo
1 file changed, 1 insertion(+)
create mode 100644 test
$ echo "Fox jumps over the lazy dog" > test; git add test; git commit -m "Fix typo"
[master 9ea19df] Fix typo
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log
commit 9ea19dfe2597b28eb576e2682e745de3da74733f
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 17:01:13 2021 +0200
Fix typo
commit 776387b563edba9df2a12c5d1a2fd5bffb10c643
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 17:00:53 2021 +0200
Commit with a typo
commit 7f9478a83e3938bf57552c1b90ddc7322b1bf315
Author: mzakrze <xxxxxx@gmail.com>
Date: Sun Apr 11 16:59:04 2021 +0200
Init commit
$ git reset --hard 7f9478a83e3938bf57552c1b90ddc7322b1bf315
HEAD is now at 7f9478a Init commit
$ git cherry-pick 9ea19 # cherry-pick "Fix typo"
error: could not apply 9ea19df... Fix typo
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
INB4:我不是在寻找“解决方案”,我只是想了解为什么 git 认为这是一个冲突。
如果您查看 cherry-pick
命令的文档(参见 git cherry-pick --help
),描述是“应用一些现有提交引入的更改”。换句话说,这会查看选定的提交及其父项,计算两者之间的差异,并尝试将该更改应用到当前分支。
您尝试提交的更改cherry-pick
影响了一个不存在的文件,因此无法应用。
如果您只是想要源代码提交中存在的文件,您可以:
git checkout 9ea19 test
请记住,cherry-pick 在技术上是一种三向合并。您 运行 git cherry-pick C
,对于某些提交 C
——通常由哈希 ID 指定——并且 Git 找到提交 C
的父级 P
:
- 提交
P
现在是 合并基础; ours
提交是 当前 (HEAD
) 提交;和theirs
提交是提交C
。
P
和HEAD
的区别在于,有问题的文件已被完全删除。 P
和C
的区别是修改了文件内容
对于标准合并算法(git-merge-recursive
),这是一个高级别或树级别冲突:一个modify/delete冲突。这是无法用 -X ours
或 -X theirs
解决的合并冲突。因此,合并在中间停止,给您留下必须解决的合并冲突。
解决合并冲突,运行git cherry-pick --continue
完成cherry-pick。解决此合并冲突的方式取决于您; git checkout
命令就可以了,或者你可以使用git checkout --theirs test
和git add test
。请注意,当使用 git checkout --ours
(在这种情况下不适用)和 git checkout --theirs
时,Git 不会标记冲突已解决,但是当使用 git checkout CHERRY_PICK_HEAD
(或原始哈希 ID)时, Git 是否 标记冲突已解决。这是由于 git checkout
.