git cherry-pick不只是选择提交的差异

时间:2017-03-03 05:57:25

标签: git cherry-pick

我有两个分支:AB

  • A的提交历史记录:a <- b <- c;
  • B的提交历史记录:a <- h <- i;

假设这里只有一个文件。

  1. 在提交b中,我添加了一些文字,例如“foo”。
  2. 在提交c中,我添加了一些文字,例如“bar”。
  3. 然后我在git cherry-pick c分支上B。我认为cherry-pick只会选择c中的更改为分支B。但是,它会将foobar添加到分支B。这显然不是我想要的。
  4. 因此,cherry-pick将从祖先提交c中选择提交a中触及的那些文件的所有更改。是对的吗?如果我只想从bc选择差异并将其应用到i,该怎么办?

    更新确切的步骤

    1. 创建一个git repo;
    2. 添加文件test.txt并发出第一个提交init committest.txt现在是:

      first line  
      second line
      
    3. 创建新分支dev但留在分支master;

    4. added in commit b添加到文件并发出提交btest.txt现在是:

      first line
      added in commit b
      second line
      
    5. added in commit c添加到文件并发出提交ctest.txt现在是:

      first line
      added in commit b
      added in commit c
      second line
      
    6. 签出dev分支并发出提交htest.txt现在是:

      first line
      second line
      
      adding by commit h
      
    7. git cherry-pick <commit c SHA1 ID>将提交c提交到提交h

    8. 冲突讯息:

      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
      
    9. 请参阅? cherry-pick也会在提交b中带来更改。

    10. 谢谢!

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:0)

  

如果我只想从b到c中选择差异并将其应用到i?

,该怎么办?

您可以在两次提交(diff)之间查找/写入文件的c..d。然后将其应用于您当前的分支。

$ 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