How to get just one file from another branch
我正在使用git并在master branch上工作。这个分支有一个名为app.js的文件。
我有一个experiment分支,在其中我做了大量的更改和承诺。现在,我只想把所有对app.js所做的更改从experiment转到master分支。
我该怎么做?
我又一次不想合并。我只想把app.js的所有变化从experiment分公司带到master分公司。
- 这是如何将单个文件的版本从一个git分支复制到另一个git分支的副本?
- 例外答案和其他人今天回答如何复制文件的内容,这就是我找到那个答案时想要的。但是,如果读得准确,nick希望带来更改,而不是全文,master中的文件可能与experiment中的文件不同,例如可以包含从其他分支合并而来的更改,这些更改将在文件中丢失,只需复制。另一方面,他不想合并,但据我所知,git merge这个术语只用于分支机构,不用于具体文件,所以这里没有矛盾。
1 2 3
| git checkout master # first get back to master
git checkout experiment -- app.js # then copy the version of app.js
# from branch"experiment" |
另请参见Git如何撤消一个文件的更改?
作为Jakub Nar?BSKI在评论中提到:
1
| git show experiment:path/to/app.js > path/to/app.js |
号
除此之外,它也可以工作,正如so问题"如何从git中的特定修订中检索单个文件"中详述的那样。,您需要使用repo根目录的完整路径。因此,Jakub在其示例中使用的路径/to/app.js。
正如弗罗斯蒂在评论中提到的:
you will only get the most recent state of app.js
号
但是,对于git checkout或git show,您实际上可以引用您想要的任何修订,如问题"git gui中文件的git checkout revision"所示:
1 2
| $ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME |
相同的是$filename是版本化文件的完整路径。
$REVISION可以如git rev-parse所示:
1 2 3
| 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 |
。
等等。
施密霍斯在评论中补充道:
you also can do this from a stash:
1
| git checkout stash -- app.js |
This is very useful if you're working on two branches and don't want to commit.
号
- 一个注意事项:您将只获得app.js的最新状态,不会从实验分支中获得任何历史记录。
- 或git show experiment:path/to/app.js > app.js。
- 所以我不能将一个文件从master导入到另一个分支,只能从其他分支导入master。思想?
- @ThomasReggi您应该能够从任何分支导入(签出)文件到任何当前分支。如果不能,这是一个很好的问题,具体细节如准确的错误消息,以及使用的Git和OS版本。
- 我让它工作了,我想导入一个我没有从Github上下载的文件。抱歉@vonc!所以它只是导入同一个文件。
- 在子目录中,还可以使用experiment:./app.js。(您不必指定完整路径。)我之所以了解这一点,是因为Git给了我一条非常有用的错误消息:"您的意思是‘mybranch:full/path/to/my/file.xsl’aka‘mybranch:/file.xsl’?"是的,我做到了!我想我从来没有为一个致命的错误信息感到高兴过。
- @埃文伦茨听起来很棒!您使用的是什么版本的Git?
- @vehsakul语法用于检查任何分支上的文件:git checkout $REVISION -- $FILENAME。experiment@{yesterday}是指截至昨天在experiment分公司的版本,即使你在master分公司。
- 我看到签出文件会在这个操作之后立即添加到索引中(如"要提交的更改")。
- @Tomaszgandor是的,我提到在stackoverflow.com/a/21066489/6309中,git show不会修改索引,但是git checkout会修改索引。
- 你为什么要用--,我也没用过。我错过什么了吗?
- @wviana它将选项与参数分开:stackoverflow.com/a/1192194/6309
- 在师父那里,我试过以东十一〔七〕字,但它给了我以东十一〔八〕字。必须先做git checkout some_branch,然后做git checkout master,再做git checkout some_branch -- my.file,才能从分支机构获得该文件。
- @盖子可能是因为你只有原点/某个分支。
- @VONC是的,原点/某些分支工作。它还为我提供了分支上文件的最新版本,这正是我想要的。谢谢!
- 我想在这里提到,你也可以从藏匿处得到:以东十一〔十二〕号。如果您正在处理两个分支并且不想提交,那么这非常有用。
- @施密霍斯谢谢你。我已经把你的评论包括在回答中,以提高可见度。
- 那只是复制一个文件吗?如果我们合并会发生什么?
- @Terrytan"如果我们合并会发生什么?":如果手动复制分支中该文件的内容,则不会超过(或少于):如果两个分支中都没有进一步修改(针对该文件),合并将忽略该文件。
- @菲利普雷戈,我想看一个新的问题来说明这个案例:那样的话,我就知道该怎么解决了。
- 无法复制
- 我找到了。这应该包括在这个答案中。请注意,我得到了"无效的引用",但我能够获取分支。$git checkout issue/2020.07.04--pom.xml致命:无效引用:issue/2020.07.04$git fetch origin issue/2020.07.04 from example.com*branch issue/2020.07.04->fetch_head
- @菲利普雷戈有趣。对于测试,我仍然认为用一个单独的问题来详细说明这个bug(使用OS和Git版本)是有用的。一旦我们都明白了问题所在,我会编辑这个答案。
- Stack不允许我再发布问题。Git版本2.17.1.Windows.2 Windows 7
- 还是不行
- @正如我之前提到的,这将更好地作为一个新问题来解决。您可以考虑为此目的创建一个新帐户(稍后请求合并该新帐户)
一切都很简单,使用git checkout。
假设you're on master支,得到app.js from new-feature支:
1 2 3
| git checkout new-feature path/to/app.js
// note that there is no leading slash in the path! |
这将为您带来所需文件的内容。您可以像往常一样,使用sha1的一部分而不是新的功能分支名称来获取文件,因为它在那个特定的提交中是这样的。
- 我发现总是指定源代码git checkout origin/source_branch path/to/file很有帮助,因为如果您忽略了更新本地repo的源分支,您可能会得到文件的旧版本……问我怎么知道。;)
- 难道我们不应该用git checkout origin source_branch path/to/file把分支放到远程吗?所以这是文件的最后一个版本?有关这两个命令之间的区别,请参阅此链接:stackoverflow.com/questions/26125162/…
- @mymozaaa这个问题没有提到远程,因此假设它是纯粹的本地回购。
- 这个命令会带来文件的历史记录,还是只带来文件的最后一个版本?
- @用户1366265此命令将把文件放在指定的特定提交或指定的分支头中。没有"文件历史",所有历史信息只存储在分支中。
- @塔利里亚语-但如果你还没有拉或拿,你还是会被烤。在获取之后,最好还是执行git push . origin/otherbranch:otherbranch(在不签出的情况下更新本地分支,但仅用于快进)。
- 这似乎会自动暂存签出的文件。是否可以在不进行分段的情况下进行相同的操作?
对VONC和CHHH答案的补充。
1 2 3
| 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 |
。
或
1
| git checkout experiment -- app.js |
。
- 酷!我讨厌指定长路径。分支名称和路径之间的双破折号(--是可选的吗?它仅仅是为了防止以破折号开头的路径被视为选项/开关吗?
- 老实说,我不知道。直到你指出这一点,我才注意到我忘记了双破折号。
- git show branch:path这个。我最喜欢的新git命令。
- @Tomaszgandor的--是可选的,但是避免与分支名称冲突更有用。例如,git checkout -- foo表示"从head签出文件foo"(即覆盖foo中的本地更改,即git reset --hard的一个子集),但git checkout foo可能表示这一点或"让我们转到foo分支"。
1
| git checkout branch_name file_name |
。
例子:
1
| git checkout master App.java |
如果您的分支名称中有句点,这将不起作用。
1 2
| git checkout"fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git. |
。
- @菲利普雷戈这个答案是正确的。我猜你的分支中有不同的大写或标点符号,或者你只有一个远程分支而不是本地分支。参见git checkout文档:git scm.com/docs/git checkout documentation/…
- @布雷特,我发现当分支名称有句号时,它不起作用。我建议编辑一下
或者,如果您需要来自其他分支的所有文件:
1
| git checkout <branch name> -- . |
- 最初的问题包含"只有一个文件"。
- 这将替换现有文件,而不是合并
- 这个.有很大的不同:它不移动到另一个分支,而是从那里复制所有文件,同时仍将您留在当前的分支上。您可以从其他分支获取内容而不必进入它。
查看Github上的文件并从中拉出
这是一种务实的方法,它不会直接回答OP,但有些人认为这是有用的:
如果有问题的分支在Github上,那么您可以使用Github提供的许多工具中的任何一个导航到所需的分支和文件,然后单击"原始"查看纯文本,并(可选)根据需要复制和粘贴文本。
我喜欢这种方法,因为它允许您在将远程文件拖到本地计算机之前查看整个文件。
- 赞成票,因为只有工作回答我。
- 但是,复制和粘贴原始文件可能会导致Git diff中出现不需要的字符更改。直接将文件保存到项目中以确保没有更改更安全。