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

Nic*_*ilt 1154 git git-checkout

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

我有一个experiment分支,我做了一堆变更和大量的提交.现在我希望把做只对所有变化app.jsexperimentmaster分支.

我怎么做?

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

Von*_*onC 1472

git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"
Run Code Online (Sandbox Code Playgroud)

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

正如JakubNarębski在评论中提到的那样:

git switch master
git restore -s experiment -- app.js
Run Code Online (Sandbox Code Playgroud)

也可以工作,除了如SO问题" 如何从Git中的特定修订中检索单个文件? "中详述的那样,您需要使用repo根目录中的完整路径.
因此,Jakub在他的例子中使用了路径/ to/app.js.

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

你只会获得app.js的最新状态

但是,对于git switch或者git restore,您实际上可以引用您想要的任何修订,如SO问题" git gui中文件的git checkout修订版 "所示:

git restore -s experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -WS -- app.js
Run Code Online (Sandbox Code Playgroud)

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

git checkout可以如下所示git show:

git show experiment:path/to/app.js > path/to/app.js
Run Code Online (Sandbox Code Playgroud)

等等.

schmijos 在评论中补充道:

你也可以从藏匿处做到这一点:

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME
Run Code Online (Sandbox Code Playgroud)

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

  • 或者`git show experiment:path/to/app.js> app.js` (48认同)
  • 一个注意事项:您将只获得最新的app.js状态,您将无法从实验分支中获取任何历史记录. (12认同)
  • 为什么要用`--`,我没有用它也做了同样的事情。我错过了什么吗? (3认同)
  • @wviana它将选项与参数分开:http://stackoverflow.com/a/1192194/6309 (3认同)
  • @ThomasReggi你应该能够将文件从任何分支导入(签出)到任何当前分支.如果你不能,这可以是一个很好的问题在这里问,具体的细节,如确切的错误信息,以及使用的Git和操作系统的版本. (2认同)
  • 在子目录中,您也可以使用`experiment:./ app.js`。(您不必指定完整路径。)由于git给我提供了非常有用的错误消息,我了解到了这一点:“您的意思是'mybranch:full / path / to / my / file.xsl'又名'mybranch: ./file.xsl'?” 是的,我做到了!我认为我从未对致命错误消息感到高兴。 (2认同)
  • @TomaszGandor 是的,我在 http://stackoverflow.com/a/21066489/6309 中提到过,其中 git show 不会修改索引,但 git checkout 会修改索引。 (2认同)

Dmi*_*mov 323

一切都更简单,使用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!
Run Code Online (Sandbox Code Playgroud)

这将为您带来所需文件的内容.您可以像往常一样使用sha1的一部分而不是 新功能 分支名来获取该特定提交中的文件.

  • 我发现始终指定源`git checkout origin/source_branch path/to/file`是有帮助的,因为如果你忽略了更新本地仓库的源分支,你可能会得到一个旧版本的文件...问我我怎么知道 ;) (66认同)
  • @Mymozaaa这个问题没有提到遥控器,因此假设它是一个纯粹的本地回购 (2认同)
  • 该命令会带来文件的历史记录,还是仅带来文件的最后版本? (2认同)
  • @user1366265 此命令会将文件按原样放在您指定的特定提交或您指定的分支的头中。没有“一个文件的历史”这样的东西,所有的历史信息都只存储在分支中。 (2认同)
  • 这似乎会自动暂存已签出的文件。是否可以不进行分阶段执行相同操作? (2认同)

Ale*_*sen 35

补充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
Run Code Online (Sandbox Code Playgroud)

要么

git checkout experiment -- app.js
Run Code Online (Sandbox Code Playgroud)

  • @TomaszGandor` - `是可选的,但避免与分支名称冲突更有用.例如,`git checkout - foo`表示"从HEAD中检出文件foo"(即覆盖*foo*中的局部变化,即`git reset --hard`的子集),但是`git checkout foo`可能意味着*或*"让我们去分支*foo*". (5认同)
  • 凉!我讨厌指定长路径.分支名称和路径之间的双短划线(` - `)是可选的吗?是否只是为了防止以短划线开头的路径被视为选项/开关? (2认同)

小智 30

git checkout branch_name file_name
Run Code Online (Sandbox Code Playgroud)

例:

git checkout master App.java
Run Code Online (Sandbox Code Playgroud)


Gab*_*les 13

所有关于检出文件或目录 git

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

# check out all files in <paths> from branch <branch_name>
git checkout <branch_name> -- <paths>
Run Code Online (Sandbox Code Playgroud)

来源: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
Run Code Online (Sandbox Code Playgroud)

