MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / execute

Method execute

src/tools/git/commit.ts:36–100  ·  view source on GitHub ↗
(args: z.infer<typeof GitCommitArgs>, ctx: ToolContext)

Source from the content-addressed store, hash-verified

34 argsSchema = GitCommitArgs;
35
36 async execute(args: z.infer<typeof GitCommitArgs>, ctx: ToolContext): Promise<ToolResult> {
37 if (!await isGitRepo(ctx.cwd, ctx.signal)) {
38 return { content: '[NOT_A_GIT_REPO] Current directory is not inside a git working tree.', isError: true };
39 }
40
41 // Stage if requested
42 if (args.paths && args.paths.length > 0) {
43 const addR = await git(['add', '--', ...args.paths], { cwd: ctx.cwd, signal: ctx.signal });
44 if (addR.exitCode !== 0) {
45 return { content: `[ERROR] git add failed: ${addR.stderr.trim()}`, isError: true };
46 }
47 } else if (args.stage_all) {
48 const addR = await git(['add', '-u'], { cwd: ctx.cwd, signal: ctx.signal });
49 if (addR.exitCode !== 0) {
50 return { content: `[ERROR] git add -u failed: ${addR.stderr.trim()}`, isError: true };
51 }
52 }
53
54 // Safety: bail if nothing staged (unless amending or empty allowed)
55 if (!args.amend && !args.allow_empty) {
56 const stagedR = await git(['diff', '--cached', '--quiet'], { cwd: ctx.cwd, signal: ctx.signal });
57 // diff --cached --quiet exits 0 when no diff, 1 when there's a diff
58 if (stagedR.exitCode === 0) {
59 return {
60 content: '[NOTHING_STAGED] No changes are staged for commit. ' +
61 'Use `paths` or `stage_all=true` to stage first, or call `git_status` to inspect the working tree.',
62 isError: true,
63 };
64 }
65 }
66
67 // Build commit args
68 const commitArgs = ['commit', '-F', '-'];
69 if (args.amend) commitArgs.push('--amend');
70 if (args.allow_empty) commitArgs.push('--allow-empty');
71 if (args.sign_off) commitArgs.push('--signoff');
72
73 const r = await git(commitArgs, {
74 cwd: ctx.cwd,
75 signal: ctx.signal,
76 stdin: args.message,
77 timeoutMs: 120_000, // pre-commit hooks can take a while
78 });
79
80 if (r.exitCode !== 0) {
81 // Pre-commit hook failure or other reason — bubble both streams so the model sees lint output
82 return {
83 content: `[COMMIT_FAILED] git commit exited ${r.exitCode}.\n${r.stderr.trim()}\n${r.stdout.trim()}`.trim(),
84 isError: true,
85 };
86 }
87
88 // Fetch the resulting commit SHA + subject for the result
89 const showR = await git(['log', '-1', '--pretty=format:%h%x00%s'], { cwd: ctx.cwd, signal: ctx.signal });
90 let summary = r.stdout.trim();
91 if (showR.exitCode === 0 && showR.stdout) {
92 const [sha, subject] = showR.stdout.split('\x00');
93 summary = `Created commit ${sha}: ${subject}`;

Callers

nothing calls this directly

Calls 3

isGitRepoFunction · 0.85
gitFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected