如何从 Git 中的特定修订版检索单个文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/610208/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:13:56  来源:igfitidea点击:

How to retrieve a single file from a specific revision in Git?

gitsingle-file

提问by Milan Babu?kov

I have a Git repository and I'd like to see how some files looked a few months ago. I found the revision at that date; it's 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8. I need to see what one file looks like, and also save it as a ("new") file.

我有一个 Git 存储库,我想看看几个月前一些文件的样子。我在那个日期找到了修订版;它是27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8。我需要查看一个文件的外观,并将其另存为(“新”)文件。

I managed to see the file using gitk, but it doesn't have an option to save it. I tried with command-line tools, the closest I got was:

我设法使用 看到了该文件gitk,但它没有保存它的选项。我尝试使用命令行工具,最接近的是:

git-show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8 my_file.txt

However, this command shows a diff, and not the file contents. I know I can later use something like PAGER=catand redirect output to a file, but I don't know how to get to the actual file content.

但是,此命令显示差异,而不是文件内容。我知道我以后可以使用类似的东西PAGER=cat并将输出重定向到文件,但我不知道如何获取实际的文件内容。

Basically, I'm looking for something like svn cat.

基本上,我正在寻找类似svn cat 的东西。

采纳答案by VonC

To complete your own answer, the syntax is indeed

要完成您自己的答案,语法确实是

git show object
git show $REV:$FILE
git show somebranch:from/the/root/myfile.txt
git show HEAD^^^:test/test.py

The command takes the usual style of revision, meaning you can use any of the following:

该命令采用通常的修订风格,这意味着您可以使用以下任何一种:

  1. branch name (as suggestedby ash)
  2. HEAD+ x number of ^characters
  3. The SHA1 hash of a given revision
  4. The first few (maybe 5) characters of a given SHA1 hash
  1. 分支名称(由ash建议
  2. HEAD+ x^字符数
  3. 给定修订的 SHA1 哈希
  4. 给定 SHA1 哈希的前几个(可能是 5 个)字符

TipIt's important to remember that when using "git show", always specify a path from the root of the repository, not your current directory position.

提示 请务必记住,使用“ git show”时,请始终指定从存储库根目录开始的路径,而不是您当前的目录位置。

(Although Mike Moreartymentions that, at least with git 1.7.5.4, you can specify a relative path by putting "./" at the beginning of the path -- for example:

(尽管Mike Morearty提到,至少在 git 1.7.5.4 中,您可以通过./在路径开头放置“ ”来指定相对路径——例如:

git show HEAD^^:./test.py

)

)



With Git 2.23+ (August 2019), you can also use git restorewhich replaces the confusing git checkoutcommand

使用 Git 2.23+(2019 年 8 月),您还可以使用git restorewhich 替换令人困惑的git checkout命令

git restore -s <SHA1>     -- afile
git restore -s somebranch -- afile

That would restore on the working tree only the file as present in the "source" (-s)commit SHA1 or branch somebranch.
To restore also the index:

这将仅在工作树上恢复“源”(-s提交 SHA1 或分支中存在的文件somebranch
还要恢复索引:

git restore -s <SHA1> -SW -- afile

(-SW: short for --staged --worktree)

( -SW: 简称--staged --worktree)



Before git1.5.x, that was done with some plumbing:

在 git1.5.x 之前,这是通过一些管道完成的:

git ls-tree <rev>
show a list of one or more 'blob' objects within a commit

git ls-tree <rev>
在提交中显示一个或多个“blob”对象的列表

git cat-file blob <file-SHA1>
cat a file as it has been committed within a specific revision (similar to svn cat). use git ls-tree to retrieve the value of a given file-sha1

git cat-file blob <file-SHA1>
cat 文件,因为它已在特定修订版中提交(类似于 svn cat)。使用 git ls-tree 检索给定 file-sha1 的值

git cat-file -p $(git-ls-tree $REV $file | cut -d " " -f 3 | cut -f 1)::

git-ls-tree lists the object ID for $file in revision $REV, this is cut out of the output and used as an argument to git-cat-file, which should really be called git-cat-object, and simply dumps that object to stdout.

git-ls-tree 列出了修订版 $REV 中 $file 的对象 ID,这是从输出中切出并用作 git-cat-file 的参数,它实际上应该称为 git-cat-object,并且只是转储该对象到标准输出。



Note: since Git 2.11 (Q4 2016), you can apply a content filter to the git cat-fileoutput!

注意:从 Git 2.11(2016 年第四季度)开始,您可以对git cat-file输出应用内容过滤器!

See commit 3214594, commit 7bcf341(09 Sep 2016), commit 7bcf341(09 Sep 2016), and commit b9e62f6, commit 16dcc29(24 Aug 2016) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster--in commit 7889ed2, 21 Sep 2016)

请参阅Johannes Schindelin ( ) 的commit 3214594commit 7bcf341(09 Sep 2016)、commit 7bcf341(09 Sep 2016) 和commit b9e62f6commit 16dcc29(24 Aug 2016 )(由Junio C Hamano合并-- --提交 7889ed2 中,2016 年 9 月 21 日)dscho
gitster

cat-file: support --textconv/--filtersin batch mode

Even though "git hash-objects", which is a tool to take an on-filesystem data stream and put it into the Git object store, allowed to perform the "outside-world-to-Git" conversions (e.g. end-of-line conversions and application of the clean-filter), and it had the feature on by default from very early days, its reverse operation "git cat-file", which takes an object from the Git object store and externalize for the consumption by the outside world, lacked an equivalent mechanism to run the "Git-to-outside-world"

cat-file: 支持--textconv/--filters批处理模式

尽管 " git hash-objects" 是一种获取文件系统数据流并将其放入 Git 对象存储的工具,但允许执行“外部世界到 Git”的转换(例如行尾转换和应用程序的清洁过滤器),并且它从很早的时候就默认启用了该功能,它的反向操作“ git cat-file”从Git对象存储中获取对象并外部化以供外部世界使用,缺乏等效的机制运行“Git 到外部世界”

git config diff.txt.textconv "tr A-Za-z N-ZA-Mn-za-m <"
git cat-file --textconv --batch

Note: "git cat-file --textconv" started segfaulting recently (2017), which has been corrected in Git 2.15 (Q4 2017)

注意:“ git cat-file --textconv”最近开始进行段错误(2017 年),这已在 Git 2.15(2017 年第四季度)中得到纠正

See commit cc0ea7c(21 Sep 2017) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster--in commit bfbc2fc, 28 Sep 2017)

