【问题标题】:Git: How do I recover the most recent version of every single file ever removed in a branch?Git:如何恢复分支中删除的每个文件的最新版本?
【发布时间】:2022-01-10 01:59:45
【问题描述】:

我有一个带有一个分支的 Git 存储库,在一年多的时间里,数千个文件经历了一个生命周期,每个文件都经过最初添加,然后多次修改,最后被删除。

我想检索存储库中存在的每个文件在删除之前的最新版本,以便将每个文件存档到单独的位置。我不需要在 Git 中恢复那些旧版本,我只需要将每个文件的最新版本(尊重其相应的相对路径)转储到存储库外部的某个目录。

什么是完成此任务的好方法?

(我看到的其他问答涉及如何恢复由单个提交或几个提交删除的单个文件或子目录,而不是如何在数千个提交中为数千个文件执行此操作。)

【问题讨论】:

  • 是否有任何文件名重叠?像创建/修改/删除/重新创建同名等?
  • @CarlNorum 不,即使他们这样做了,我也可以使用仅获取与每个路径关联的最新内容的解决方案。
  • 您是否需要使用 git bash 或类似工具来执行此操作,或者您是否有一个可以/将执行此操作的操作系统,它可能允许使用不同的工具,例如更传统的编程语言?
  • 另外,看起来很清楚,但只是想 100% 确定,您只想归档该路径中 HEAD 中不再存在的文件?因此,如果该位置仍有路径,您不需要此工具或方法或其他任何东西来制作它的单独副本?
  • @LasseV.Karlsen:最好使用 shell 命令,是的,但如果您认为这需要开发一种编程语言和一个库,那么这是一个值得提出的观点。

标签: git


【解决方案1】:

我可能会开始,也许:

 git log --format='' --full-history --name-status --diff-filter=D

这应该列出所有已删除的文件。它不捕获提交哈希,但如果与更智能的脚本集成,它可以。然后获取文件被删除的提交——当文件被删除时,假设它在最后一次触及路径的提交中被删除——并使用git show deleted_in^:filename在删除之前获取文件内容。

这个 bash sn -p 应该恢复“tmp”中已删除的文件。更改相关以涵盖“在分支中”的含义。我建议添加-n 100 或类似的进行测试。 YMMV。

 git log --format='' --full-history --name-status --diff-filter=D |
 cut -f2 |
 (while read file; do (
     c=$(git rev-list head --max-count=1 -- "$file");
     echo "restoring '$file' deleted in $c";
     mkdir -p "tmp/$(dirname \\"$file\\")";
     git show $c^:"$file" > "tmp/$file";
   ); done)

更智能的脚本可能会捕获文件被删除的提交文件名,以避免上面使用次要的git rev-list。然后,这样的脚本将确保它仍然使用文件被修改的最后一次提交,这个问题在上面的脚本中不存在,因为 rev-list 使用只返回最后一次提交。

【讨论】:

  • 次要:考虑--diff-filter=D 而不是| grep ^D
猜你喜欢
  • 2011-07-29
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 2019-06-17
  • 1970-01-01
  • 2020-07-09
相关资源
最近更新 更多