我在编辑器中打开了文件“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>
你可以使用git show:
git show HEAD^:main.cpp > old_main.cpp
(注意HEAD^和main.cpp之间有冒号[:]。)<revision>:<path>语法在git rev-parse manpage中描述,在“指定修订”部分的最后一点旁边:
<rev>:<path>, e.g. HEAD:README, :README, master:./README
A suffix : followed by a path names the blob or tree at the given path in the tree-ish
object named by the part before the colon. :path (with an empty part before the colon)
is a special case of the syntax described next: content recorded in the index at the
given path. A path starting with ./ or ../ is relative to the current working directory.
The given path will be converted to be relative to the working tree’s root directory.
This is most useful to address a blob or tree from a commit or tree that has the same
tree structure as the working tree.
注意,这里的<path>是相对于项目的顶部目录的完整路径,即。git/ directory目录。(或者,更确切地说,到“<revision>”,通常可以是任何<树状>,即表示树的东西。)
如果你想使用相对于当前目录的路径,你需要使用。/<path>语法(或../从当前目录往上的路径)。
编辑2015-01-15:增加相对路径语法
在大多数情况下,你可以使用低级(管道)git cat-file命令得到相同的输出:
git cat-file blob HEAD^:main.cpp > old_main.cpp
单文件用例
为了获得一致的签出行为,包括自锁等,使用一个辅助文件夹(以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/替换为用于此类操作的目录-例如/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)的情况下创建,然后可以配置稀疏签出,或者通过git restore -s <commit> <file(s)/sub-dir>检索选择的单个文件/子dirs
类似地,可以创建一个额外的匿名工作树(共享HEAD),只需将包含内容的.git文件放入其中
gitdir: <MAIN-REPO-WORKTREE>/.git
我无法让@kxr的答案工作。我发现这个更简单:
# Rename the current file.
mv path/to/file.txt path/to/file_current.txt`
# Checkout some other version of that file.
git checkout <commit> -- path/to/file.txt
这比使用git show的公认答案要好,因为它保留了不可见的字符。
注意:在上面的代码中,文件的“其他版本”将保持原始文件名,而当前文件是您必须重命名的文件。
这里是一个git别名,它在一行中完成这个任务。这个命令实际上使当前文件保持原来的文件名:
Restore-as = "! "Mv $1 $1_tmp && git checkout $3 - $1 && git restore - staging $1 && Mv $1 $2 && Mv $1_tmp $1 #”(参见这里了解为什么我们需要#后缀)
然后可以这样使用:git restore-as path/to/file.txt path/to/file_old.txt <commit>