git-checkout使用新名称 checkout 文件的旧版本

n9vozmp4  于 2022-12-25  发布在  Git
关注(0)|答案(4)|浏览(100)

我在编辑器中打开了文件“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的一个变体,它可以做到这一点。
更新:在mac osx 10.5.7上使用git

prompt> git --version
git version 1.6.0.4
prompt>

更新2:雅库布·纳伦布斯基的回答是:

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

UPDATE3:Karmi的回答,对于一个特定的修订:

prompt> git show 4c274dd91dc:higgs/Higgs.xcodeproj/project.pbxproj > old_project.pbxproj
prompt>
js5cn81o

js5cn81o1#

您可以使用git show来实现此目的:

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

(Note HEAD^main.cpp之间有冒号[:]字符。)<revision>:<path>语法在git rev-parse手册页中进行了说明,该手册页位于“指定修订版本”部分的倒数第二点:
<rev>:<path>,例如HEAD:README:READMEmaster:./README
后缀:后跟一个路径,用于命名由冒号前的部分命名的树状对象中给定路径处的blob或树。:path(冒号前有一个空部分)是下面描述的语法的特殊情况:记录在给定路径的索引中的内容。以./../开头的路径相对于当前工作目录。给定路径将转换为相对于工作树的根目录。这对于从与工作树具有相同树结构的提交或树中寻址blob或树非常有用。
注意这里的<path>是相对于项目的top目录FULL路径,也就是.git/目录所在的目录。(或者,更确切地说,是“",通常可以是任何 ,也就是表示树的东西。)
如果要使用相对于当前目录的路径,则需要使用./<path>语法(或者使用../path从当前目录向上)。

**编辑2015-01-15:**添加了关于相对路径语法的信息

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

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

dfty9e192#

再补充一下雅库布的回答:如果你只想浏览终端中的文件内容,你甚至不需要用>将输出重定向到一个文件,你可以直接运行$ git show 58a3db6:path/to/your/file.txt

yizd12fk

yizd12fk3#

单个文件使用情形

为了获得一致的 checkout 行为(包括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"

(Best在创建/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)的情况下创建工作树,并且随后可以配置sparse-checkout,或者可以通过git restore -s <commit> <file(s)/sub-dir>检索仅选定的单个文件/子目录
类似地,可以创建额外的匿名工作树(共享HEAD),只需将包含内容的文件.git放入其中即可

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

vjhs03f74#

我无法让@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 showaccepted answer更好,因为它保留了不可见字符。
注意:在上面的代码中,文件的“其他版本”将保留原始文件名,而当前文件是您必须重命名的文件。
下面是一个git别名,它可以在一行中完成这个操作,这个命令实际上让 current 文件保持原来的文件名:
restore-as = "!mv $1 $1_tmp && git checkout $3 -- $1 && git restore --staged $1 && mv $1 $2 && mv $1_tmp $1 #"(请参阅here了解为什么需要#后缀)
这可以用作:git restore-as path/to/file.txt path/to/file_old.txt <commit>

相关问题