1173

我有两个完全合并在一起的分支。

但是,合并完成后,我意识到一个文件已被合并弄乱了(其他人做了自动格式化,gah),在另一个分支中更改为新版本会更容易,并且然后在将它带入我的分支后重新插入我的一行更改。

那么在 Git 中最简单的方法是什么?

4

7 回答 7

1979

从您希望文件结束的分支运行它:

git checkout otherbranch myfile.txt

一般公式:

git checkout <commit_hash> <relative_path_to_file_or_dir>
git checkout <remote_name>/<branch_name> <file_or_dir>

一些注释(来自评论):

  • 使用提交哈希,您可以从任何提交中提取文件
  • 这适用于文件和目录
  • 覆盖文件myfile.txtmydir
  • 通配符不起作用,但相对路径可以
  • 可以指定多个路径

替代:

git show commit_id:path/to/file > path/to/file
于 2008-11-21T04:31:21.363 回答
121

我会使用git restore(自 Git 2.23 起可用):

git restore --source otherbranch path/to/myfile.txt


为什么比其他选择更好?

  • 默认情况下git restore只修改工作目录中的文件。

git checkout otherbranch -- path/to/myfile.txt将文件复制到工作目录(磁盘上的文件),但也复制到暂存区。这与您手动复制此文件并git add在其上执行的效果相似。git restore默认情况下仅更改工作目录。

要获得与您相同的结果,git checkout otherbranch -- path/to/myfile.txt您可以编写git restore --source otherbranch --staged --worktree path/to/myfile.txt

  • 默认情况下git restore,当其他分支中缺少文件时,从工作目录中删除文件

git restore可用于恢复整个文件夹git restore --source otherbranch path/to/dir。您可以执行类似的操作,git checkoutgit restore默认情况下会删除otherbranch. 获取git checkout行为使用--overlay选项。

例如,如果文件otherbranch少于当前工作目录中的文件(并且这些文件被跟踪),则没有--overlay选项git restore将删除它们。但这是很好的默认行为,您很可能希望目录状态“与 in 相同otherbranch”,而不是“与 in 相同,otherbranch但带有我当前分支的其他文件”。

要获得与您相同的结果,git checkout otherbranch -- path/to/dir您可以编写git restore --source otherbranch --staged --worktree --overlay path/to/dir

  • git restore不使用 shell 重定向来创建文件(Powershell 唯一的问题)

git show otherbranch:path/to/myfile.txt > path/to/myfile.txt使用标准外壳重定向。如果您使用 PowerShell,那么文本编码可能会出现问题,或者如果它是二进制文件,您可能会得到损坏的文件。git restore更改文件全部由可执行git文件完成。

于 2020-03-25T18:52:53.250 回答
91

我最终在类似的搜索中遇到了这个问题。就我而言,我希望将另一个分支中的文件提取到与文件原始位置不同的当前工作目录中。答案

git show TREEISH:path/to/file > path/to/local/file
于 2011-08-17T20:38:03.420 回答
52

使用结帐命令:

  git diff --stat "$branch"
  git checkout --merge "$branch" "$file"
  git diff --stat "$branch"
于 2010-03-06T14:30:51.000 回答
27
  1. 确保您在需要文件副本的分支中。

    例如:我想要master中的子分支文件,所以你需要checkout或者应该在master中git checkout master

  2. 现在从 sub 分支中单独检查特定文件到master

     git checkout sub_branch file_path/my_file.ext
    

    sub_branch意味着您拥有该文件的位置,后跟您需要复制的文件名。

于 2017-06-29T08:47:44.953 回答
21

按照madlep 的回答,您也可以使用目录 blob 从另一个分支复制一个目录。

git checkout other-branch app/**

至于 OP 的问题,如果您只更改了一个文件,这将正常工作。

于 2015-06-06T21:29:37.257 回答
5

请注意,在接受的答案中,第一个选项从另一个分支暂存整个文件(就像git add ...已经执行过的一样),第二个选项只会导致复制文件,但不会暂存更改(就像你有只是手动编辑了文件并且有显着的差异)。

Git 从另一个分支复制文件而不暂存它

变更阶段(例如git add filename)

$ git checkout directory/somefile.php feature-B

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   directory/somefile.php

未完成的更改(未暂存或提交):

$ git show feature-B:directory/somefile.php > directory/somefile.php

$ git status
On branch feature-A
Your branch is up-to-date with 'origin/feature-A'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   directory/somefile.php

no changes added to commit (use "git add" and/or "git commit -a")
于 2019-05-08T17:00:40.077 回答