如何仅从另一个分支获取一个文件


1260

我正在使用git并在master分支上工作。该分支有一个名为的文件app.js

我有一个experiment分支,在其中进行了大量更改和大量提交。现在,我想将所有所做的更改仅带到app.jsfrom experimentmasterBranch。

我怎么做?

再一次,我不想合并。我只想把所有的变化,app.jsexperiment分支到master分支。



1
到目前为止,除了答案之外,其他人都回答如何复制文件的内容,这就是我发现自己想要的东西。但是,如果准确阅读,Nick希望带来更改而不是全文,并且其中的文件master可能与experiment有所不同,例如可以包含与其他分支合并的更改,这些更改可能会在文件中丢失,只是被复制。PS另一方面,他不希望合并,但据我所知git merge术语仅用于分支,而不用于特定文件,因此这里没有矛盾。
阿列克谢·马蒂安诺夫

Answers:


1599
git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"

另请参见git如何撤消对一个文件的更改?


更新2019年8月,Git 2.23

使用new git switchgit restore命令,将是:

git switch master
git restore -s experiment -- app.js

默认情况下,仅还原工作树。
如果您还想更新索引(意味着还原文件内容,通过一个命令将其添加到索引中):

git restore -s experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -WS -- app.js

正如雅库布·纳伦斯基(JakubNarębski)在评论中提到的那样:

git show experiment:path/to/app.js > path/to/app.js

除SO问题“ 如何从Git中的特定修订版本检索单个文件? ”中详细介绍的之外,该方法同样适用,您需要使用来自仓库的根目录的完整路径。
因此,Jakub在他的示例中使用了path / to / app.js。

正如Frosty在评论中提到的那样:

您只会得到app.js的最新状态

但是,对于git checkoutgit show,您实际上可以引用所需的任何修订版,如SO问题“ git gui中文件的git checkout修订版 ”所示:

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME

相同的是$ FILENAME是版本文件的完整路径

$REVISION可以如下所示git rev-parse

experiment@{yesterday}:app.js # app.js as it was yesterday 
experiment^:app.js            # app.js on the first commit parent
experiment@{2}:app.js         # app.js two commits ago

等等。

schmijos添加了评论

您也可以从隐藏处执行此操作:

git checkout stash -- app.js

如果您正在两个分支上并且不想提交,这将非常有用。


13
注意事项:您只会获得app.js的最新状态,而不会从实验分支中获取任何历史记录。

2
@ThomasReggi,您应该能够将文件从任何分支导入(签出)到任何当前分支。如果不能,那么这里可能是一个很好的问题,其中包含具体的详细信息,例如确切的错误消息以及所使用的Git和OS的版本。
VonC 2014年

2
在子目录中,您也可以使用experiment:./app.js。(您不必指定完整路径。)由于git给我提供了非常有用的错误消息,我了解到了这一点:“您的意思是'mybranch:full / path / to / my / file.xsl'又名'mybranch: ./file.xsl'?” 是的,我做到了!我认为我从未对致命错误消息感到高兴。
埃文·伦兹

1
@TomaszGandor是的,我在stackoverflow.com/a/21066489/6309中提到,其中git show不会修改索引,但是git checkout会修改索引。
VonC

1
@FriedBrice见我的回答:这几天,这将是git restore -s new-feature path/to/app.js
VonC

358

一切都简单得多,为此可以使用git checkout。

假设you're on master要获取app.js from new-feature分支,请执行以下操作:

git checkout new-feature path/to/app.js

// note that there is no leading slash in the path!

这将为您带来所需文件的内容。您可以像往常一样使用sha1的一部分代替 新功能的 分支名称来获取文件,就像在特定提交中一样。

注意new-feature必须是本地分支,而不是远程分支。


76
我发现始终指定原点很有帮助,git checkout origin/source_branch path/to/file因为如果您忽略了更新本地存储库的源分支,则可能会得到文件的旧版本……请问我怎么知道。;)
talyric,2014年

2
@Mymozaaa的问题没有提到遥控器,因此假设它是纯粹的本地仓库
Dmitry Avtonomov