如果您没有指定,branch_name它会自动假定为HEAD,这是您对当前检出分支的最新提交。所以,你也可以这样做来检查“somefile.c”并让它覆盖任何本地的、未提交的更改:

# Check out "somefile.c" from `HEAD`, to overwrite any local, uncommitted
# changes
git checkout -- somefile.c

# Or check out a whole folder from `HEAD`:
git checkout -- some_directory
Run Code Online (Sandbox Code Playgroud)

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

# General form
git 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 directory
mkdir ../temp
git show HEAD~3:main.cpp > ../temp/main_old.cpp
Run Code Online (Sandbox Code Playgroud)

我学到的来源:@Jakub Nar?bski's answer to: git-checkout old revision of a file at a new name

3.如果你在解决中部是git mergegit cherry-pickgit rebase,或git revert改变?

那么,在这种情况下,你最好这样做:

# Keep `--theirs` for all conflicts within this file
git checkout --theirs -- path/to/some/file
# OR: keep `--ours` for all conflicts within this file
git checkout --ours -- path/to/some/file
Run Code Online (Sandbox Code Playgroud)

或者:

# Keep `--theirs` for all conflicts within files inside this dir
git checkout --theirs -- path/to/some/dir
# OR: keep `--ours` for all conflicts within files inside this dir
git checkout --ours -- path/to/some/dir
Run Code Online (Sandbox Code Playgroud)

checkout在此之前不要使用上一节中的常规形式,除非这是您真正想做的。请参阅我的回答中的“警告警告”部分:根据 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
# OR
error: path 'path/to/some/dir/file1.cpp' does not have their version
Run Code Online (Sandbox Code Playgroud)

...运行上述命令时,您只需git rm要先访问这些文件,然后再次尝试git checkout --oursorgit checkout --theirs命令。有关这些命令的详细说明,请参阅我的回答,包括自动查找和删除这些错误文件的表单:git checkout --ours when file spec 包含已删除的文件

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

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

git reset my_branch -- path/to/some/file_or_dir
git checkout-index -fa
git clean -fd
git commit -m "hard reset path/to/some/file_or_dir to its state \
as it was at my_branch"
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请在此处查看我自己的答案:Why git can't do hard/soft resets by path? .

也可以看看:

  1. git checkout在这里的回答中展示了更多这样的例子:根据 Git,谁是“我们”,谁是“他们”?.
  2. [我对“如何按路径执行 --soft 或 --hard git reset”的回答]为什么 git 不能按路径执行硬/软重置?
  3. git-checkout 以新名称对文件的旧版本
  4. [我的回答] git checkout --ours 当文件规范包含已删除的文件时
  5. [我的回答]使用 git,如何将工作树(本地文件系统状态)重置为索引(“暂存”文件)的状态?

  • 警告!!在没有先了解它会做什么的情况下,永远不要执行“git clean -fd”。幸运的是,Jetbrains 为我保留了这些文件的备份。想一想,`\rm -rf *`... (2认同)
  • @jtlz2,我在该代码上方的注释中添加了一个长警告块。这涵盖了吗? (2认同)

Con*_*ith 11

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

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

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

(所选择的答案信息量很大,但也有点压倒性。)


aru*_*asu 7

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

git checkout 06f8251f path_to_file
Run Code Online (Sandbox Code Playgroud)

例如,在 Windows 上:

git checkout 06f8251f C:\A\B\C\D\file.h
Run Code Online (Sandbox Code Playgroud)

  • 这是一个有效的实际场景。答案正确地处理了分支,但是查看分支的特定提交又如何呢? (4认同)

Pra*_*vin 7

git checkout <branch_name> -- <paths>
Run Code Online (Sandbox Code Playgroud)

更多信息


Jes*_*ter 6

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

git checkout <branch name> -- .
Run Code Online (Sandbox Code Playgroud)

  • 我猜因为最初的queston包含"只有一个文件". (22认同)
  • 这个`.`产生了很大的不同:它不是移动到另一个分支,而是从那里复制所有文件,同时仍然让你在当前的文件上.你从其他分支获得内容而不进入它. (3认同)

fea*_*ool 5

查看 GitHub 上的文件并从那里提取它

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

如果相关分支位于 GitHub 上,那么您可以使用 GitHub 提供的众多工具导航到所需的分支和文件,然后单击“原始”查看纯文本,并(可选)将文本复制并粘贴为想要的。

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

  • 然而,复制并粘贴原始文件可能会导致 git diff 中出现不需要的字符更改。将文件直接保存到项目中以确保不发生更改会更安全。 (2认同)

归档时间:

查看次数:

512587 次

最近记录:

6 年,3 月 前