MCPcopy Create free account
hub / github.com/SIMARSINGHRAYAT/Gitzo / createMultiFileCommitWithCoAuthors

Function createMultiFileCommitWithCoAuthors

src/utils/github.ts:340–427  ·  view source on GitHub ↗
(
  token: string,
  owner: string,
  repo: string,
  branch: string,
  files: { path: string; content: string }[],
  commitMessage: string,
  coAuthors: { name: string; email: string }[]
)

Source from the content-addressed store, hash-verified

338 * This is the core function for Pair Extraordinaire badge.
339 */
340export async function createMultiFileCommitWithCoAuthors(
341 token: string,
342 owner: string,
343 repo: string,
344 branch: string,
345 files: { path: string; content: string }[],
346 commitMessage: string,
347 coAuthors: { name: string; email: string }[]
348) {
349 if (files.length === 0) throw new Error('No files to commit.');
350
351 const base = `/repos/${owner}/${repo}`;
352 const jsonHeaders = { 'Content-Type': 'application/json' };
353
354 // Build commit message with Co-authored-by trailers
355 let fullMessage = commitMessage;
356 if (coAuthors.length > 0) {
357 fullMessage += '\n\n';
358 fullMessage += coAuthors
359 .map(ca => `Co-authored-by: ${ca.name} <${ca.email}>`)
360 .join('\n');
361 }
362
363 // Step 1: Get the current commit SHA that the branch points to
364 const refRes = await ghFetch(`${base}/git/ref/heads/${encodeURIComponent(branch)}`, token);
365 if (!refRes.ok) await handleGitError(refRes, 'Failed to get branch ref');
366 const refData = await refRes.json();
367 const latestCommitSHA: string = refData.object.sha;
368
369 // Step 2: Get the tree SHA of that commit
370 const commitRes = await ghFetch(`${base}/git/commits/${latestCommitSHA}`, token);
371 if (!commitRes.ok) await handleGitError(commitRes, 'Failed to get commit');
372 const commitData = await commitRes.json();
373 const baseTreeSHA: string = commitData.tree.sha;
374
375 // Step 3: Create blobs for EACH file
376 const treeEntries: { path: string; mode: string; type: string; sha: string }[] = [];
377 for (const file of files) {
378 const base64Content = utf8ToBase64(file.content);
379 const blobRes = await ghFetch(`${base}/git/blobs`, token, {
380 method: 'POST',
381 body: JSON.stringify({ content: base64Content, encoding: 'base64' }),
382 headers: jsonHeaders,
383 });
384 if (!blobRes.ok) await handleGitError(blobRes, `Failed to create blob for ${file.path}`);
385 const blobData = await blobRes.json();
386 treeEntries.push({
387 path: file.path,
388 mode: '100644',
389 type: 'blob',
390 sha: blobData.sha,
391 });
392 }
393
394 // Step 4: Create a new tree with ALL file entries
395 const treeRes = await ghFetch(`${base}/git/trees`, token, {
396 method: 'POST',
397 body: JSON.stringify({ base_tree: baseTreeSHA, tree: treeEntries }),

Callers 2

startYOLOBadgeWorkflowFunction · 0.90
startCreatingPairsFunction · 0.90

Calls 3

ghFetchFunction · 0.85
handleGitErrorFunction · 0.85
utf8ToBase64Function · 0.85

Tested by

no test coverage detected