Describe the bug
git_commit reports success when nothing is staged. It creates an empty commit and returns a hash, so a caller cannot tell it apart from a real commit.
src/git/src/mcp_server_git/server.py:128-130:
def git_commit(repo: git.Repo, message: str) -> str:
commit = repo.index.commit(message)
return f"Changes committed successfully with hash {commit.hexsha}"
repo.index.commit() writes a tree from the index unconditionally; GitPython has no --allow-empty gate. The return string cannot be false.
The practical failure: an agent edits files, calls git_commit without git_add — or after a git_add whose paths matched nothing — and gets a hash back. It tells the user the work is committed. The working tree is still dirty, HEAD still holds the old content, and the repository now carries an empty commit.
git commit itself refuses this with "no changes added to commit".
To Reproduce
import git
repo = git.Repo(".") # one tracked file, edited but not staged
commit = repo.index.commit("agent says: fix applied")
print(commit.parents[0].tree.hexsha == commit.tree.hexsha) # True — empty
status before: M a.txt
git_commit -> Changes committed successfully with hash efd05335b0ab
status after: M a.txt
a.txt in HEAD: v1 # the edit was never committed
Expected behavior
Refuse, as git commit does without --allow-empty. Two cases git does permit and that should keep working: the first commit on an unborn branch, and an empty merge commit while MERGE_HEAD is present.
Additional context
No test covers this; test_git_commit stages a file first.
#4761 implements it.
Describe the bug
git_commitreports success when nothing is staged. It creates an empty commit and returns a hash, so a caller cannot tell it apart from a real commit.src/git/src/mcp_server_git/server.py:128-130:repo.index.commit()writes a tree from the index unconditionally; GitPython has no--allow-emptygate. The return string cannot be false.The practical failure: an agent edits files, calls
git_commitwithoutgit_add— or after agit_addwhose paths matched nothing — and gets a hash back. It tells the user the work is committed. The working tree is still dirty,HEADstill holds the old content, and the repository now carries an empty commit.git commititself refuses this with "no changes added to commit".To Reproduce
Expected behavior
Refuse, as
git commitdoes without--allow-empty. Two cases git does permit and that should keep working: the first commit on an unborn branch, and an empty merge commit whileMERGE_HEADis present.Additional context
No test covers this;
test_git_commitstages a file first.#4761 implements it.