Skip to content

建议更新检查改用 ls-remote 替代 fetch 全量 tags,以支持浅克隆安装包 #9

Description

@isHarryh

问题描述

背景

pyappify 打包的发行安装包会把 app 仓库的完整 .git 目录一并打进安装包(包内路径 data/apps/<app>/repo/)。例如,目前 ok-ef 的更新库有 442 个 commit,已压缩的完整 .git 目录约为 214MB,占其安装包近一半体积。

为了减小应用打包体积,计划在打包侧把 repo 改为浅克隆(实测仅约 51MB,安装包可节省约 160MB)。但实测发现某些行为会让浅克隆失效,详见下。

阻塞问题

get_tags_and_current_version(src-tauri/src/git.rs)会在每次启动或更新检查时执行:

let mut fetch_options = create_fetch_options(remote_callbacks, None);
remote.fetch(&["+refs/tags/*:refs/tags/*"], ...)

fetch 全量 tags 的对象闭包 = 除浅边界内的对象外的全部历史对象。对浅克隆仓库实测发现,用户首次启动(或首次更新检查)会额外下载约 160MB 并把 .git 膨胀回全量——安装包省下的体积用户还得自己下载回来,浅克隆优化名存实亡。这与服务器是否支持 shallow 无关。

建议改动

get_tags_and_current_version 的远端 tag 列表改用 ls-remote(只取 refs,不拉对象)替代 fetch 全量 tags:

let mut callbacks = RemoteCallbacks::new();
configure_credentials(&mut callbacks, remote_url);
let connection = remote.connect_auth(Direction::Fetch, Some(callbacks), Some(create_proxy_options()))?;
let remote_tags = connection.list()?; // 过滤 refs/tags/ 前缀

代码中已有同款实现:collect_remote_tag_names(tag pruning 使用,git.rs)。

改动后:

  • 更新检查零对象传输,浅克隆仓库正确保持;
  • 执行更新仍走已有的 per-tag fetch(+refs/tags/<目标>:refs/tags/<目标>),前向更新增量传输;
  • 全量 fetch 会保留在 clone、首次 ensure_repository 等必要路径中。

已知降级点(可接受)

  • 浅克隆下 "更新失败后回滚到旧版本" 依赖本地旧 tag 与父提交:使用 depth-2 即可保住 "Rollback by previous commit" 兜底,解析不到旧 tag 时会走现有失败处理,报错不崩溃。
  • libgit2 fetch 不做自动 gc/加深,用户多次增量更新后 .git 会缓慢增长,但每次仅 MB 级增量更新,属于可接受范围。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions