以新名称对文件的旧版本进行git检出

我在编辑器中打开了文件“main.cpp”。

我也想在编辑器中看到“main.cpp”的先前修订。

我现在的做法是这样的。

close "main.cpp" in the editor


prompt> mv main.cpp tmp
prompt> git checkout HEAD^ main.cpp
prompt> mv main.cpp old_main.cpp
prompt> mv tmp main.cpp
prompt>


open "main.cpp" and "old_main.cpp" in the editor

它是否可以简化,这样我就不必在编辑器中关闭“main.cpp”了?

我所希望的是git-checkout的一个变体可以做到这一点。


更新:我使用git在mac osx 10.5.7

prompt> git --version
git version 1.6.0.4
prompt>

Jakub narylbski回答:

prompt> git show HEAD^:dir1/dir2/dir3/main.cpp > old_main.cpp
prompt>

更新3:Karmi的回答,对于一个具体的修订:

prompt> git show 4c274dd91dc:higgs/Higgs.xcodeproj/project.pbxproj > old_project.pbxproj
prompt>
69194 次浏览

你可以使用git show:

git show HEAD^:main.cpp > old_main.cpp

(注意在HEAD^main.cpp之间有冒号[:]字符。)<revision>:<path>语法在git rev-parse手册页中描述,在“指定修订”的最后一点旁边。部分:

<rev>:<path>,例如HEAD:README:READMEmaster:./README

后缀:后跟路径命名树状结构中给定路径处的blob或树 由冒号前部分命名的对象。:path(冒号前有一个空部分) 下面描述的语法是一种特殊情况:记录在索引中的内容 给定的路径。以./../开头的路径是相对于当前工作目录的。 给定的路径将被转换为相对于工作树的根目录。 这对于从具有相同内容的提交或树中处理blob或树非常有用 树结构作为工作树。

注意,这里的<path>是相对于项目的顶级目录完整的路径,即包含.git/目录的目录。(或者,更确切地说,是“__abc4”,它通常可以是任何& lt; tree-ish>,即表示树的东西。)

如果你想使用相对于当前目录的path,你需要使用./<path>语法(或../path从当前目录往上)。

Edit 2015-01-15: added information about relative path syntax


在大多数情况下,使用低级(管道)git cat-file命令可以得到相同的输出:

git cat-file blob HEAD^:main.cpp > old_main.cpp

只是补充一下Jakub的答案:如果你只对终端中的文件内容感兴趣,你甚至不必将输出重定向到>文件。你可以运行$ git show 58a3db6:path/to/your/file.txt

单文件用例

为了获得一致的签出行为,包括autocrlf等,使用一个辅助文件夹(以TEMP为例),并从一个旧的/不同的<commit>中恢复文件状态,如下所示:

git --work-tree TEMP/ restore main.cpp -s <commit>
mv TEMP/main.cpp old_main.cpp

使用别名使其成为单行命令

git restore-as old_main.cpp main.cpp -s <commit>

创建别名:

git config --global alias.restore-as "!f() { git --work-tree /tmp/ restore $2 $3 $4 $5 $6 && mv -iv /tmp/$2 $1; }; f"

(最好在创建后将/tmp/替换为为此类操作保留的目录-例如/tmp/gitmv。)

注意:

git show <commit>:main.cpp > old_main.cpp

.. 只会从存储库中产生一个原始读取。

使用第二个工作树——链接的或匿名的

一个长期的并行工作树(与带有主工作树的存储库相链接/已知)可以通过git-worktree (git v2.6.7以来的新功能)使用,并且可以将其HEAD放在不同的分支/ <commit>上:

git worktree add [<options>] <new-worktree-path> [<commit-ish>]

工作树可以在没有初始签出的情况下创建(--no-checkout),随后可以配置sparse-checkout,或者只是通过git restore -s <commit> <file(s)/sub-dir>检索选定的单个文件/子dirs

类似地,可以创建一个额外的匿名工作树(共享HEAD),只需将包含内容的文件.git放入其中

gitdir: <MAIN-REPO-WORKTREE>/.git