mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(install): tolerate stale autostash drop after interrupted install (#14735)
- After a successful git stash apply, git stash drop may fail with 'not a stash reference' when a prior install was interrupted; set -e must not abort the installer. - Log a warning and continue; local changes are already applied. - Add bash regression tests + install.sh guard assertion. Fixes https://github.com/NousResearch/hermes-agent/issues/14735 Made-with: Cursor
This commit is contained in:
parent
a0d8dd7ba3
commit
2a0aa1de92
2 changed files with 108 additions and 1 deletions
|
|
@ -752,7 +752,12 @@ clone_repo() {
|
|||
if [ "$restore_now" = "yes" ]; then
|
||||
log_info "Restoring local changes..."
|
||||
if git stash apply "$autostash_ref"; then
|
||||
git stash drop "$autostash_ref" >/dev/null
|
||||
# Apply succeeded; dropping the captured stash ref can still fail
|
||||
# after an interrupted prior install (stale hash / not a stash ref).
|
||||
# Never abort the installer here — user changes are already applied (#14735).
|
||||
if ! git stash drop "$autostash_ref" >/dev/null 2>&1; then
|
||||
log_warn "Could not drop installer autostash (already removed or not a stash reference). Continuing. (#14735)"
|
||||
fi
|
||||
log_warn "Local changes were restored on top of the updated codebase."
|
||||
log_warn "Review git diff / git status if Hermes behaves unexpectedly."
|
||||
else
|
||||
|
|
|
|||
102
tests/test_install_sh_issue_14735.py
Normal file
102
tests/test_install_sh_issue_14735.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
"""Regression tests for scripts/install.sh autostash cleanup (issue #14735).
|
||||
|
||||
The installer uses ``set -e``. A stale ``git stash drop <ref>`` after a prior
|
||||
interrupted run must not abort the whole script. These tests validate the
|
||||
guard pattern and that install.sh still contains it.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _repo_root() -> Path:
|
||||
return Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def test_install_sh_stash_drop_after_apply_is_non_fatal() -> None:
|
||||
"""Reproduce #14735: drop of a non-stash ref must not exit under set -e."""
|
||||
script = textwrap.dedent(
|
||||
r"""
|
||||
set -euo pipefail
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
cd "$tmp"
|
||||
git init -q
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Hermes Install Test"
|
||||
echo v1 >tracked.txt
|
||||
git add tracked.txt
|
||||
git commit -q -m "base"
|
||||
echo dirty >>tracked.txt
|
||||
git stash push -u -q -m "hermes-install-autostash-test"
|
||||
stash_ref=$(git rev-parse refs/stash)
|
||||
stale_ref=$(git rev-parse HEAD)
|
||||
git stash apply "$stash_ref"
|
||||
# Same pattern as scripts/install.sh after fix: drop must not abort.
|
||||
if ! git stash drop "$stale_ref" >/dev/null 2>&1; then
|
||||
echo "drop_failed_as_expected"
|
||||
fi
|
||||
echo "survived"
|
||||
"""
|
||||
)
|
||||
proc = subprocess.run(
|
||||
["bash", "-c", script],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
assert proc.returncode == 0, (proc.stdout, proc.stderr, proc.returncode)
|
||||
assert "survived" in proc.stdout
|
||||
assert "drop_failed_as_expected" in proc.stdout
|
||||
|
||||
|
||||
def test_install_sh_documents_guarded_autostash_drop() -> None:
|
||||
"""install.sh must keep the non-fatal autostash drop guard (issue #14735)."""
|
||||
install_sh = _repo_root() / "scripts" / "install.sh"
|
||||
text = install_sh.read_text(encoding="utf-8")
|
||||
# After successful apply: guarded drop + user-facing warning.
|
||||
assert re.search(
|
||||
r'git stash apply "\$autostash_ref"[\s\S]{0,800}?'
|
||||
r'if ! git stash drop "\$autostash_ref"\s*>\s*/dev/null\s*2>&1',
|
||||
text,
|
||||
), "expected guarded 'git stash drop' after successful apply"
|
||||
assert "Could not drop installer autostash" in text
|
||||
assert "#14735" in text
|
||||
|
||||
|
||||
def test_stash_pop_round_trip_succeeds() -> None:
|
||||
"""Sanity: stash / pop succeeds in a fresh repo (install path uses apply+drop)."""
|
||||
script = textwrap.dedent(
|
||||
r"""
|
||||
set -euo pipefail
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
cd "$tmp"
|
||||
git init -q
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Hermes Install Test"
|
||||
echo v1 >f
|
||||
git add f && git commit -q -m one
|
||||
echo v2 >>f
|
||||
git stash push -u -q -m stash1
|
||||
if ! git stash pop -q; then
|
||||
echo "stash_pop_failed" >&2
|
||||
exit 2
|
||||
fi
|
||||
echo ok
|
||||
"""
|
||||
)
|
||||
proc = subprocess.run(
|
||||
["bash", "-c", script],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
assert proc.returncode == 0, (proc.stdout, proc.stderr)
|
||||
assert "ok" in proc.stdout
|
||||
Loading…
Add table
Add a link
Reference in a new issue