我正在使用 Git 并在master
分支上工作。该分支有一个名为app.js
.
我有一个experiment
分支,我在其中进行了大量更改和大量提交。现在我想将所做的所有更改都带到app.js
fromexperiment
到master
分支。
我怎么做?
我再一次不想合并。我只想将所有更改app.js
从experiment
一个分支带到master
另一个分支。
我正在使用 Git 并在master
分支上工作。该分支有一个名为app.js
.
我有一个experiment
分支,我在其中进行了大量更改和大量提交。现在我想将所做的所有更改都带到app.js
fromexperiment
到master
分支。
我怎么做?
我再一次不想合并。我只想将所有更改app.js
从experiment
一个分支带到master
另一个分支。
git checkout master # first get back to master
git checkout experiment -- app.js # then copy the version of app.js
# from branch "experiment"
使用新的git switch
和git restore
命令,这将是:
git switch master
git restore --source experiment -- app.js
默认情况下,只恢复工作树。
如果您还想更新索引(意味着恢复文件内容,并在一个命令中将其添加到索引中):
git restore --source experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -SW -- app.js
正如Jakub Narębski在评论中提到的那样:
git show experiment:path/to/app.js > path/to/app.js
也可以工作,除了如 SO 问题“如何从 Git 中的特定修订版中检索单个文件? ”中详述的那样,您需要使用来自 repo 根目录的完整路径。
因此,Jakub 在他的示例中使用了 path/to/app.js。
正如Frosty在评论中提到的:
你只会得到 app.js 的最新状态
但是,对于git checkout
or git show
,您实际上可以引用您想要的任何修订,如 SO 问题“ git checkout revision of a file in git gui ”所示:
$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME
相同的是 $FILENAME 是版本化文件的完整路径。
$REVISION
可以如图所示git rev-parse
:
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
等等。
您也可以从隐藏处执行此操作:
git checkout stash -- app.js
如果您在两个分支上工作并且不想提交,这将非常有用。
一切都简单得多,为此使用 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!
这将为您带来所需文件的内容。您可以像往常一样使用 sha1 的一部分而不是 new-feature 分支名称来获取该特定提交中的文件。
注意:new-feature
需要是本地分支,而不是远程分支。
git checkout branch_name file_name
例子:
git checkout master App.java
如果您的分支名称中有句点,这将不起作用。
git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.
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
# 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
,这是您对当前签出分支的最新提交。因此,您也可以这样做来检查“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
# 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
我学到这一点的来源:@Jakub Narębski 的回答:git-checkout old revision of a file under a new name
git merge
或更改,该怎么办git cherry-pick
?git rebase
git revert
那么,在这种情况下,您最好执行以下操作。注意:要了解每个上下文中的提交哈希或分支--theirs
,--ours
请在此处查看我的答案:根据 Git,谁是“我们”,谁是“他们”?:
# 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
或者:
# 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
不要checkout
在这之前做上一节中的常规形式,除非那是你真正想做的。请参阅上面引用的我的答案中的“警告警告警告”部分:根据 Git,谁是“我们”,谁是“他们”?.
处理path does not have our version
或path 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
...运行上述命令时,您只需先访问git rm
这些文件,然后再次尝试git checkout --ours
orgit checkout --theirs
命令。有关这些命令的详细说明,请参阅我的答案,包括为您自动查找和删除那些错误文件的表单:git checkout --ours 当文件规范包含已删除文件时。
在这种情况下,这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"
有关更多详细信息,请参见我自己的答案:Why git can't do hard/soft resets by path?
git checkout
我在这里的回答中展示了更多这些示例:根据 Git,谁是“我们”,谁是“他们”?.要从另一个分支恢复文件,只需在工作分支中使用以下命令:
git restore -s my-other-branch -- ./path/to/file
该标志是您要从中提取文件的分支-s
的缩写。source
(选择的答案信息量很大,但也有点压倒性。)
或者,如果您想要来自另一个分支的所有文件:
git checkout <branch name> -- .
这是一种不直接回答 OP 的务实方法,但有些人发现它很有用:
如果有问题的分支在 GitHub 上,那么您可以使用 GitHub 提供的许多工具中的任何一个导航到所需的分支和文件,然后单击“原始”以查看纯文本,并(可选)将文本复制并粘贴为想要的。
我喜欢这种方法,因为它可以让您在将远程文件拉到本地计算机之前完整地查看远程文件。
如果您想要来自特定提交(任何分支)的文件,请说06f8251f
git checkout 06f8251f path_to_file
例如,在 Windows 上:
git checkout 06f8251f C:\A\B\C\D\file.h
另一种方法是创建具有差异的补丁并将其应用到主分支中。假设您开始使用 app.js 之前的最后一次提交是 00000aaaaa 并且包含您想要的版本的提交是 00000bbbbb
你在实验分支上运行它:
git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git
这将创建一个文件,其中包含 app.js 的这两个提交之间的所有差异,您可以将其应用到任何您想要的地方。您可以将该文件保存在项目之外的任何位置
然后,在 master 你只需运行:
git apply ~/app_changes.git
现在您将看到项目中的更改,就像您手动进行的一样。
对于所有喜欢避免未知 git 命令或害怕破坏某些东西的人来说,还有一个简单的解决方案:
可能需要比适当的 git 命令更长的时间......但它有效且易于理解
从另一个分支签出文件是一个简单的单行命令:
git checkout branch C:\path\to\file.cs
如果您想要多个文件
git checkout branch C:\path\to\file1.cs C:\path\to\file2.cs
git checkout master -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.
git show <your-branch>:path/to/<your-file>
希望这会帮助你。如果您有任何疑问,请告诉我。