问题描述
我有一个与挑剔的提交和冲突有关的问题.
I have a question related to cherry-picking commits and conflicts.
"Pro Git"书解释提交是一种快照,而不是补丁/差异.
The 'Pro Git' book explains that commits are kind of snapshots and not patches/diffs.
但是挑选樱桃的提交可能会表现得像补丁一样.
But cherry-picking commit may behave as it was a patch.
下面是一个简单的例子:
Example below, in short:
-
创建3次提交,每次编辑文件的第一行(单行)
create 3 commits, each time edit first (and single) line of the file
将分支重置为首次提交
test1:尝试挑选第三次提交(冲突)
test1 : try to cherry-pick third commit (conflict)
测试2:尝试选择第二次提交(确定)
test 2: try to cherry-pick second commit (OK)
mkdir gitlearn
cd gitlearn
touch file
git init
Initialized empty Git repository in /root/gitlearn/.git/
git add file
#fill file by single 'A'
echo A > file && cat file
A
git commit file -m A
[master (root-commit) 9d5dd4d] A
1 file changed, 1 insertion(+)
create mode 100644 file
#fill file by single 'B'
echo B > file && cat file
B
git commit file -m B
[master 28ad28f] B
1 file changed, 1 insertion(+), 1 deletion(-)
#fill file by single 'C'
echo C > file && cat file
C
git commit file -m C
[master c90c5c8] C
1 file changed, 1 insertion(+), 1 deletion(-)
git log --oneline
c90c5c8 C
28ad28f B
9d5dd4d A
测试1
#reset the branch to 9d5dd4d ('A' version)
git reset --hard HEAD~2
HEAD is now at 9d5dd4d A
git log --oneline
9d5dd4d A
#cherry-pick 'C' version over 'A'
git cherry-pick c90c5c8
error: could not apply c90c5c8... C
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'
#the conflict:
cat file
<<<<<<< HEAD
A
=======
C
>>>>>>> c90c5c8... C
测试2
#same for 'B' - succeeds
git reset --hard HEAD
HEAD is now at 9d5dd4d A
git cherry-pick 28ad28f
[master eb27a49] B
1 file changed, 1 insertion(+), 1 deletion(-)
请解释为什么测试1失败(如果提交是补丁,但快照,我可以想象答案吗?)
Please explain why test 1 failed (I could imagine the answer if commits were patches, but snapshots?)
推荐答案
Pro Git书是正确的:提交是快照.
The Pro Git book is correct: a commit is a snapshot.
您也没错,但是:git cherry-pick
应用了补丁.
You are also correct, though: git cherry-pick
applies a patch.
怎么可能?答案是,当您选择提交时,还需要使用-m parent-number
参数指定要考虑的 parent 提交.然后,cherry-pick命令会针对该父对象生成一个差异,以便立即应用所产生的差异.
How can this be? The answer is that when you cherry-pick a commit, you also specify which parent commit to consider, with the -m parent-number
argument. The cherry-pick command then generates a diff against that parent, so that the resulting diff can be applied now.
如果您选择选择一个非合并提交,则只有一个父级,因此您实际上不会传递-m
,并且该命令使用(单)父级来生成差异.但是提交本身仍然是快照,并且是cherry-pick
命令,用于找到commit^1
(第一个也是唯一的父级)与 commit
的区别,并将其应用.
Should you choose to cherry-pick a non-merge commit, there is only one parent, so you don't actually pass -m
and the command uses the (single) parent to generate the diff. But the commit itself is still a snapshot, and it's the cherry-pick
command that finds the diff of commit^1
(the first and only parent) vs commit
and applies that.
这篇关于摘樱桃提交-是提交快照还是补丁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!