如何只选择一个文件的更改,而不是整个提交

ash*_*him 95 git

我需要将一个分支中引入的更改应用到另一个分支.我可以用樱桃挑选来做到这一点.但是,在我的情况下,我想应用仅与一个文件相关的更改,我不需要挑选整个提交.怎么做?

pok*_*oke 126

根据您想要实现的目标,您有不同的选择:

如果您希望文件的内容与目标分支上的内容相同,则可以使用git checkout <branch> -- <filename>.但是,这不会"挑选"单个提交中发生的更改,而只是获取所述文件的结果状态.因此,如果您在提交中添加了一行,但之前的提交更改了更多,并且您只想添加该行而不进行其他更改,则结帐不是您想要的.

否则,如果要将提交中引入的修补程序仅应用于单个文件,则可以有多个选项.您可以运行git cherry-pick -n,即不提交它,编辑提交(例如,使用重置所有文件git reset -- .,仅添加您实际想要更改的文件git add <filename>).或者你可以为文件创建diff并应用diff然后:

git diff <branch>^..<branch> -- <filename> | git apply
Run Code Online (Sandbox Code Playgroud)


Sai*_*esh 20

创建patch file并应用它.

git diff branchname -- filename > patchfile
git apply patchfile
Run Code Online (Sandbox Code Playgroud)

编辑:

由于您需要从提交中获取更改,因此请创建如下补丁:

git show sha1 -- filename > patchfile
Run Code Online (Sandbox Code Playgroud)

  • 对于这个特例,是的.但一般来说,如果你想从对特定文件的提交中选择更改,那么`checkout`将不起作用,因为它可能涉及其他不需要的先前更改,并且可能不包含在当前分支中进行的更改. (7认同)

0x9*_*x90 10

另一个方便的事情是在本地获取补丁然后使用:

git checkout {<name_of_branch>, commit's SHA} <path to the file> 
Run Code Online (Sandbox Code Playgroud)

这不是一个挑选的樱桃.

  • 警告:正如@poke在他的回答中所说,这不会复制更改; 它复制文件的整个状态.因此,如果你想_add_一个提交对文件的更改,那么通过这样检查你最终_overwriting_任何新的改变,这是不好的. (2认同)

Rag*_*m S 7

Git准备好了一切:)

只是用 git checkout <sha> <path-to-file>

  • 这不是一个挑选 - 完全检查文件.目标是从提交中进行特定更改.通常这些是相同的,但有时它们不是. (3认同)

Ism*_*bal 6

git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension
Run Code Online (Sandbox Code Playgroud)

如果您希望将另一个分支中的单个文件复制到当前工作分支,则此方法有效


shu*_*uva 6

使用-n选项来避免提交。

git cherry-pick -n <target>
Run Code Online (Sandbox Code Playgroud)

现在通过选择所需的文件来进行提交。

git commit -- file1 file2
Run Code Online (Sandbox Code Playgroud)


ara*_*b31 5

您可以尝试这样做:

git show COMMIT_ID -- path/to/specific-file | git apply
Run Code Online (Sandbox Code Playgroud)

例如:

git show 3feaf20 -- app/views/home/index.html | git apply
Run Code Online (Sandbox Code Playgroud)