ChatGPT解决这个技术问题 Extra ChatGPT

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

我有一个 .tex 文件的一个版本,它来自许多之前的提交,我想获得一份副本。对于具有我想要的文件版本的提交,我有 sha1 哈希值。我不想替换文件的当前版本。相反,我只想获得它的单独副本,以反映其在旧版本中的状态。

许多类似的问题建议使用 git checkout <sha1> -- file.tex,但这只是不断给出“错误:pathspec 'file.tex' 与 git 已知的任何文件不匹配”。

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

这可能吗?我怎样才能做到这一点?

制作当前文件的副本,然后运行 git checkout <commit-id> file.ext

q
qqx

您可以使用 git cat-file 将文件的内容转储到标准输出并将其重定向到您想要的目标:

git cat-file -p <sha1>:./file.tex > wherever.tex

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


请注意,与许多其他 git 命令不同,文件名(此处为“file.tex”)必须是 git repo 根目录的名称;所以如果你想要 foo/file.tex 并且你在子目录 foo 中你不能输入上面的内容,你必须输入 :foo/file.tex 尽管你已经在 foo 中。
@Daniel,这是真的。但是,至少对于最新版本的 git,您始终可以使用 . 来引用当前目录。我已经更新了我的答案以反映这一点。
现在我相信轮回。
伟大的。 git cat-file -p ^:./file.tex > where.tex 会从上一次提交中获取文件的版本吗?
@ATL_DEV,执行此操作的任何命令语法都需要指定(1)要使用的命令,(2)要获取的路径/文件,(3)提交的标签或 sha 以及(4)文件副本的目标.您如何使语法更简单?
g
gws

git show 与绝对存储库路径一起使用:

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

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

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

与检出文件相比,show 本质上不会更改您的工作区,您可以对输出做任何您喜欢的事情。

归功于 this answer,当然也可以在 manual 中查看完整的详细信息。


这显然是最准确的答案,因为它不会更改存储库的版本/状态并允许恢复存储库的任何状态。
J
Jon-Eric

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

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

这是迄今为止我见过的最好的解决方案。我仍然很生气,似乎没有办法直接获取该文件。
最后一个命令需要是 git checkout HEAD file.tex。第一个 checkout 命令将修改索引以及工作树副本,因此不指定修订的 checkout 仍将使用旧版本。