fix(gitstore): return real git object ids instead of hex-of-hex

`porcelain.commit()` and `repo.refs[...]` hand back object ids as a
40-character hex string that is already encoded to bytes. Calling `.hex()`
on that encodes the ASCII a second time, so every id GitStore produced or
displayed was double-encoded:

    auto_commit()          -> '62623234'
    git log --abbrev=8     -> 'bb244606'

The module is self-consistently wrong, so `/dream-log` and `/dream-restore`
work as long as the id came from nanobot itself. What does not work is
crossing the boundary: ids in logs and commit output match nothing in
`git log`, and an id copied from `git log` cannot be resolved:

    _resolve_sha(own id)      -> b'bb244606d780...'
    _resolve_sha(real git id) -> None

Use `.decode()` at the four sites that consume dulwich object ids. Nothing
persists an id — callers either display it or resolve it live — so there is
no stored state in the old format.

Adds two regression tests: the id returned by `auto_commit` must equal
`git log --abbrev=8`, and a real git id must resolve through `_resolve_sha`.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ATECHPCS
2026-07-30 18:25:56 +08:00
committed by Xubin Ren
co-authored by Claude
parent bb2f6cf324
commit 92361cbeac
2 changed files with 29 additions and 4 deletions
+22
View File
@@ -310,3 +310,25 @@ class TestNestedRepoProtection:
assert result is False
assert not (workspace / ".git").exists()
class TestCommitIdEncoding:
"""Commit ids must be usable with git, not hex-of-hex."""
def test_auto_commit_returns_the_real_short_sha(self, git, tmp_path):
(tmp_path / "MEMORY.md").write_text("- a fact\n", encoding="utf-8")
sha = git.auto_commit("memory update")
expected = subprocess.run(
["git", "-C", str(tmp_path), "log", "-1", "--format=%h", "--abbrev=8"],
capture_output=True, text=True, check=True,
).stdout.strip()
assert sha == expected
def test_a_real_git_sha_resolves(self, git, tmp_path):
(tmp_path / "MEMORY.md").write_text("- a fact\n", encoding="utf-8")
git.auto_commit("memory update")
real = subprocess.run(
["git", "-C", str(tmp_path), "log", "-1", "--format=%h", "--abbrev=8"],
capture_output=True, text=True, check=True,
).stdout.strip()
assert git._resolve_sha(real) is not None