1
此命令会带来文件的历史记录,还是只是文件的最新版本?
user1366265

1
@ user1366265此命令会将文件原样放置在您指定的特定提交中或您指定的分支头中。没有“文件的历史记录”之类的东西,所有历史记录信息仅存储在分支中。
德米特里·

3
这似乎会自动暂存已签出的文件。是否可以不进行分阶段执行相同操作?
bluenote10

44
git checkout branch_name file_name

例:

git checkout master App.java

如果您的分支机构名称中包含句点,则此方法将无效。

git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.

@PhilipRego这个答案是正确的。我猜您的分支中存在不同的大小写或标点符号,或者您只有一个远程分支,而没有本地分支。请参阅git checkout doc:git-scm.com/docs/git-checkout#Documentation/…–
Bret,

@Bret我发现分支名称中有句点时它不起作用。我建议进行编辑
菲利普·雷戈

这是最好的答案。我希望这个答案是最高的评分。目前最高的一个非常混乱,而不是简单
拉塞尔乐高

41

补充VonC和chhh的答案。

git show experiment:path/to/relative/app.js > app.js
# If your current working directory is relative than just use
git show experiment:app.js > app.js

要么

git checkout experiment -- app.js

2
凉!我讨厌指定长路径。--分支名称和路径之间的双破折号()是否可选?是否只是为了防止将以破折号开头的路径视为选项/开关?
Tomasz Gandor

老实说我不知道​​。在您指出之前,我什至没有注意到我已经忘记了双破折号。
AlexLordThorsen

6
@TomaszGandor --是可选的,但是它与避免分支名称冲突更有用。例如,git checkout -- foo表示“从HEAD检出文件foo”(即覆盖foo中的本地更改,即的子集git reset --hard),但git checkout foo可能表示 “我们去分支foo ”。
Alois Mahdal

8

或者,如果您希望来自另一个分支的所有文件:

git checkout <branch name> -- .

23
初始任务包含“仅一个文件”。
greatvovan

1
这将替换现有文件而不是合并文件
Amare

3
.产生了很大的不同:它不会移动到另一个分支,而是从那里复制所有文件,同时仍将您留在当前文件中。您可以从其他分支获取内容而无需进入。
Xeverous

4

查看github上的文件并从那里拉出

这是一种务实的方法,不能直接回答OP,但发现有些有用:

如果有问题的分支位于GitHub上,则可以使用GitHub提供的许多工具中的任何一个导航到所需的分支和文件,然后单击“原始”以查看纯文本,并(可选)将文本复制并粘贴为想要的。

我喜欢这种方法,因为它可以让您在将远程文件拉到本地计算机之前完整地查看它。


2
但是,复制和粘贴原始文件可能会导致git diff中不必要的字符更改。将文件直接保存到项目中以确保没有更改是更安全的。
菲利普·雷戈

0

如果要从特定提交(任何分支)中获取文件,请说06f8251f

git checkout 06f8251f path_to_file

例如,在Windows中:

git checkout 06f8251f C:\ A \ B \ C \ D \ file.h


1
感谢您抽出宝贵的时间来回答!但这不能回答问题,并且9年前已经发布了一个非常详细的好答案。无需质疑这个问题。
内森

这是一个有效的实际方案。答案正确地处理了分支,但是如何查看分支的特定提交呢?
arupjbasu

0

另一种方法是创建具有差异的补丁并将其应用到master分支(例如)中。假设开始使用app.js之前的最后一次提交是00000aaaaa,而包含所需版本的提交是00000bbbbb

您可以在实验分支上运行此代码:

git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git

这将创建一个文件,其中包含app.js的这两次提交之间的所有差异,您可以将其应用于任何位置。您可以将该文件保留在项目外部的任何位置

然后,在master中,您只需运行:

git apply ~/app_changes.git

现在您将看到项目中的更改,就像您手动进行的一样。


-3
git checkout master               -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.

git show <your-branch>:path/to/<your-file> 

希望这会帮助你。如果您有任何疑问,请告诉我。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.