git cherry-pick 不只是选择提交的差异
git cherry-pick does not just pick the diff of the commit
我有两个分支:A
和 B
。
A
的提交历史:a <- b <- c
;
B
的提交历史:a <- h <- i
;
假设这里只有一个文件。
- 在提交
b
中,我添加了一些文本,例如 "foo"。
- 在提交
c
中,我添加了一些文本,例如 "bar"。
- 然后我
git cherry-pick c
在 B
分支。我以为 cherry-pick
只会选择 c
中的更改来分支 B
。但是,它会将 foo
和 bar
添加到分支 B
。这显然不是我想要的。
因此,cherry-pick
将选择自祖先提交 a
以来提交 c
中涉及的那些文件的所有更改。那正确吗?如果我只想选择从 b
到 c
的差异并将其应用到 i
怎么办?
更新确切步骤
- 初始化一个 git 回购;
添加文件 test.txt
并发出第一个提交 init commit
。 test.txt
现在是:
first line
second line
创建一个新分支 dev
但留在分支 master
;
将 added in commit b
添加到文件并发出提交 b
。 test.txt
现在是:
first line
added in commit b
second line
将 added in commit c
添加到文件并发出提交 c
。 test.txt
现在是:
first line
added in commit b
added in commit c
second line
签出 dev
分支并发出提交 h
。 test.txt
现在是:
first line
second line
adding by commit h
git cherry-pick <commit c SHA1 ID>
挑选提交 c
到提交 h
.
冲突信息:
index 6a8dc57,594c6ec..0000000
@@@ -1,4 -1,4 +1,9 @@@
first line
++<<<<<<< HEAD
++=======
+ added in commit b
+ added in commit c
++>>>>>>> 06ce9b1... commit c adding another line
second line
+
+adding by commit h
看到了吗? cherry-pick
也会在提交 b
.
中带来更改
谢谢!
What if I only want to pick the diff from b to c and apply it onto i?
您可以 find/write 两次提交 (c..d
) 之间的文件 diff
。然后在您当前的分支中应用它。
$ git checkout <B-branch>
# write the diff in a file named 'change.patch' (root directory)
$ git diff <b-commit> <c-commit> <file-name> >> ~/changes.patch
$ git apply ~/changes.patch # apply the changes
$ git add .
# merge the changes to i (previous commit)
$ git commit --amend -m 'Apply the diff of b and c'
$ git push -f origin HEAD # force(-f) push since history is changed
git cherry-pick
尝试只提交一次。但它通过应用需要一些上下文的补丁来做到这一点。提交 C 中所做的更改与提交 b 中所做的更改非常接近,因此您会遇到冲突 - 它不能只找到必须应用更改的正确位置。当你有冲突时,你也会得到一些冲突的上下文,这至少是你提交 B 的一部分。
如果没有冲突,它是这样工作的:
$ git init
$ cat > f
line1
line2
line3
$ git add f
$ git commit -a -m "initial"
# Edited to add a line in the beginning of f
$ cat f
Commit b
line1
line2
line3
$ git commit f -m "B"
# Edited to add a line in the end of f
$ cat f
Commit b
line1
line2
line3
Commit c
$ git commit f -m "C"
$ git checkout HEAD^^
$ git cherry-pick master
$ cat f
line1
line2
line3
Commit c
我有两个分支:A
和 B
。
A
的提交历史:a <- b <- c
;B
的提交历史:a <- h <- i
;
假设这里只有一个文件。
- 在提交
b
中,我添加了一些文本,例如 "foo"。 - 在提交
c
中,我添加了一些文本,例如 "bar"。 - 然后我
git cherry-pick c
在B
分支。我以为cherry-pick
只会选择c
中的更改来分支B
。但是,它会将foo
和bar
添加到分支B
。这显然不是我想要的。
因此,cherry-pick
将选择自祖先提交 a
以来提交 c
中涉及的那些文件的所有更改。那正确吗?如果我只想选择从 b
到 c
的差异并将其应用到 i
怎么办?
更新确切步骤
- 初始化一个 git 回购;
添加文件
test.txt
并发出第一个提交init commit
。test.txt
现在是:first line second line
创建一个新分支
dev
但留在分支master
;将
added in commit b
添加到文件并发出提交b
。test.txt
现在是:first line added in commit b second line
将
added in commit c
添加到文件并发出提交c
。test.txt
现在是:first line added in commit b added in commit c second line
签出
dev
分支并发出提交h
。test.txt
现在是:first line second line adding by commit h
git cherry-pick <commit c SHA1 ID>
挑选提交c
到提交h
.冲突信息:
index 6a8dc57,594c6ec..0000000 @@@ -1,4 -1,4 +1,9 @@@ first line ++<<<<<<< HEAD ++======= + added in commit b + added in commit c ++>>>>>>> 06ce9b1... commit c adding another line second line + +adding by commit h
看到了吗?
cherry-pick
也会在提交b
. 中带来更改
谢谢!
What if I only want to pick the diff from b to c and apply it onto i?
您可以 find/write 两次提交 (c..d
) 之间的文件 diff
。然后在您当前的分支中应用它。
$ git checkout <B-branch>
# write the diff in a file named 'change.patch' (root directory)
$ git diff <b-commit> <c-commit> <file-name> >> ~/changes.patch
$ git apply ~/changes.patch # apply the changes
$ git add .
# merge the changes to i (previous commit)
$ git commit --amend -m 'Apply the diff of b and c'
$ git push -f origin HEAD # force(-f) push since history is changed
git cherry-pick
尝试只提交一次。但它通过应用需要一些上下文的补丁来做到这一点。提交 C 中所做的更改与提交 b 中所做的更改非常接近,因此您会遇到冲突 - 它不能只找到必须应用更改的正确位置。当你有冲突时,你也会得到一些冲突的上下文,这至少是你提交 B 的一部分。
如果没有冲突,它是这样工作的:
$ git init
$ cat > f
line1
line2
line3
$ git add f
$ git commit -a -m "initial"
# Edited to add a line in the beginning of f
$ cat f
Commit b
line1
line2
line3
$ git commit f -m "B"
# Edited to add a line in the end of f
$ cat f
Commit b
line1
line2
line3
Commit c
$ git commit f -m "C"
$ git checkout HEAD^^
$ git cherry-pick master
$ cat f
line1
line2
line3
Commit c