我有两个完全合并在一起的分支。
但是,合并完成后,我意识到一个文件已被合并弄乱了(其他人做了自动格式化,gah),在另一个分支中更改为新版本会更容易,并且然后在将它带入我的分支后重新插入我的一行更改。
那么在 Git 中最简单的方法是什么?
git restore --source otherbranch path/to/myfile.txt
(参见 the answer 中的解释)。
从您希望文件结束的分支运行它:
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.txt 和 mydir
通配符不起作用,但相对路径可以
可以指定多个路径
替代:
git show commit_id:path/to/file > path/to/file
我会使用 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 checkout
执行类似的操作,但默认情况下 git restore
将删除 otherbranch
上丢失的文件。要获得 git checkout
行为,请使用 --overlay
选项。
例如,如果 otherbranch
上的文件少于当前工作目录中的文件(并且这些文件被跟踪),没有 --overlay
选项 git restore
将删除它们。但这是很好的默认行为,您很可能希望目录状态“与 otherbranch
相同”,而不是“与 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,那么文本编码可能会出现问题,或者如果它是 binary,您可能会得到损坏的文件。使用 git restore
更改文件全部由 git
可执行文件完成。
git restore
方法可以将文件从源分支复制到目标分支上的 new 文件?使用 git show 我可以使用 shell 重定向 (git show otherbranch:path/to/file1.txt > path/to/file2.txt
) 来执行此操作,但由于您提到的原因,我想避免 shell 重定向。
git restore
中获得它的机会不大(但谁知道;))。这个重定向问题基本上是 Powershell 问题,不确定是否有任何其他 shell 有问题。我通常会回到需要使用“git show
with redirection”命令的“git bash”甚至“cmd”。或者使用 GitExtensions 之类的 GUI,您可以在其中浏览提交的文件树并在任何文件上单击“另存为”。
git restore --source=otherbranch path/to/myfile.txt
优于 git restore --source otherbranch path/to/myfile.txt
原因是在第二种情况下,tab
列出可用分支不起作用。
checkout
时代”的回复🙂
我最终在类似的搜索中遇到了这个问题。就我而言,我希望将另一个分支中的文件提取到与文件原始位置不同的当前工作目录中。 Answer:
git show TREEISH:path/to/file > path/to/local/file
git diff <other branch> <path to file>
效果很好。
使用结帐命令:
git diff --stat "$branch"
git checkout --merge "$branch" "$file"
git diff --stat "$branch"
git diff
支持一个 --stat
参数,它基本上与 diffstat 做同样的事情。
确保您在需要文件副本的分支中。比如:我想要master里面的sub分支文件,所以你需要checkout还是应该在master里面 git checkout master 现在把你想要的具体文件单独从sub分支里面check out到master里面, git checkout sub_branch file_path/my_file.ext 这里是sub_branch表示您拥有该文件的位置,后跟需要复制的文件名。
在 madlep's answer 之后,您还可以使用目录 blob 从另一个分支复制一个目录。
git checkout other-branch app/**
至于 OP 的问题,如果您只更改了一个文件,这将正常工作。
origin/other-branch
来引用 repo 分支。基本,但咬我。 (答案很好 - 无需编辑)
请注意,在接受的答案中,第一个选项 stages 来自另一个分支的整个文件(如 git add ...
已执行),第二个选项只会导致复制文件,但不会'不要暂存更改(就好像您刚刚手动编辑了文件并且有明显的差异一样)。
Git copy file from another branch without staging it
变更阶段(例如 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")
抱歉,没有人提到在恢复文件之前你真的想预览与该分支相关的本地更改,所以:
git diff <other-branch-name> -- <filename>
然后,当您接受丢失(覆盖)时,您可以遵循:
git restore --source <other-branch-name> <filename>
or
git checkout <other-branch-name> <filename>
''
将它们包装起来,这样它们就不会被 shell 解释。