相当于git存档直接到磁盘,无需任何tar处理



我正在分析修订历史,使用git-archive获取特定修订的文件(请参阅https://stackoverflow.com/a/40811494/1168342)。

这种方法是可行的,但我正在努力为有许多修订的项目进行优化。许多处理都浪费在归档(通过tar)和返回到另一个目录中的文件(再次通过tar)上。

我正在寻找一种不涉及tar的方法,类似于git cp $revision $dest/。以下是我迄今为止探索的内容:

  • 我可以使用带有文件副本的git reset $revision --hard方法,但它会导致分析的并行化无效,除非我创建多个repo副本(每个线程/进程一个)。

  • 有一个使用JGit的Java项目名为Doris,它通过低级操作实现了这一点,但当出现奇怪的文件(例如,指向其他repo的链接)时,它就会中断。随着git的发展,有很多特殊情况,所以如果可能的话,我不想在低级别上这样做。

  • 我知道Python有一个git API,但它的归档功能也使用tar。出于与上述相同的原因,我不想将其编码到太低的级别。

使用:

mkdir <path> &&
GIT_INDEX_FILE=<path>/.git git --work-tree=<path> checkout <revision> -- . &&
rm <path>/.git

git checkout步骤将覆盖索引,因此为了使此并行化良好,我们可以将索引文件指向目标。有一个文件名是非常安全的:.git

(这就像git worktree add的轻量级版本,它也避免了将新提取的树记录为活动工作树。)

编辑以添加旁注(我希望OP知道这一点,但供将来参考):注意git archive应用了该技术不应用的某些.gitattributes过滤器。特别地,git checkout将不服从export-ignoreexport-subst指令。

在JGit中,ArchiveCommand实现了git archive的功能,还提供了几种现成的归档文件格式。但是,ArchiveCommand可以使用自定义存档格式进行扩展。

自定义格式需要实现Format接口并将其注册到ArchiveCommand::registerFormat。即使相应的API设计时似乎考虑到了单个输出文件,也应该可以将内容输出到目录中。

最新更新