diff --git a/scripts/install.sh b/scripts/install.sh index eb6bdfe300b4..92c077bd6fd5 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2874,7 +2874,11 @@ install_openclaw_from_git() { validate_git_checkout_head "$repo_dir" || return 1 if [[ ! -d "$repo_dir" ]]; then mkdir -p "$(dirname "$repo_dir")" - run_quiet_step "Cloning OpenClaw" git clone "$repo_url" "$repo_dir" + # Blobless clone: the installer checks out one release tag, so full blob + # history is downloaded and then discarded. blob:none keeps ref metadata + # (unlike --depth 1) so ref switching and later updates still work, and + # git warns and falls back to a full clone if the server cannot filter. + run_quiet_step "Cloning OpenClaw" git clone --filter=blob:none "$repo_url" "$repo_dir" fi local git_ref diff --git a/test/scripts/install-sh.test.ts b/test/scripts/install-sh.test.ts index 0ca86ca542db..bce15156e364 100644 --- a/test/scripts/install-sh.test.ts +++ b/test/scripts/install-sh.test.ts @@ -1017,14 +1017,47 @@ NODE const output = result?.stdout ?? ""; expect(output).toContain(`git=${join(openclawHome, "openclaw")}`); const mkdirParentIndex = script.indexOf('mkdir -p "$(dirname "$repo_dir")"'); - const cloneIndex = script.indexOf( - 'run_quiet_step "Cloning OpenClaw" git clone "$repo_url" "$repo_dir"', - ); + // Ordering only. The clone flags are asserted behaviorally below, so this + // needle stays short enough to survive future changes to them. + const cloneIndex = script.indexOf('run_quiet_step "Cloning OpenClaw" git clone'); expect(mkdirParentIndex).toBeGreaterThan(-1); expect(cloneIndex).toBeGreaterThan(-1); expect(mkdirParentIndex).toBeLessThan(cloneIndex); }); + it("uses a blobless partial clone for new git installs", () => { + const result = runInstallShell(` + set -euo pipefail + source "${SCRIPT_PATH}" + repo="$HOME/openclaw" + check_git() { return 0; } + ensure_pnpm() { :; } + ensure_pnpm_binary_for_scripts() { :; } + resolve_git_openclaw_ref() { printf 'main\\n'; } + checkout_git_openclaw_ref() { :; } + cleanup_legacy_submodules() { :; } + activate_repo_pnpm_version() { :; } + git_install_lockfile_flag() { printf '%s\\n' '--frozen-lockfile'; } + run_quiet_step() { + printf 'step:%s|%s\\n' "$1" "\${*:2}" + [[ "$1" == "Cloning OpenClaw" ]] && mkdir -p "$repo" + return 0 + } + ensure_user_local_bin_on_path() { mkdir -p "$HOME/.local/bin"; } + ui_info() { :; } + ui_success() { :; } + ui_error() { printf 'error:%s\\n' "$*"; } + git() { return 0; } + + install_openclaw_from_git "$repo" + `); + + expect(result.status).toBe(0); + expect(result.stdout).toContain( + "step:Cloning OpenClaw|git clone --filter=blob:none https://github.com/openclaw/openclaw.git", + ); + }); + it("does not treat OS HOME config as active when OPENCLAW_HOME is set", () => { const tmp = mkdtempSync(join(tmpdir(), "openclaw-install-legacy-config-")); const osHome = join(tmp, "os-home");