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

我有一个master分支,其中包含一个名为app.js的文件。我在experiment分支上对该文件进行了更改。

我只想将从experimentapp.js所做的更改应用到master分支。

1121343 次浏览
git checkout master               # first get back to mastergit checkout experiment -- app.js # then copy the version of app.js# from branch "experiment"

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


2019年8月更新,Git 2.23

使用新的#0#1命令,这将是:

git switch mastergit restore --source experiment -- app.js

默认情况下,只恢复工作树。
如果您也想更新索引(意味着恢复文件内容,在一个命令中将其添加到索引中):

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

JakubNarbski在评论中提到:

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

也可以,除了,如SO问题“如何从Git中的特定版本检索单个文件?”中详述的,您需要使用存储库根目录的完整路径。
因此Jakub在他的例子中使用的路径/to/app.js。

正如在评论中提到的:

你只会得到最新的app.js

但是,对于git checkoutgit show,您实际上可以引用任何您想要的版本,如SO问题“git gui中文件的git签出版本”所示:

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

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

$REVISION可以如#1所示:

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

诸如此类。

schmijos添加在评论

您也可以从stash中执行此操作:

git checkout stash -- app.js

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

一切都很简单,使用git签出。

假设#0分支,要得到#1分支做:

git checkout new-feature path/to/app.js
// note that there is no leading slash in the path!

这将为您带来所需文件的内容。您可以一如既往地使用部分sha1而不是新特性分支名称获取该文件,就像它在该特定提交中一样。

说明new-feature需要是当地分支,而不是远程分支。

补充VonC的和chhh的答案:

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

git checkout experiment -- app.js

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

git checkout <branch name> -- .
git checkout branch_name file_name

示例:

git checkout master App.java

如果您的分支名称中有句点,这将不起作用。

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

在github上查看文件并从那里提取

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

如果有问题的分支在GitHub上,那么您可以使用GitHub提供的许多工具中的任何一个导航到所需的分支和文件,然后单击“Raw”查看纯文本,并(可选)根据需要复制和粘贴文本。

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

如果您想要来自特定提交(任何分支)的文件,请说06f8251f

git checkout 06f8251f path_to_file

例如,在Windows上:

git checkout 06f8251f C:\A\B\C\D\file.h
git checkout master               -go to the master branch firstgit checkout <your-branch> -- <your-file> --copy your file data from your branch.
git show <your-branch>:path/to/<your-file>

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

另一种方法是创建一个带有差异的补丁并将其应用于master分支例如,假设你开始处理app.js之前的最后一次提交是00000aaaaa,包含你想要的版本的提交是00000bbbbb

你在实验分支上运行它:

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

这将为app.js创建一个包含这两个提交之间所有差异的文件,您可以在任何地方应用该文件

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

git apply ~/app_changes.git

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

要从另一个分支恢复文件,只需从您的工作分支使用以下命令:

git restore -s my-other-branch -- ./path/to/file

-s标志是source的缩写,即您要从其中提取文件的分支。

(选择的答案非常有用,但也有点压倒性。

所有关于检查git中的文件或目录

1.如何从另一个分支签出一个或多个文件目录或将哈希提交到您当前签出的分支:

# check out all files in <paths> from branch <branch_name>git checkout <branch_name> -- <paths>

来源:http://nicolasgallagher.com/git-checkout-specific-files-from-another-branch/

另见man git checkout

示例:

# Check out "somefile.c" from branch `my_branch`git checkout my_branch -- somefile.c
# Check out these 4 files from `my_branch`git checkout my_branch -- file1.h file1.cpp mydir/file2.h mydir/file2.cpp
# Check out ALL files from my_branch which are in# directory "path/to/dir"git checkout my_branch -- path/to/dir

如果你不指定,它的branch_name会自动被假定为HEAD,这是你对当前签出分支的最新提交。因此,你也可以这样做来签出“一些文件. c”并让它覆盖任何本地的、未提交的更改:

# Check out "somefile.c" from `HEAD`, to overwrite any local, uncommitted# changesgit checkout -- somefile.c
# Or check out a whole folder from `HEAD`:git checkout -- some_directory

2.更进一步:如何从任何分支签出任何文件或将哈希提交到计算机上的任何位置(非常有用!):

# General formgit show my_branch_or_commit_hash:my_file.cpp > any/path/my_file.cpp
# Example: check out `main.cpp` from 3 commits ago in your currently-checked-out# branch (3 commits prior to `HEAD`, or `HEAD~3`) into a temporary directorymkdir ../tempgit show HEAD~3:main.cpp > ../temp/main_old.cpp

我学到这个的来源:@Jakub Narbski的答案:git-check out新名称下文件的旧版本

3.如果您正在解决git mergegit cherry-pickgit rebasegit revert更改怎么办?

在这种情况下,你最好做到以下几点。

# Keep `--theirs` for all conflicts within this filegit checkout --theirs -- path/to/some/file# OR: keep `--ours` for all conflicts within this filegit checkout --ours -- path/to/some/file

或:

# Keep `--theirs` for all conflicts within files inside this dirgit checkout --theirs -- path/to/some/dir# OR: keep `--ours` for all conflicts within files inside this dirgit checkout --ours -- path/to/some/dir

在此之前,不要做上一节中的常规#0表单,除非这是你真正想做的。参见上面引用的我的答案中的"警告警告警告"部分:根据Git,谁是“我们”,谁是“他们”?

处理path does not have our versionpath does not have their version错误:

如果你看到这样的错误:

error: path 'path/to/some/dir/file1.cpp' does not have our version# ORerror: path 'path/to/some/dir/file1.cpp' does not have their version

…当运行上面的命令时,您只需要先git rm这些文件,然后再次尝试git checkout --oursgit checkout --theirs命令。有关这些命令的详细说明,请参阅我的答案,包括一个自动查找和删除这些错误文件的表单:当文件规范包括已删除的文件时,我们的git签出

4.如果您想在另一个提交或分支中将某个文件或目录的状态重置为完全匹配该文件或目录的状态怎么办?

在这种情况下,git checkout my_branch -- some_file_or_dir是不够的,因为如果您在指定目录中的文件存在于当前签出的分支或提交中但不存在于my_branch中,那么您希望它们在本地被删除,但是git checkout不会删除任何存在于本地但不在指定提交上的文件,相反,它只在本地覆盖个文件及其来自指定提交的版本。因此,在本地也删除个不应该在那里的文件,所以你最终在本地得到的是你在提交或分支my_branch上拥有的内容的精确副本,你必须执行以下操作:

# How to "hard reset" "path/to/some/file_or_dir" to its state exactly as it was# at commit or branch `my_branch`## WARNING: `git status` should be TOTALLY CLEAN before beginning this process!# Otherwise, you risk PERMANENTLY LOSING any uncommitted changes shown by# `git status`, since `git clean -fd` 'f'orce deletes ALL files# and 'd'irectories which are in your current working tree (file system), but# which are *not* in the path you specify below in commit or branch `my_branch`.# Therefore, anything NOT already committed gets **permanently lost** as though# you had used `rm` on it!
git reset my_branch -- path/to/some/file_or_dirgit checkout-index -fagit clean -fd  # SEE WARNING ABOVE!git commit -m "hard reset path/to/some/file_or_dir to its state \as it was at my_branch"

在这里看到我自己的答案,了解更多细节:为什么git不能通过路径进行硬/软重置?

另见:

  1. 快速链接到我的答案我经常引用并认为是“git基础”
    1. 在git中从另一个分支创建分支的各种方法
    2. 关于在git中检查文件或目录的所有内容
    3. 根据Git,谁是"我们",谁是"他们"?
  2. 我在这里的答案中展示了更多这些git checkout的例子:根据Git,谁是“我们”,谁是“他们”?
  3. [我的答案“如何通过路径进行--soft或--hard git重置”]为什么git不能通过路径进行硬/软重置?
  4. git-check out新名称下文件的旧版本
  5. [我的回答]当文件规范包括已删除的文件时,我们的git签出
  6. [我的回答]使用git,如何将工作树(本地文件系统状态)重置为索引的状态(“暂存”文件)?

从另一个分支签出文件是一个简单的单行命令:

git checkout branch C:\path\to\file.cs

如果您想要多个文件

git checkout branch C:\path\to\file1.cs C:\path\to\file2.cs

对于所有喜欢避免未知git命令或害怕破坏某些东西的人来说,还有一个简单的解决方案:

  1. 签出到文件所在的分支
  2. 将该文件复制到您计算机上的其他位置
  3. 签出到文件需要到达的分支
  4. 将文件粘贴到位

可能比适当的git命令需要更长的时间……但它有效且易于理解

git checkout <branch_name> -- <paths>

更多信息