From fc0900d120df5329e58642fa4d5ed28918423f47 Mon Sep 17 00:00:00 2001 From: xxxigm Date: Sun, 7 Jun 2026 18:47:07 +0700 Subject: [PATCH] fix(install): re-clone interrupted (commit-less) checkout instead of failing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An interrupted previous clone leaves the install dir's .git present but with no initial commit. rev-parse --is-inside-work-tree and git status both still succeed there, so the installer entered the update path and ran `git stash`, which aborts with "You do not have the initial commit yet" and failed the desktop install at the "Cloning Hermes repository" stage. - install.ps1: add a `git rev-parse --verify HEAD` probe to the repo-validity check so a commit-less checkout is treated as broken and re-cloned fresh. - install.sh: mirror it at the top of clone_repo() — drop a partial checkout with no resolvable HEAD so the fresh-clone path handles it (POSIX parity). Fixes #40998 --- scripts/install.ps1 | 19 +++++++++++++++---- scripts/install.sh | 9 +++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 7645af00da..4706778cc9 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1060,9 +1060,10 @@ function Install-Repository { # directory OR a symlink OR a submodule-style gitfile -- and also when # it's a broken stub left over from a failed previous install (e.g. # a partial Remove-Item that couldn't delete a locked index.lock). - # Validate the repo properly by asking git itself. Two checks - # belt-and-braces: rev-parse AND git status. If either fails the - # repo is broken and we fall through to a fresh clone. + # Validate the repo properly by asking git itself. Three checks + # belt-and-braces: rev-parse (work tree), git status, and a resolvable + # HEAD (an initial commit). If any fails the repo is broken and we + # fall through to a fresh clone. $repoValid = $false if (Test-Path "$InstallDir\.git") { Push-Location $InstallDir @@ -1077,7 +1078,17 @@ function Install-Repository { $null = & git -c windows.appendAtomically=false status --short 2>&1 $statusOk = ($LASTEXITCODE -eq 0) - if ($revParseOk -and $statusOk) { + # An interrupted previous clone leaves a repo with NO initial + # commit. rev-parse/status still succeed there, but the update + # path's `git stash` (and later `git checkout`) abort with + # "You do not have the initial commit yet" and fail the install + # (#40998). Require a resolvable HEAD so such partial checkouts + # are treated as broken and re-cloned fresh below. + $global:LASTEXITCODE = 0 + $null = & git -c windows.appendAtomically=false rev-parse --verify HEAD 2>&1 + $hasCommit = ($LASTEXITCODE -eq 0) + + if ($revParseOk -and $statusOk -and $hasCommit) { $repoValid = $true } } catch {} diff --git a/scripts/install.sh b/scripts/install.sh index e24e6537b6..0527025499 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1092,6 +1092,15 @@ show_manual_install_hint() { clone_repo() { log_info "Installing to $INSTALL_DIR..." + # An interrupted previous clone leaves a .git with no initial commit, where + # the update path's `git stash` / `git checkout` abort with "You do not + # have the initial commit yet" and fail the install (#40998). Drop such a + # partial checkout so the fresh-clone path below handles it cleanly. + if [ -d "$INSTALL_DIR/.git" ] && ! git -C "$INSTALL_DIR" rev-parse --verify HEAD >/dev/null 2>&1; then + log_warn "Existing checkout at $INSTALL_DIR has no commits (interrupted clone) -- replacing it." + rm -rf "$INSTALL_DIR" + fi + if [ -d "$INSTALL_DIR" ]; then if [ -d "$INSTALL_DIR/.git" ]; then log_info "Existing installation found, updating..."