协慌网

登录 贡献 社区

如何 git-cherry-pick 仅更改某些文件?

如果我想合并到 Git 分支中,而仅对某些提交中的某些文件所做的更改(包括对多个文件的更改)进行更改,那么如何实现呢?

stuff的 Git 提交对文件ABCD进行了更改,但是我只想将stuff AB的更改进行合并。这听起来像是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 -

它实际上并不会add文件或为您进行提交,因此您可能需要进行后续操作

git add file1.txt file2.txt
git commit -c SHA

或者,如果您想跳过添加操作,则可以使用--cached参数进行git apply

git show SHA -- file1.txt file2.txt | git apply --cached -

您还可以对整个目录执行相同的操作

git show SHA -- dir1 dir2 | git apply -

我通常将-p标志与其他分支的 git checkout 一起使用,与我遇到的大多数其他方法相比,我发现它更容易且更精细。

原则上:

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

然后,您会看到一个对话框,询问您要在 “blob” 中进行哪些更改,这几乎可以解决连续代码更改的每个块,然后您可以为每个代码块y (是) n

-ppatch选项适用于 git 中的各种命令,包括git stash save -p ,它允许您从当前工作中选择要隐藏的内容

当我做了很多工作时,有时我会使用这种技术,想将其分离出来,并使用git add -p提交更多基于主题的提交,并为每次提交选择想要的内容:)