From f60d13a861aea219bbb736ed1552cfe1d1494efe Mon Sep 17 00:00:00 2001 From: Vidit Patankar Date: Sun, 31 May 2026 14:21:31 +0530 Subject: [PATCH] fix(git): correct field alignment in git_log timestamp filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timestamp-filtered branch of git_log used --format=%H%n%an%n%ad%n%s%n. The trailing %n emits a blank line after each commit, so git produced 5 lines per commit while the parser strides by 4 ("groups of 4"). Every commit after the first was shifted by one line — its hash, author, date and subject landed in the wrong fields and the subject of the last in-range commit was dropped. Remove the trailing %n so each commit is exactly four lines, matching the parser. Adds a regression test with two timestamped commits. --- src/git/src/mcp_server_git/server.py | 2 +- src/git/tests/test_server.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/git/src/mcp_server_git/server.py b/src/git/src/mcp_server_git/server.py index 5ce953e545..f6fe465f22 100644 --- a/src/git/src/mcp_server_git/server.py +++ b/src/git/src/mcp_server_git/server.py @@ -154,7 +154,7 @@ def git_log(repo: git.Repo, max_count: int = 10, start_timestamp: Optional[str] args.extend(['--since', start_timestamp]) if end_timestamp: args.extend(['--until', end_timestamp]) - args.extend(['--format=%H%n%an%n%ad%n%s%n']) + args.extend(['--format=%H%n%an%n%ad%n%s']) log_output = repo.git.log(*args).split('\n') diff --git a/src/git/tests/test_server.py b/src/git/tests/test_server.py index a5492adc85..87d4960e3b 100644 --- a/src/git/tests/test_server.py +++ b/src/git/tests/test_server.py @@ -482,3 +482,27 @@ def test_git_branch_rejects_contains_flag_injection(test_repository): with pytest.raises(BadName): git_branch(test_repository, "local", not_contains="--exec=evil") + + +def test_git_log_timestamp_filter_aligns_commit_fields(tmp_path): + """git_log with a timestamp filter must not scramble fields across commits.""" + repo_path = tmp_path / "ts_repo" + repo = git.Repo.init(repo_path) + author = git.Actor("Tester", "tester@example.com") + (repo_path / "f.txt").write_text("a") + repo.index.add(["f.txt"]) + repo.index.commit("first commit", author=author, commit_date="2024-01-10T10:00:00") + (repo_path / "f.txt").write_text("b") + repo.index.add(["f.txt"]) + repo.index.commit("second commit", author=author, commit_date="2024-01-20T10:00:00") + + result = git_log(repo, start_timestamp="2024-01-01") + + assert len(result) == 2 + joined = "\n".join(result) + # Both subjects appear in Message fields (none dropped or shifted). + assert "Message: second commit" in joined + assert "Message: first commit" in joined + # Author appears only in Author fields, never shifted into Commit/Date. + assert "Commit: Tester" not in joined + assert "Author: Tester" in joined