From 9bbf603c864f5e4ccdfc5c45572ce8e61161543b Mon Sep 17 00:00:00 2001 From: Jay Hemnani <193022578+jayhemnani9910@users.noreply.github.com> Date: Fri, 2 Oct 2026 00:38:57 +0530 Subject: [PATCH 1/2] fix(git): keep the merge parent when git_commit concludes a merge After a conflicted merge was resolved and staged, git_commit created a commit with only HEAD as its parent and left MERGE_HEAD behind, so the merged branch's history was silently dropped and status still reported an unfinished merge. When MERGE_HEAD exists, commit with it as an extra parent and clear the merge state, as `git commit` does. --- src/git/src/mcp_server_git/server.py | 10 +++++++++- src/git/tests/test_server.py | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/git/src/mcp_server_git/server.py b/src/git/src/mcp_server_git/server.py index b94af84661..f8f978cd42 100644 --- a/src/git/src/mcp_server_git/server.py +++ b/src/git/src/mcp_server_git/server.py @@ -126,7 +126,15 @@ def git_diff(repo: git.Repo, target: str, context_lines: int = DEFAULT_CONTEXT_L return repo.git.diff(f"--unified={context_lines}", target) def git_commit(repo: git.Repo, message: str) -> str: - commit = repo.index.commit(message) + # During a merge, keep the merged-in commits as parents and clear the merge state, like `git commit`. + merge_head = Path(repo.git_dir) / "MERGE_HEAD" + if merge_head.exists(): + parents = [repo.head.commit, *(repo.commit(sha) for sha in merge_head.read_text().split())] + commit = repo.index.commit(message, parent_commits=parents) + for name in ("MERGE_HEAD", "MERGE_MSG", "MERGE_MODE"): + (Path(repo.git_dir) / name).unlink(missing_ok=True) + else: + commit = repo.index.commit(message) return f"Changes committed successfully with hash {commit.hexsha}" def git_add(repo: git.Repo, files: list[str]) -> str: diff --git a/src/git/tests/test_server.py b/src/git/tests/test_server.py index 05d5931466..59a83326ab 100644 --- a/src/git/tests/test_server.py +++ b/src/git/tests/test_server.py @@ -236,6 +236,27 @@ def test_git_log_default(test_repository): assert len(result) >= 1 assert "initial commit" in result[0] +def test_git_commit_concludes_a_merge(test_repository): + main = test_repository.active_branch + test_repository.git.checkout("-b", "feature") + Path(test_repository.working_dir, "test.txt").write_text("feature") + test_repository.index.add(["test.txt"]) + feature_commit = test_repository.index.commit("feature change") + main.checkout() + Path(test_repository.working_dir, "test.txt").write_text("main") + test_repository.index.add(["test.txt"]) + main_commit = test_repository.index.commit("main change") + with pytest.raises(git.GitCommandError): + test_repository.git.merge("feature") + + Path(test_repository.working_dir, "test.txt").write_text("resolved") + test_repository.git.add("test.txt") + git_commit(test_repository, "merge feature") + + merge_commit = test_repository.head.commit + assert merge_commit.parents == (main_commit, feature_commit) + assert not Path(test_repository.git_dir, "MERGE_HEAD").exists() + def test_git_create_branch(test_repository): result = git_create_branch(test_repository, "new-feature-branch") From 1a649232776341cff51ca5a5d3b1079ecef3eab5 Mon Sep 17 00:00:00 2001 From: Jay Hemnani <193022578+jayhemnani9910@users.noreply.github.com> Date: Fri, 2 Oct 2026 18:54:30 +0530 Subject: [PATCH 2/2] test(git): give the merge test a committer identity git merge needs user.name and user.email. CI has none, so the merge stopped before writing MERGE_HEAD and the test never saw a merge. --- src/git/tests/test_server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/git/tests/test_server.py b/src/git/tests/test_server.py index 59a83326ab..8eea776066 100644 --- a/src/git/tests/test_server.py +++ b/src/git/tests/test_server.py @@ -237,6 +237,9 @@ def test_git_log_default(test_repository): assert "initial commit" in result[0] def test_git_commit_concludes_a_merge(test_repository): + with test_repository.config_writer() as config: + config.set_value("user", "name", "Test User") + config.set_value("user", "email", "test@example.com") main = test_repository.active_branch test_repository.git.checkout("-b", "feature") Path(test_repository.working_dir, "test.txt").write_text("feature")