【问题标题】:git-checkout older revision of a file under a new namegit-checkout 新名称下文件的旧版本
【发布时间】:2010-10-27 16:01:59
【问题描述】:

我在编辑器中打开了文件“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> 

UPDATE2:Jakub Narębski 的回答是:

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> 

【问题讨论】:

  • 你用什么编辑器?也许它有插件/插件/模块添加对 Git 的支持?
  • 我使用 textmate。它有一些 git 支持,我还没有检查它是否可以做到。
  • Textmate 有 git 包:github.com/timcharper/git-tmbundle(你应该检查过 git wiki 上的 InterfacesFrontendsAndTools 页面:git.or.cz/gitwiki
  • 顺便说一下,Emacs 中的 VC 接口(Git 也以 vc-git.el 的形式提供支持)具有“显示其他版本”命令。如果 TexMate Git Bundle (git-tmbundle) 没有它,也许值得添加它。
  • 我使用符号链接来更好地跟踪我在 TextMate 中的项目。 25 个目录,300 个文件。这有助于隐藏 builddirs 和其他不相关的目录。但是 git/TextMate 对这些符号链接不太满意,所以没有 :-(

标签: git


【解决方案1】:

您可以为此使用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>FULL相对于你项目的顶级目录的路径,即带有.git/目录的目录。 (或者,更准确地说,是“”,一般可以是任何,即代表树的东西。)

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

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


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

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

【讨论】:

  • 我对完整副本感兴趣,但 git-show 只显示不同之处.. 我尝试使用 --pretty 选项.. prompt> git show --pretty=fuller HEAD^ main.cpp 但它没有解决它。
  • “git show HEAD^ main.cpp”(HEAD^ 和 main.cpp 之间有空格)不同于“git show HEAD^:main.cpp”(带有冒号 ':' 在 HEAD^ 和 main.cpp 之间)。
  • 嗯,用冒号我看到这个错误,所以我认为冒号是错误的。是的,似乎冒号是要走的路,但是我该如何解决呢?提示> git show HEAD^:main.cpp 致命:不明确的参数 'HEAD^:main.cpp':未知修订版或路径不在工作树中。使用 '--' 将路径与修订提示分开>
  • 这可能意味着你给出了错误的 PATHNAME(不幸的是因为“git show”魔法 git 不能给出更好的错误信息)。它应该是相对于项目顶级目录的完整路径名: $(git ls-tree -r --name-only HEAD^ | grep main.cpp)
  • 不是完整路径,来自文档:“以 ./ 或 ../ 开头的路径是相对于当前工作目录的。”适用于我的 1.8.5 版本。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    单一用例

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

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

    注意:

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

    .. 只会从存储库中生成原始读取。

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

    为了更舒适地使用替代文件状态(无需重命名),请使用辅助“匿名”目录作为(长期)并行工作树,如下所示:

    # one time setup
    mkdir WD2
    cd WD2
    echo gitdir: WD1 > .git
    
    # operate freely here with an alternative file set while the same branch is checked out in git
    git restore -s <commit> main.cpp
    

    (WD2:辅助目录的路径。WD1:主目录的路径 - 绝对或相对)

    注意:任何类型的 git 项目工作(恢复/添加/提交/切换...,构建任务)都可以使用该替代文件集完成 - 就好像 WD1 中的工作树文件突然被交换了一样。硬链接可用于有效地镜像大型存储库中未更改的文件。

    类似地,可以通过git-worktree 使用“链接工作树”(自 git v2.6.7 以来的新功能)。这会导致更多的 git 开销,但允许同时在不同的分支(或分离的头)上签出和工作,而无需使用额外的 repo。

    【讨论】:

    • 对我来说,这是最好的方法,因为我仍然使用原生方式获取文件内容。通过“git show”解决方案的数量,我仍然担心编码和其他事情。有了这个,我可以在我正在寻找的版本中保存文件。谢谢!
    • 注意:在第一种方法(“Singular use case”)中,“TEMP”文件夹应该存在。
    猜你喜欢
    • 2011-09-27
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2018-04-04
    相关资源
    最近更新 更多