feat(git): add git_worktree_add to lean interface (#167)#169
Conversation
The lean git MCP interface exposed git_worktree_list and git_worktree_remove but was missing git_worktree_add. This blocked any workflow that needed to commit on a different branch without disturbing the current working tree — for example, adding a submodule on a configuration branch while WIP exists on a fix branch — forcing agents to fall back to shell-exec MCPs in violation of the "no Bash for git" principle. This change adds git_worktree_add as a thin wrapper around GitPython's repo.git.worktree() with support for four modes: - Detached HEAD at current HEAD (no branch, no new_branch) - Check out an existing branch (branch=...) - Create a new branch from HEAD (new_branch=...) - Create a new branch from a start-point (new_branch=... + branch=...) The force flag adds --force and upgrades -b to -B (force-create) when new_branch is set. Tests cover all four behavior paths.
|
Claude finished @MementoRC's task —— View job PR Review: git_worktree_add ImplementationTodo List:
Review Summary ✅This is a well-implemented feature that adds the missing Code Quality: Excellent ⭐⭐⭐⭐⭐✅ Strengths1. Perfect Pattern Consistency
2. Robust Input Validation
3. Comprehensive Test Coverage
4. Clear API Design
5. Excellent Error Handling
|
The registration entry for git_submodule_add in registry_git.py passed
relative_path_params={"path"} to ToolDefinition(), but the constructor
never accepted that kwarg and _validate_path_parameters never consumed
it. Result: importing the lean interface raised TypeError at startup,
cascading into 36+ test failures across HTTPSessionManager and any path
that instantiated GitLeanInterface (PR #169 CI: Code Quality + Test
Python 3.12 both red).
Changes:
- interface.py: ToolDefinition.__init__ now accepts relative_path_params
(set[str] | None). _validate_path_parameters honors the per-tool
exemption: exempt parameters allow repo-relative values but still
reject empty strings and ".." traversal segments.
- interface.py / meta_tools.py: execute_tool_direct and execute_tool now
forward tool_def.relative_path_params into the validator.
- tests/unit/git/test_submodule_relative_path.py: regression suite for
the exemption mechanism (6 unit tests on the validator, 2 direct
tests on git_submodule_add, 2 integration tests through the lean
interface).
Behavior: submodule paths ("sub-packages/remote-iface") now flow
verbatim through git_submodule_add and land in .gitmodules unmodified,
preserving repo portability. Path traversal and CWD-relative paths in
non-exempt parameters remain rejected.
Co-Authored-By: MementoRC (https://github.com/MementoRC)
|
Claude finished @MementoRC's task —— View job PR Review: git_worktree_add Implementation ✅Todo List:
Review Summary ✅This is a well-implemented feature that adds the missing Code Quality: Excellent ⭐⭐⭐⭐⭐✅ Strengths1. Perfect Pattern Consistency
2. Robust Input Validation
3. Comprehensive Test Coverage
4. Clear API Design
5. Excellent Error Handling
|
Summary
The lean git MCP interface exposed
git_worktree_listandgit_worktree_removebut was missinggit_worktree_add. This blocked any workflow that needed to commit on a different branch without disturbing the current working tree — for example, adding a submodule on a configuration branch while WIP exists on a fix branch — forcing agents to fall back to shell-exec MCPs in violation of the "no Bash for git" principle.Signature
Behavior Matrix
new_branchbranchforcegit worktree add <wt_path>(detached HEAD)git worktree add <wt_path> main--forceto the abovegit worktree add -b feature <wt_path>git worktree add -b feature <wt_path> main-B feature(force-create) AND adds--forceChanges
src/mcp_server_git/git/operations_extended.py-git_worktree_addimplementation with input validation (DANGEROUS_CHARS) and error handling matching the existing worktree functionssrc/mcp_server_git/git/models.py-GitWorktreeAddPydantic modelsrc/mcp_server_git/lean/registry_git.py- tool registration (imports + ToolDefinition)tests/unit/git/test_git_worktree.py-TestGitWorktreeAddwith 8 tests covering all four behavior paths, input validation rejection, and error handlingTest Coverage
test_worktree_add_detached_head- no branch/new_branch -> bareadd <path>test_worktree_add_existing_branch- branch='main' ->add <path> maintest_worktree_add_new_branch- new_branch='feature' -> uses-b, not-Btest_worktree_add_force_new_branch_uses_B- force + new_branch ->-B+--forcetest_worktree_add_new_branch_with_start_point- new_branch + branch -> creates from start-pointtest_worktree_add_rejects_dangerous_chars_in_worktree_path- injection guardtest_worktree_add_handles_git_command_error- GitCommandError handlingtest_worktree_add_handles_general_exception- generic exception handlingCloses #167