From 1fdce730543627c850b79a4e1e55846486b6f6c1 Mon Sep 17 00:00:00 2001 From: Nolan Date: Sat, 4 Jul 2026 23:07:35 +0800 Subject: [PATCH] fix: /diff shows changes since the most recent message, not the previous one raw_cmd_diff used commit_before_message[-2] as the diff base, but that entry is the head recorded before the PREVIOUS message. Once two or more messages had been processed in a session, /diff (and the auto-shown post-commit diff) displayed changes accumulated since the previous message rather than the current one. For messages that produced multiple commits (reflections), the old `current_head + "^"` fallback only went back a single commit, so it showed just the last reflection's diff. Use commit_before_message[-1] (matching show_undo_hint) and fall back to `current_head + "^"` only when no message has been recorded yet. Adds a regression test. --- aider/commands.py | 4 ++-- tests/basic/test_commands.py | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/aider/commands.py b/aider/commands.py index 3881403c5c1..73e24e9c4fa 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -671,10 +671,10 @@ def raw_cmd_diff(self, args=""): self.io.tool_error("Unable to get current commit. The repository might be empty.") return - if len(self.coder.commit_before_message) < 2: + if not self.coder.commit_before_message: commit_before_message = current_head + "^" else: - commit_before_message = self.coder.commit_before_message[-2] + commit_before_message = self.coder.commit_before_message[-1] if not commit_before_message or commit_before_message == current_head: self.io.tool_warning("No changes to display since the last message.") diff --git a/tests/basic/test_commands.py b/tests/basic/test_commands.py index 406e928ebf2..c01928609a0 100644 --- a/tests/basic/test_commands.py +++ b/tests/basic/test_commands.py @@ -1714,6 +1714,51 @@ def test_cmd_diff(self): self.assertIn("-Further modified content", diff_output) self.assertIn("+Final modified content", diff_output) + def test_cmd_diff_since_last_message_not_previous(self): + """/diff must diff from the head recorded before the MOST RECENT message + (commit_before_message[-1]), not the one before it ([-2]). + + Regression: raw_cmd_diff used commit_before_message[-2], so once two + messages had been processed in a session, /diff (and the auto-shown + post-commit diff) displayed changes accumulated since the *previous* + message rather than the current one. show_undo_hint already uses [-1]. + """ + with GitTemporaryDirectory() as repo_dir: + repo = git.Repo(repo_dir) + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + fname = "f.txt" + fpath = Path(repo_dir) / fname + + def commit(content): + fpath.write_text(content) + repo.git.add(fname) + repo.git.commit("-m", content) + + commit("v0\n") # C0 + c0 = repo.head.commit.hexsha + commit("v1\n") # C1 + c1 = repo.head.commit.hexsha + commit("v2\n") # C2 <- HEAD + + # Two messages processed in this session; the head recorded before + # the most recent message is C1. + coder.commit_before_message = [c0, c1] + + with mock.patch("builtins.print") as mock_print: + commands.cmd_diff("") + + # cmd_diff prints the unified diff via builtin print (the + # "Diff since ..." header goes through the IO console instead). + diff_output = mock_print.call_args[0][0] + + # Base must be C1 ([-1]) -> diff is v1..v2; not C0 ([-2]) -> v0..v2. + self.assertIn("-v1", diff_output) + self.assertIn("+v2", diff_output) + self.assertNotIn("-v0", diff_output) + def test_cmd_model(self): io = InputOutput(pretty=False, fancy_input=False, yes=True) coder = Coder.create(self.GPT35, None, io)