如何在Git存储库中获取文件的旧版本副本?

74

我有一个从多个提交之前的 .tex 文件版本,我想获取一份副本。我有该文件所需版本的 SHA1 哈希值。我不想替换当前版本的文件,而是想要一个单独的副本,反映其旧版本的状态。

很多类似的问题建议使用 git checkout <sha1> -- file.tex,但这只会不断给出 "error: pathspec 'file.tex' did not match any file(s) known to git." 的错误信息。

我感兴趣的文件最初存在于存储库的顶层目录。我目前在存储库的子目录中尝试运行此命令,以便在子目录中获取 file.tex 的旧版本。

这可行吗? 我该如何做?


4
复制当前文件,并运行 git checkout <commit-id> file.ext 命令? - adamdunson
5
可能是如何使用Git快速查看文件的旧版本?的重复问题。 - Ciro Santilli OurBigBook.com
3个回答

109
你可以使用 git cat-file 命令将文件的内容输出到标准输出,并将其重定向到你想要的目标位置:
git cat-file -p <sha1>:./file.tex > wherever.tex

如果您在存储库的子目录中,则 ./ 是必需的,如果您在存储库的顶级,则可以省略它。此外,在旧版本的git中可能无法正常工作,这种情况下,您需要显式提供相对于存储库根目录的完整文件路径。


3
请注意,与许多其他 Git 命令不同的是,文件名(此处为“file.tex”)必须是来自 Git 仓库根目录的名称;因此,如果您想要处理 foo/file.tex 文件,并且当前位于子目录 foo 中,则不能直接输入上述命令。相反,您需要输入 <sah1>:foo/file.tex,即使您已经在 foo 目录中也是如此。 - Daniel
1
@Daniel,没错。但是,至少在最近的git版本中,您始终可以使用“.”来引用当前目录。我已经更新了我的答案以反映这一点。 - qqx
现在我相信轮回。 - user4084811
好的。git cat-file -p <sha1>^:./file.tex > wherever.tex 可以获取先前提交的文件版本吗? - Learner
@ATL_DEV,要执行此操作的命令语法需要指定(1)要使用的命令,(2)要获取的路径/文件,(3)提交的标签或sha以及(4)文件复制的目标。您如何使语法更简单? - John Pankowicz

15

使用带有绝对仓库路径的git show:

工作目录$ git show revision:repo/module/package/code.file > code.file.old

或相对于当前目录的路径:

package$ git show revision:./code.file > workdir/code.file.old

与检出文件不同,show本质上不会更改您的工作区,您可以随意处理输出结果。

感谢这个答案,当然您也可以在手册中查看完整详情。


1
这显然是最准确的答案,因为它不会改变存储库的版本/状态,并允许恢复存储库的任何状态。 - G.Courmont

13

我认为最好的解决方案是覆盖您的文件,暂时将其重写。在您存储库的顶层:

git checkout <sha1> file.tex
cp file.tex directory
git checkout HEAD file.tex

1
这是我目前看到的最佳解决方案。我仍然很烦恼,似乎没有直接获取该文件的方法。 - jbranchaud
4
最后一个命令需要是 git checkout HEAD file.tex。第一个checkout命令会修改索引和工作树副本,所以未指定版本的checkout仍然会使用旧版本。 - qqx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接