547

我正在研究 2 个不同的分支:发布开发

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

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

git cherry-pick bc66559

不成功。

当我做一个

git show bc66559

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

4

8 回答 8

889

您在这里想要的核心是git add -p(-p是 的同义词--patch)。这提供了一种添加内容的交互式方式,让您决定是否每个大块应该进入,甚至让您在必要时手动编辑补丁。

将其与cherry-pick结合使用:

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. 如果您只想在提交中保留一些内容,您可以使用git reset <path>...unstage 仅这些文件。)

add -p如有必要,您可以提供特定路径。如果你从一个补丁开始,你可以cherry-pickapply.


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

git checkout -p <commit>

这会将当前提交与您指定的提交进行比较,并允许您单独从该差异中应用大块。如果您正在拉入的提交在您不感兴趣的部分提交中存在合并冲突,则此选项可能更有用。(但是,请注意,这checkoutcherry-pick:checkout尝试<commit>完全应用的内容不同,而cherry-pick应用差异来自它的父级的指定提交。这意味着checkout可以应用的不仅仅是那个提交,这可能比你想要的要多。)

于 2009-10-06T14:51:44.257 回答
80

我知道我在回答一个老问题,但看起来有一种新方法可以通过交互式签出来做到这一点:

git checkout -p bc66559

归功于我可以从另一个 git 提交中以交互方式挑选帅哥吗?

于 2013-06-29T04:46:33.153 回答
37

假设您想要的更改位于您想要更改的分支的开头,请使用 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
于 2010-02-01T06:06:38.880 回答
15

基于Mike Monkiewicz 的回答,您还可以指定一个或多个文件以从提供的 sha1/branch 中检出。

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

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

于 2014-10-24T12:48:17.430 回答
2

如果您想在命令行上指定文件列表,并在单个原子命令中完成整个操作,请尝试:

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

--3way:如果补丁没有完全应用,Git 将创建合并冲突,以便您可以运行git mergetool. 省略--3way将使 Git 放弃不能干净应用的补丁。

于 2019-08-18T04:00:58.250 回答
1

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

git format-patch <sha> -- path/to/file
git checkout other-branch
git am *.patch
于 2020-03-16T22:24:18.677 回答
0

如果“部分采摘”意味着“在文件中,选择一些更改但丢弃其他更改”,则可以通过引入git stash

  1. 做完整的樱桃采摘。
  2. git reset HEAD^将整个精心挑选的提交转换为未分级的工作更改。
  3. 现在git stash save --patch:以交互方式选择不需要的材料进行存储。
  4. Git 从工作副本中回滚隐藏的更改。
  5. git commit
  6. 丢弃不需要的更改:git stash drop.

提示:如果您为不需要的更改的存储命名:git stash save --patch junk那么如果您现在忘记执行 (6),稍后您将识别存储的内容。

于 2014-05-14T05:25:11.977 回答
0

实际上,这个问题的最佳解决方案是使用checkout表扬

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

例如,假设您在master,您想要从dev1project1/Controller/WebController1.java和进行更改project1/Service/WebService1.java,您可以使用以下命令:

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

这意味着分支仅在这两个路径上从dev1更新。

于 2021-01-27T15:47:05.863 回答