Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions stacklets/memory/bot/curator.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,8 +685,12 @@ def _commit_push(self, message: str) -> bool:
True when a commit was made and pushed (or there was nothing to
commit, which is still a success)."""
self._run("add", "-A")
# `diff --cached --quiet` exits 1 when staged changes exist.
code, _, _ = self._run("diff", "--cached", "--quiet")
# `diff --cached --quiet` exits 1 when staged changes exist, so its
# exit code is the answer to "is there anything to commit?" rather
# than a fault. It calls git directly to stay out of `_run`, which
# reports every non-zero exit as a failure and would therefore
# announce a broken mirror on every cycle that had work to do.
code, _, _ = run_git(self.path, "diff", "--cached", "--quiet", env=self._env)
if code != 0:
rc, _, _ = self._run(
"-c", f"user.name={_BRAIN_AUTHOR_NAME}",
Expand Down
37 changes: 37 additions & 0 deletions tests/stacklets/test_memory_curator_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,21 @@ def warnings_logged():
logger.remove(sink_id)


@pytest.fixture
def debug_logged():
"""Everything the curator says, DEBUG included.

`warnings_logged` deliberately starts at WARNING. The line pinned
below only ever appears at DEBUG, so it needs its own sink.
"""
from loguru import logger

lines: list[str] = []
sink_id = logger.add(lines.append, level="DEBUG")
yield lines
logger.remove(sink_id)


class TestVaultSync:
"""The curator's vault sync: source policy, one auth retry, loud."""

Expand Down Expand Up @@ -414,3 +429,25 @@ async def test_a_push_that_cannot_land_is_reported_not_forced(
assert any("not reaching Forgejo" in line for line in warnings_logged)
# The commit is still here for the next cycle to deliver.
assert "brain: project" in _log_subjects(local)

async def test_a_routine_commit_does_not_report_git_as_failing(
self, git_healthy_clone, tmp_path, debug_logged,
):
"""`git diff --cached --quiet` answers with its exit code, and 1
means staged changes exist — the reason to commit, not a fault.
Reporting it as "brain git diff failed" told anyone reading the
curator's log that the mirror was broken at exactly the moments
it was working, which is worse than silence.
"""
from curator import CURATOR_REMOTE, Brain

local = git_healthy_clone.local
_git(local, "remote", "add", CURATOR_REMOTE,
str(git_healthy_clone.remote))
(local / "index.md").write_text("generated\n", encoding="utf-8")

pushed = await Brain(local, tmp_path / "source").commit_push("brain: project")

assert pushed is True
assert "brain: project" in _log_subjects(local)
assert [ln for ln in debug_logged if "git diff failed" in ln] == []
Loading