Answers:
您在这里想要的核心是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>
这会将当前提交与您指定的提交进行比较,并允许您分别应用该差异中的块。如果您要拉入的提交在您不感兴趣的部分提交中具有合并冲突,则此选项可能更有用。(但是请注意,这checkout
与cherry-pick
:checkout
尝试<commit>
完全应用的内容,cherry-pick
应用diff的差异不同。从其父级提交的指定提交。这意味着它不仅checkout
可以应用该提交,还可以应用更多。
cherry-pick -n
似乎没有离开的变化上演-会展无疑是一个--no-commit
选择停止正确提交之前,即所有的变化上演。我将重置添加到答案中。
git checkout -p <F>
并不能只是让你从F中的变化,它可以让你ABCDEF所有一起捣碎,并让您整理出的哪一部分要。将其削减到F中的一些变化是很痛苦的。另一方面,git cherry-pick -n <F>
仅使您获得F中的更改-如果其中一些更改发生冲突,它会帮助您了解情况,以便您确定如何正确合并。
git reset
会删除暂存文件和add -p
只想说“没有补充”。
假设您要进行的更改位于要进行更改的分支的开头,请使用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
在Mike Monkiewicz答案的基础上,您还可以指定一个或多个文件从提供的sha1 /分支中检出。
git checkout -p bc66559 -- path/to/file.java
这将允许您交互式地选择要应用于当前文件版本的更改。
如果要在命令行上指定文件列表,并通过一个原子命令完成全部操作,请尝试:
git apply --3way <(git show -- list-of-files)
--3way
:如果补丁不能很好地应用,Git将创建合并冲突,因此您可以运行git mergetool
。省略--3way
将使Git放弃无法完全应用的补丁。
如果“部分采摘”的意思是“在文件内,选择一些更改,但放弃其他更改”,则可以通过输入以下内容来完成git stash
:
git reset HEAD^
将整个精心挑选的提交转换为未分阶段的工作更改。git stash save --patch
:以交互方式选择不需要的材料进行存储。git commit
git stash drop
。提示:如果您给不需要的更改存储区起了个名字:git stash save --patch junk
那么如果您现在忘记做(6),稍后您将识别该存储区的含义。