如果我想将仅对特定提交中更改的部分文件(包括对多个文件的更改)进行的更改合并到Git分支中,如何实现这一点?

假设名为stuff的Git提交对文件A、B、C和D进行了更改,但我只想将stuff的更改合并到文件A和B。这听起来像Git cherry-pick的工作,但cherry pick只知道如何合并整个提交,而不是文件的子集。


当前回答

情况:

你在你的分支上,比如说,你在任何其他分支上都有你的承诺。您只能从该特定提交中选择一个文件。

方法:

步骤1:在所需的分支上签出。

git checkout master

步骤2:确保已复制所需的提交哈希。

git checkout commit_hash path\to\file

步骤3:您现在在所需的分支上对所需文件进行了更改。你只需要添加并提交它们。

git add path\to\file
git commit -m "Your commit message"

其他回答

我会选择一切,然后这样做:

git reset --soft HEAD^

然后我会还原我不想要的更改,然后进行新的提交。

其他方法对我不起作用,因为提交时对很多其他文件进行了大量更改和冲突。我想到的只是

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 -

使用修补程序标志签出

完成您所描述内容的一个简单方法是通过签出补丁。修改我在顶部提供的四个变量。脚本执行以下操作:

克隆包含提交的分支(源分支)签出要将文件移动到的分支(目标分支)在所需的提交版本签出源分支,提供补丁标志和文件的相对位置作为参数。添加、提交、推送

对我来说,这一直是最简单的方法。步骤#3确实创建了一个交互式shell,但如果你想破坏目标,你可以默认整个选项。

source_branch=branch_with_file_you_want
destination_branch=file_go_here
rev=757c47d4
relative_file_path=structures/serializers/node.py
message="Patching a file from $source_branch to $destination_branch"

git clone https://github.com/yourepo/app.git -b $source_branch $source_branch
cd $source_branch
git checkout $destination_branch
git checkout $rev --patch $source_branch $relative_file_path
git add $relative_file_path
git commit -m "$message"
git push

如果您是远程GitLab,如果您需要MR,可以使用git push-o merge_request.create

Cherry pick是从特定的“提交”中选择更改。最简单的解决方案是选择某些文件的所有更改

 git checkout source_branch <paths>...

例如:

$ git branch
* master
  twitter_integration
$ git checkout twitter_integration app/models/avatar.rb db/migrate/20090223104419_create_avatars.rb test/unit/models/avatar_test.rb test/functional/models/avatar_test.rb
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   app/models/avatar.rb
#   new file:   db/migrate/20090223104419_create_avatars.rb
#   new file:   test/functional/models/avatar_test.rb
#   new file:   test/unit/models/avatar_test.rb
#
$ git commit -m "'Merge' avatar code from 'twitter_integration' branch"
[master]: created 4d3e37b: "'Merge' avatar code from 'twitter_integration' branch"
4 files changed, 72 insertions(+), 0 deletions(-)
create mode 100644 app/models/avatar.rb
create mode 100644 db/migrate/20090223104419_create_avatars.rb
create mode 100644 test/functional/models/avatar_test.rb
create mode 100644 test/unit/models/avatar_test.rb

来源和完整解释http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/

更新:

使用此方法,git不会合并文件,它只会覆盖在目标分支上所做的任何其他更改。您需要手动合并更改:

$git diff HEAD文件名

将分支合并为新分支(挤压)并删除不需要的文件:

git checkout master
git checkout -b <branch>
git merge --squash <source-branch-with-many-commits>
git reset HEAD <not-needed-file-1>
git checkout -- <not-needed-file-1>
git reset HEAD <not-needed-file-2>
git checkout -- <not-needed-file-2>
git commit