如果我想将仅对特定提交中更改的部分文件(包括对多个文件的更改)进行的更改合并到Git分支中,如何实现这一点?
假设名为stuff的Git提交对文件A、B、C和D进行了更改,但我只想将stuff的更改合并到文件A和B。这听起来像Git cherry-pick的工作,但cherry pick只知道如何合并整个提交,而不是文件的子集。
如果我想将仅对特定提交中更改的部分文件(包括对多个文件的更改)进行的更改合并到Git分支中,如何实现这一点?
假设名为stuff的Git提交对文件A、B、C和D进行了更改,但我只想将stuff的更改合并到文件A和B。这听起来像Git cherry-pick的工作,但cherry pick只知道如何合并整个提交,而不是文件的子集。
当前回答
我会使用cherry-pick-n(--no-commit)来完成,它允许您在提交之前检查(和修改)结果:
git cherry-pick -n <commit>
# unstage modifications you don't want to keep, and remove the
# modifications from the work tree as well.
# this does work recursively!
git checkout HEAD <path>
# commit; the message will have been stored for you by cherry-pick
git commit
如果绝大多数修改都是您不想要的,那么您可以重新设置所有内容,然后添加您想要的内容,而不是检查各个路径(中间步骤):
# unstage everything
git reset HEAD
# stage the modifications you do want
git add <path>
# make the work tree match the index
# (do this from the top level of the repo)
git checkout .
其他回答
其他方法对我不起作用,因为提交时对很多其他文件进行了大量更改和冲突。我想到的只是
git show SHA -- file1.txt file2.txt | git apply -
它实际上并没有为您添加文件或进行提交,因此您可能需要使用
git add file1.txt file2.txt
git commit -c SHA
或者,如果您想跳过add,可以使用--cached参数来git-apply
git show SHA -- file1.txt file2.txt | git apply --cached -
您也可以对整个目录执行相同的操作
git show SHA -- dir1 dir2 | git apply -
您可以使用:
git diff <commit>^ <commit> -- <path> | git apply
符号<commit>^指定<commit>的(第一个)父级。因此,这个diff命令选择在commit<commit>中对<path>所做的更改。
注意,这还不会提交任何内容(正如gitcherry-pick所做的那样)。所以,如果你想这样做,你必须做到:
git add <path>
git commit
我会选择一切,然后这样做:
git reset --soft HEAD^
然后我会还原我不想要的更改,然后进行新的提交。
我找到了另一种方法来防止樱桃采摘上的任何冲突合并,IMO很容易记住和理解。因为您实际上不是在挑选提交,而是其中的一部分,所以您需要先拆分它,然后创建一个符合您需要的提交,然后再挑选它。
首先从要拆分并签出的提交创建分支:
$ git checkout COMMIT-TO-SPLIT-SHA -b temp
然后恢复上一次提交:
$ git reset HEAD~1
然后添加您要选择的文件/更改:
$ git add FILE
并提交:
$ git commit -m "pick me"
请注意提交散列,让我们将其称为PICK-SHA,然后返回主分支,例如master强制结账:
$ git checkout -f master
和樱桃选择承诺:
$ git cherry-pick PICK-SHA
现在可以删除临时分支:
$ git branch -d temp -f
我通常将-p标志与来自其他分支的git签出一起使用,我发现这比我遇到的大多数其他方法更容易和更精细。
原则上:
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -p
例子:
git checkout mybranch config/important.yml app/models/important.rb -p
然后,您会看到一个对话框,询问您希望在“blobs”中进行哪些更改,这基本上适用于连续代码更改的每个块,然后您可以为每个代码块发出y(是)n(否)等信号。
-p或patch选项适用于git中的各种命令,包括git stash save-p,它允许您从当前工作中选择要隐藏的内容
当我做了很多工作,并希望将其分离出来,使用gitadd-p提交更多基于主题的提交,并选择每次提交所需的内容时,我有时会使用此技术:)