fix: auto-stash local changes during updates

This commit is contained in:
smillunchick 2026-03-11 20:35:10 +00:00 committed by teknium1
parent 1a857123b3
commit f764c7135d
3 changed files with 185 additions and 2 deletions

View file

@ -45,6 +45,7 @@ Usage:
import argparse
import os
import subprocess
import sys
from pathlib import Path
from typing import Optional
@ -1930,9 +1931,61 @@ def _update_via_zip(args):
print("✓ Update complete!")
def _stash_local_changes_if_needed(git_cmd: list[str], cwd: Path) -> Optional[str]:
status = subprocess.run(
git_cmd + ["status", "--porcelain"],
cwd=cwd,
capture_output=True,
text=True,
check=True,
)
if not status.stdout.strip():
return None
from datetime import datetime, timezone
stash_name = datetime.now(timezone.utc).strftime("hermes-update-autostash-%Y%m%d-%H%M%S")
print("→ Local changes detected — stashing before update...")
subprocess.run(
git_cmd + ["stash", "push", "--include-untracked", "-m", stash_name],
cwd=cwd,
check=True,
)
stash_ref = subprocess.run(
git_cmd + ["rev-parse", "--verify", "refs/stash"],
cwd=cwd,
capture_output=True,
text=True,
check=True,
).stdout.strip()
return stash_ref
def _restore_stashed_changes(git_cmd: list[str], cwd: Path, stash_ref: str) -> None:
print("→ Restoring local changes...")
restore = subprocess.run(
git_cmd + ["stash", "apply", stash_ref],
cwd=cwd,
capture_output=True,
text=True,
)
if restore.returncode != 0:
print("✗ Update pulled new code, but restoring local changes failed.")
if restore.stdout.strip():
print(restore.stdout.strip())
if restore.stderr.strip():
print(restore.stderr.strip())
print("Your changes are still preserved in git stash.")
print(f"Resolve manually with: git stash apply {stash_ref}")
sys.exit(1)
subprocess.run(git_cmd + ["stash", "drop", stash_ref], cwd=cwd, check=True)
def cmd_update(args):
"""Update Hermes Agent to the latest version."""
import subprocess
import shutil
print("⚕ Updating Hermes Agent...")
@ -1998,8 +2051,15 @@ def cmd_update(args):
return
print(f"→ Found {commit_count} new commit(s)")
auto_stash_ref = _stash_local_changes_if_needed(git_cmd, PROJECT_ROOT)
print("→ Pulling updates...")
subprocess.run(git_cmd + ["pull", "origin", branch], cwd=PROJECT_ROOT, check=True)
try:
subprocess.run(git_cmd + ["pull", "origin", branch], cwd=PROJECT_ROOT, check=True)
finally:
if auto_stash_ref is not None:
_restore_stashed_changes(git_cmd, PROJECT_ROOT, auto_stash_ref)
# Reinstall Python dependencies (prefer uv for speed, fall back to pip)
print("→ Updating Python dependencies...")