【问题标题】:Equivalent of git-archive direct to disk, without any tar processing相当于 git-archive 直接到磁盘,没有任何 tar 处理
【发布时间】:2017-10-25 21:33:57
【问题描述】:

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

该方法有效,但我正在尝试针对具有许多修订的项目进行优化。许多处理浪费在归档(通过 tar)和返回到另一个目录中的文件(再次通过 tar)。

我正在寻找一种不涉及tar 的方法来执行此操作,例如git cp $revision $dest/。以下是我目前探索的内容:

  • 我可以将git reset $revision --hard 方法与文件副本一起使用,但它会使分析的并行化无效,除非我创建了存储库的多个副本(每个线程/进程一个)。

  • 有一个 Java project using JGit called Doris 可以通过低级操作完成此操作,但是当有奇怪的文件(例如,指向其他 repos 的链接)时它会中断。随着 git 的发展,有很多特殊情况,所以如果可能的话,我不想在底层做这件事。

  • 我知道 Python 有一个 git API,但它的 archive feature 也使用 tar。出于与上述相同的原因,我不想在太低的级别上编写代码。

【问题讨论】:

    标签: git optimization jgit gitpython


    【解决方案1】:

    用途:

    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 指令。

    【讨论】:

    • 我认为只要工作树和存储库位于同一文件系统上,工作树/.git 索引名称就可以工作。将临时索引放在带有垃圾名称的本地存储库中总是有效的。
    • @jthill:我使用 /tmp(一个单独的文件系统)作为目标,在常规文件系统上使用源 repo 进行了测试。这只是一个特定的操作系统,但它对跨设备链接的限制与大多数其他操作系统相同。
    • 嗯。我想知道为什么对读取树有限制--index-output 而不是 GIT_INDEX_FILE,然后,或者该文档可能已过时,它显示“在命令运行时,原始索引文件被锁定为与往常相同的机制。文件必须允许从在通常索引文件旁边创建的临时文件中重命名(2);通常这意味着它需要与索引文件本身位于同一文件系统上,并且您需要对目录的写入权限索引文件和索引输出文件位于。"
    • @jthill:我没有调查,但我怀疑git checkout 要么注意到当前索引不存在并简单地创建并填充它解锁,要么将.lock 文件创建为&lt;work-dir&gt;/.git.lock这里(如果是这样的话,可能会与存储库中的真实文件发生冲突)。
    • @kostix 这就是为什么我将其描述为一种轻量级的git worktree add。添加工作树会添加辅助索引和HEAD,但也会记录添加的工作树并写入.git文件。在某些时候,您可能想要运行 git worktree prune 来清理它们。这种偷偷摸摸的结帐方法避免了这种情况。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-08
      • 2012-12-30
      • 2022-10-18
      • 2013-08-20
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多