请参阅Jeff King ( )提交的 cc0ea7c(2017 年 9 月 21 日(由Junio C Hamano合并-- --提交 bfbc2fc,2017 年 9 月 28 日)peff
gitster



Note that to override/replacea file with a past content, you should not use the confusing git checkoutcommandanymore, but git restore(Git 2.23+, August 2019)

请注意,要覆盖/替换具有过去内容的文件,您不应再使用混淆git checkout命令,但是git restore(Git 2.23+,2019 年 8 月)

git restore -s <SHA1> -- afile

That would restore on the working tree only the file as present in the "source" (-s) commit SHA1.
To restore also the index:

这将仅在工作树上恢复“源”(-s)提交 SHA1 中存在的文件。
还要恢复索引:

git restore -s <SHA1> -SW -- afile

(-SW: short for --staged --worktree)

( -SW: 简称--staged --worktree)

回答by c-a

If you wish to replace/overwritethe content of a file in your current branch with the content of the file from a previous commit or a different branch, you can do so with these commands:

如果您希望使用来自先前提交或不同分支的文件内容替换/覆盖当前分支中的文件内容,您可以使用以下命令:

git checkout 08618129e66127921fbfcbc205a06153c92622fe path/to/file.txt

or

或者

git checkout mybranchname path/to/file.txt

You will then have to commit those changes in order for them to be effective in the current branch.

然后,您必须提交这些更改,以便它们在当前分支中生效。

回答by Milan Babu?kov

You need to provide the full path to the file:

您需要提供文件的完整路径:

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:full/repo/path/to/my_file.txt

回答by jmarceli

The easiestway is to write:

最简单的办法就是写:

git show HASH:file/path/name.ext > some_new_name.ext

where:

在哪里:

  • HASHis the Git revision SHA-1 hash number
  • file/path/name.extis name of the file you are looking for
  • some_new_name.extis path and name where the old file should be saved
  • HASH是 Git 修订版 SHA-1 哈希数
  • file/path/name.ext是您要查找的文件的名称
  • some_new_name.ext是应该保存旧文件的路径和名称

Example

例子

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:my_file.txt > my_file.txt.OLD

This will save my_file.txtfrom revision 27cf8eas a new file with name my_file.txt.OLD

这会将修订版27cf8e中的my_file.txt保存为名为my_file.txt.OLD的新文件

It was tested with Git 2.4.5.

它使用 Git 2.4.5 进行了测试。

If you want to retrieve deletedfile you can use HASH~1(one commit before specified HASH).

如果要检索已删除的文件,可以使用HASH~1(在指定 HASH 之前提交一次)。

EXAMPLE:

例子:

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8~1:deleted_file.txt > deleted_file.txt

回答by Alessandro Jacopson

In Windows, with Git Bash:

在 Windows 中,使用 Git Bash:

  • in your workspace, change dir to the folder where your file lives
  • git show cab485c83b53d56846eb883babaaf4dff2f2cc46:./your_file.ext > old.ext
  • 在您的工作区中,将 dir 更改为您的文件所在的文件夹
  • git show cab485c83b53d56846eb883babaaf4dff2f2cc46:./your_file.ext > old.ext

回答by Mr_and_Mrs_D

And to nicely dump it into a file (on Windows at least) - Git Bash:

并将其很好地转储到文件中(至少在 Windows 上)-Git Bash:

$ echo "`git show 60d8bdfc:src/services/LocationMonitor.java`" >> LM_60d8bdfc.java

The "quotes are needed so it preserves newlines.

"需要引号,因此保留了换行。

回答by Adrian Gunawan

This will help you get all deleted files between commits without specifying the path, useful if there are a lot of files deleted.

这将帮助您在提交之间获取所有已删除的文件而无需指定路径,如果删除了大量文件,则非常有用。

git diff --name-only --diff-filter=D $commit~1 $commit | xargs git checkout $commit~1

回答by jsina

git checkout {SHA1} -- filename

this command get the copied file from specific commit.

此命令从特定提交中获取复制的文件。

回答by rocketInABog

Get the file from a previous commit through checking-out previous commit and copying file.

通过检出先前的提交和复制文件,从先前的提交中获取文件。

  • Note which branch you are on: git branch
  • Checkout the previous commit you want: git checkout 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8
  • Copy the file you want to a temporary location
  • Checkout the branch you started from: git checkout theBranchYouNoted
  • Copy in the file you placed in a temporary location
  • Commit your change to git: git commit -m "added file ?? from previous commit"
  • 注意你所在的分支:git branch
  • 签出您想要的上一个提交: git checkout 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8
  • 将你想要的文件复制到一个临时位置
  • 签出您开始的分支: git checkout theBranchYouNoted
  • 复制您放置在临时位置的文件
  • 将您的更改提交到 git:git commit -m "added file ?? from previous commit"