Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nullclaw/nullclaw/llms.txt
Use this file to discover all available pages before exploring further.
Git Operations
The git_operations tool provides structured Git operations with comprehensive input sanitization and workspace scoping.
Supported operations:
status — Show working tree status
diff — Show file differences
log — View commit history
branch — List branches
commit — Create commit
add — Stage files
checkout — Switch branches
stash — Stash changes
Security features:
- Command injection prevention
- Workspace path scoping with
cwd override
- Commit message truncation
- Branch name validation
Parameters
Git operation: status, diff, log, branch, commit, add, checkout, or stash
Commit message (required for commit operation)
File paths to stage (required for add operation)
Branch name (required for checkout operation)
Files to diff (defaults to . for all files)
Show staged changes for diff operation (default: false)
Number of log entries (default: 10, max: 1000)
Repository directory (absolute path within allowed paths; defaults to workspace)
Configuration
const gt = try allocator.create(git.GitTool);
gt.* = .{
.workspace_dir = "/path/to/workspace",
.allowed_paths = &.{}, // Additional repo paths
};
Operations
status
Show working tree status in porcelain v2 format.
Usage:
{
"tool": "git_operations",
"operation": "status"
}
Response:
# branch.oid 7a3b8c1d2e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b
# branch.head main
# branch.upstream origin/main
# branch.ab +0 -0
1 .M N... 100644 100644 100644 da39a3e... da39a3e... src/main.zig
? untracked.txt
Command:
git status --porcelain=2 --branch
diff
Show file differences.
Usage (unstaged changes):
{
"tool": "git_operations",
"operation": "diff",
"files": "src/main.zig"
}
Response:
diff --git a/src/main.zig b/src/main.zig
index 1234567..abcdefg 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,3 +1,4 @@
const std = @import("std");
+const config = @import("config.zig");
pub fn main() !void {
Usage (staged changes):
{
"tool": "git_operations",
"operation": "diff",
"cached": true
}
Command:
git diff --unified=3 --cached -- .
log
View commit history.
Usage:
{
"tool": "git_operations",
"operation": "log",
"limit": 5
}
Response:
7a3b8c1d|Alice|alice@example.com|2026-03-01 12:00:00 -0800|Add git operations tool
6f5e4d3c|Bob|bob@example.com|2026-03-01 11:30:00 -0800|Update documentation
5e4d3c2b|Alice|alice@example.com|2026-02-28 16:45:00 -0800|Fix memory leak in shell tool
4d3c2b1a|Bob|bob@example.com|2026-02-28 14:20:00 -0800|Add browser tool tests
3c2b1a9e|Alice|alice@example.com|2026-02-28 10:15:00 -0800|Initial commit
Format: hash|author|email|date|message
Command:
git log -5 --pretty=format:%H|%an|%ae|%ad|%s --date=iso
branch
List branches with current branch indicator.
Usage:
{
"tool": "git_operations",
"operation": "branch"
}
Response:
main|*
feature-browser|
fix-memory-leak|
Format: branch_name|* (asterisk indicates current branch)
Command:
git branch --format=%(refname:short)|%(HEAD)
commit
Create a commit with staged changes.
Usage:
{
"tool": "git_operations",
"operation": "commit",
"message": "Add git operations tool with input sanitization"
}
Response:
Committed: Add git operations tool with input sanitization
Command:
git commit -m "Add git operations tool with input sanitization"
Commit message truncation:
- Messages truncated to 2000 bytes
- UTF-8 boundary-aware truncation
- Prevents extremely long commit messages
Example: Long message
{
"tool": "git_operations",
"operation": "commit",
"message": "[2000+ characters]"
}
Truncated at UTF-8 boundary near 2000 bytes.
Empty commit messages are rejected: “Commit message cannot be empty”
add
Stage files for commit.
Usage:
{
"tool": "git_operations",
"operation": "add",
"paths": "src/tools/git.zig"
}
Response:
Staged: src/tools/git.zig
Multiple files:
{
"tool": "git_operations",
"operation": "add",
"paths": "src/*.zig"
}
Response:
Command:
git add -- src/tools/git.zig
Note: -- separator prevents path injection
checkout
Switch to a different branch.
Usage:
{
"tool": "git_operations",
"operation": "checkout",
"branch": "feature-browser"
}
Response:
Switched to branch: feature-browser
Command:
git checkout feature-browser
Branch name validation:
Branch names are validated to prevent injection:
- Blocked:
;, |, `, $()
- Allowed:
a-z, A-Z, 0-9, /, -, _, .
Example: Blocked injection
{
"tool": "git_operations",
"operation": "checkout",
"branch": "main; rm -rf /"
}
Response:
Unsafe git arguments detected
stash
Stash uncommitted changes.
Push/save stash:
{
"tool": "git_operations",
"operation": "stash",
"action": "push"
}
Response:
Saved working directory and index state WIP on main: 7a3b8c1 Add git tool
Pop stash:
{
"tool": "git_operations",
"operation": "stash",
"action": "pop"
}
Response:
On branch main
Changes not staged for commit:
modified: src/main.zig
Dropped refs/stash@{0} (7a3b8c1d)
List stashes:
{
"tool": "git_operations",
"operation": "stash",
"action": "list"
}
Response:
stash@{0}: WIP on main: 7a3b8c1 Add git tool
stash@{1}: WIP on feature: 6f5e4d3 Update docs
Default action: push
Command Sanitization
All string arguments are sanitized before passing to Git to prevent command injection.
Blocked Patterns
Dangerous git options:
--exec=cmd — Execute arbitrary command
--upload-pack=cmd — Remote command execution
--receive-pack=cmd — Remote command execution
--pager=cmd — Pager command injection
--editor=cmd — Editor command injection
-c key=value — Config injection
--no-verify — Bypass hooks
Shell metacharacters:
; — Command separator
| — Pipe
> < — Redirection
` — Backtick execution
$() — Command substitution
Examples
Blocked: Config injection
{
"tool": "git_operations",
"operation": "commit",
"message": "-c core.sshCommand=evil"
}
Response:
Unsafe git arguments detected
Blocked: Command substitution
{
"tool": "git_operations",
"operation": "add",
"paths": "$(whoami)"
}
Response:
Unsafe git arguments detected
Allowed: Normal paths
{
"tool": "git_operations",
"operation": "add",
"paths": "src/main.zig"
}
Allowed ✓
Working Directory Control
Default: workspace_dir
By default, git operations run in workspace_dir:
{
"tool": "git_operations",
"operation": "status"
}
Runs git status in /workspace
Custom cwd (within workspace)
{
"tool": "git_operations",
"operation": "log",
"cwd": "/workspace/subproject"
}
Runs git log in /workspace/subproject
Custom cwd (outside workspace)
Requires allowed_paths configuration:
gt.* = .{
.workspace_dir = "/workspace",
.allowed_paths = &.{
"/data/repos",
"/home/user/projects",
},
};
{
"tool": "git_operations",
"operation": "status",
"cwd": "/data/repos/project-a"
}
Allowed (in allowed_paths)
{
"tool": "git_operations",
"operation": "status",
"cwd": "/tmp/repo"
}
Blocked:
cwd is outside allowed areas
cwd Validation Rules
cwd must be an absolute path
cwd must be within workspace_dir or allowed_paths
cwd is resolved with realpathAlloc() to prevent symlink escapes
- Relative
cwd is rejected: “cwd must be an absolute path”
Error Handling
Repository Not Found
{
"tool": "git_operations",
"operation": "status",
"cwd": "/workspace/not-a-repo"
}
Response:
fatal: not a git repository (or any of the parent directories): .git
Nothing to Commit
{
"tool": "git_operations",
"operation": "commit",
"message": "Empty commit"
}
Response:
On branch main
nothing to commit, working tree clean
Branch Not Found
{
"tool": "git_operations",
"operation": "checkout",
"branch": "nonexistent-branch"
}
Response:
error: pathspec 'nonexistent-branch' did not match any file(s) known to git
No Files to Add
{
"tool": "git_operations",
"operation": "add",
"paths": "nonexistent.txt"
}
Response:
fatal: pathspec 'nonexistent.txt' did not match any files
Use Cases
Check Status Before Commit
{
"tool": "git_operations",
"operation": "status"
}
Stage and Commit Changes
[
{
"tool": "git_operations",
"operation": "add",
"paths": "src/tools/git.zig"
},
{
"tool": "git_operations",
"operation": "commit",
"message": "Add git operations tool"
}
]
View Recent Commits
{
"tool": "git_operations",
"operation": "log",
"limit": 10
}
Switch Branch
{
"tool": "git_operations",
"operation": "checkout",
"branch": "feature-branch"
}
Stash Before Switching
[
{
"tool": "git_operations",
"operation": "stash",
"action": "push"
},
{
"tool": "git_operations",
"operation": "checkout",
"branch": "main"
}
]
Review Staged Changes
{
"tool": "git_operations",
"operation": "diff",
"cached": true
}
Source
src/tools/git.zig:10-335
Testing
Run git tool tests:
zig build test --summary all
Tests cover:
- All operations (status, diff, log, branch, commit, add, checkout, stash)
- Command sanitization (injection prevention)
- Working directory validation
- Error cases
- Commit message truncation
- Branch name validation