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

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


当前回答

为了完整,最适合我的是:

git show YOURHASH --no-color -- file1.txt file2.txt dir3 dir4 | git apply -3 --index -

这正是OP想要的。它在需要时进行冲突解决,类似于合并的方式。它会添加但不会提交新的更改,请参阅状态。

其他回答

与Jefromi的答案相比,这种方法的优势可能在于您不必记住git重置的哪个行为是正确的:)

 # Create a branch to throw away, on which we'll do the cherry-pick:
 git checkout -b to-discard

 # Do the cherry-pick:
 git cherry-pick stuff

 # Switch back to the branch you were previously on:
 git checkout -

 # Update the working tree and the index with the versions of A and B
 # from the to-discard branch:
 git checkout to-discard -- A B

 # Commit those changes:
 git commit -m "Cherry-picked changes to A and B from [stuff]"

 # Delete the temporary branch:
 git branch -D to-discard

您可以使用:

git diff <commit>^ <commit> -- <path> | git apply

符号<commit>^指定<commit>的(第一个)父级。因此,这个diff命令选择在commit<commit>中对<path>所做的更改。

注意,这还不会提交任何内容(正如gitcherry-pick所做的那样)。所以,如果你想这样做,你必须做到:

git add <path>
git commit

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

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 checkout <branch|hash> -- path/to/file1 path/to/filen

然后,在提交之前,取消编写必要的更改以适应代码并对其进行测试。如果一切按预期进行,那么提交。

情况:

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

方法:

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

git checkout master

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

git checkout commit_hash path\to\file

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

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