部分樱桃 - 用Git挑选一个提交

时间:2009-10-06 14:47:04

标签: git git-cherry-pick

我正在开设两个不同的分支机构:发布开发

我注意到我仍然需要将一些提交到发布分支的更改集成回开发分支。

问题是我不需要所有的提交,只有某些文件中的某些人,所以简单

git cherry-pick bc66559

没有做到这一点。

我做的时候

git show bc66559

我可以看到差异,但实际上并不知道将其部分应用到我当前工作树的好方法。

8 个答案:

答案 0 :(得分:731)

您需要的核心内容是git add -p-p--patch的同义词)。这提供了一种检查内容的交互方式,让您决定是否应该进入每个大块,甚至可以在必要时手动编辑修补程序。

与樱桃挑选结合使用:

git cherry-pick -n <commit> # get your patch, but don't commit (-n = --no-commit)
git reset                   # unstage the changes from the cherry-picked commit
git add -p                  # make all your choices (add the changes you do want)
git commit                  # make the commit!

(感谢Tim Henigan提醒我git-cherry-pick有--no-commit选项,感谢Felix Rabe指出你需要重置!如果你只想留下一些东西在提交时,您可以使用git reset <path>...来取消暂存这些文件。)

如果有必要,您当然可以提供add -p的具体路径。如果您开始使用补丁,则可以将cherry-pick替换为apply


如果您真的想要git cherry-pick -p <commit>(该选项不存在),您可以使用

git checkout -p <commit>

这会将当前提交与您指定的提交区分开来,并允许您单独应用该差异中的值。如果您提交的提交在您不感兴趣的部分提交中存在合并冲突,则此选项可能更有用。(但请注意,checkoutcherry-pick不同:{{ 1}}尝试完全应用checkout的内容,<commit>从其父级应用指定提交的diff。这意味着cherry-pick可以应用的不仅仅是那个提交,超过你想要的。)

答案 1 :(得分:67)

我知道我正在回答一个老问题,但看起来有一种新方法可以通过交互式检查来完成:

git checkout -p bc66559

归功于Can I interactively pick hunks from another git commit?

答案 2 :(得分:36)

假设您想要的更改位于分支的开头,您希望进行更改,请使用git checkout

单个文件:

git checkout branch_that_has_the_changes_you_want path/to/file.rb

对于多个文件只是菊花链:

git checkout branch_that_has_the_changes_you_want path/to/file.rb path/to/other_file.rb

答案 3 :(得分:13)

Mike Monkiewicz答案的基础上,你还可以指定一个或多个要从提供的sha1 / branch签出的文件。

git checkout -p bc66559 -- path/to/file.java 

这将允许您以交互方式选择要应用于当前版本文件的更改。

答案 4 :(得分:1)

如果要在命令行上指定文件列表,并通过一个原子命令完成全部操作,请尝试:

git apply --3way <(git show -- list-of-files)

--3way:如果补丁不能很好地应用,Git将创建合并冲突,因此您可以运行git mergetool。省略--3way将使Git放弃无法完全应用的补丁。

答案 5 :(得分:0)

如果&#34;部分樱桃采摘&#34;意味着&#34;在文件中,选择一些更改但丢弃其他人&#34;,可以通过引入git stash来完成:

  1. 做完整的樱桃选择。
  2. git reset HEAD^将整个樱桃选择的提交转换为未经分级的工作更改。
  3. 现在git stash save --patch:以交互方式选择不需要的材料进行存储。
  4. Git从您的工作副本中回滚了隐藏的更改。
  5. git commit
  6. 丢掉不必要的变化:git stash drop
  7. 提示:如果你给不需要的更改藏匿名称:git stash save --patch junk那么如果你现在忘了做(6),之后你就会认出它藏匿的东西。

答案 6 :(得分:0)

使用git format-patch切出您关心的提交部分,并使用git am将其应用于另一个分支

git format-patch <sha> -- path/to/file
git checkout other-branch
git am *.patch

答案 7 :(得分:0)

其实这个问题最好的解决方法是使用checkoutcommend

git checkout <branch> <path1>,<path2> ..

例如,假设您在 ma​​ster 中,您希望从 dev1 更改 project1/Controller/WebController1.javaproject1/Service/WebService1.java,您可以使用此:

git checkout dev1 project1/Controller/WebController1.java project1/Service/WebService1.java

这意味着 ma​​ster 分支仅在这两条路径上从 dev1 更新。