Tucker McKnight <tmcknight@instructure.com> | Thu Jun 18 2026
Chunk command output when reading git show and git blame Previously, large files were causing it to crash with an stdout buffer overflow error.
194 195 196 197 198 199 200
})
eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString: string, branchName: string) => {
const renderer = eleventyConfig?.javascript?.functions?.renderContent
if (renderer) {
return await renderer.bind({
data: {
branch: branchName194 195 196 197 198 199 200 201
})
eleventyConfig.addAsyncFilter("renderContentIfAvailable", async (contentString: string, branchName: string) => {
// TODO: give the user an option to skip this. E.g. when doing the 11ty repo, complains about missing tags.
const renderer = eleventyConfig?.javascript?.functions?.renderContent
if (false && renderer) {
return await renderer.bind({
data: {
branch: branchName0 1
i
mport escape from 'escape-html'
import * as Diff from 'diff'
import {type Repository} from './dataTypes.ts'0 1 2
import childProcess from 'child_process'
import escape from 'escape-html'
import * as Diff from 'diff'
import {type Repository} from './dataTypes.ts'49 50 51 52 53 54
if (str.startsWith(' ')) { return str.replace(" ", "") }
}).join("\n")
const changeObject = Diff.diffWordsWithSpace(lastHunkBefore, lastHunkAfter)
let beforeText = ""
let afterText = ""
49 50 51 52 53 54 55 56
if (str.startsWith(' ')) { return str.replace(" ", "") }
}).join("\n")
const changeObject = (lastHunkBefore.length > 1000 || lastHunkAfter.length > 1000)
? []
: Diff.diffWordsWithSpace(lastHunkBefore, lastHunkAfter)
let beforeText = ""
let afterText = ""
98 99 100 101 102 103
return outputDir + (reposConfig.path || "") + "/" + slugify(repoName) + ".git"
}
export {
getGitDiffsFromPatchText,
getLocation,
}98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
return outputDir + (reposConfig.path || "") + "/" + slugify(repoName) + ".git"
}
const readChunkedCommandOutput = async (executable, args): Promise<string> => {
return new Promise((resolve) => {
const cmd = childProcess.spawn(executable, args, {
stdio: [0, "pipe", "inherit"],
})
let output = ""
cmd.stdout.on('data', (data) => {
output = output + data
})
cmd.on('close', () => {
resolve(output)
})
})
}
export {
getGitDiffsFromPatchText,
getLocation,
readChunkedCommandOutput,
}8 9 10 11 12 13
import { type Repository, type FileInfo } from './dataTypes.ts'
import cloneUrl from './vcses/git/helpers.ts'
import { addBranchToCommitsMap } from './vcses/git/operations.ts'
import { getLocation} from './helpers.ts'
import { getFileList, getFileLastTouchInfo } from './vcses/git/operations.ts'
const exec = util.promisify(childProcess.exec)8 9 10 11 12 13
import { type Repository, type FileInfo } from './dataTypes.ts'
import cloneUrl from './vcses/git/helpers.ts'
import { addBranchToCommitsMap } from './vcses/git/operations.ts'
import { getLocation, readChunkedCommandOutput } from './helpers.ts'
import { getFileList, getFileLastTouchInfo } from './vcses/git/operations.ts'
const exec = util.promisify(childProcess.exec)250 251 252 253 254 255 256
currentCommit = commits.get(currentCommit.parent)
}
}
const gitShowCmd = `git -C ${repoLocation} show ${sha}:${filename}`
const fileContents = (await exec(gitShowCmd)).stdout
const blameLines = await getFileLastTouchInfo(filename, sha, repoLocation)
const commit = {
contents: fileContents,250 251 252 253 254 255
currentCommit = commits.get(currentCommit.parent)
}
}
const fileContents = await readChunkedCommandOutput('git', ['-C', repoLocation, 'show', `${sha}:${filename}`])
const blameLines = await getFileLastTouchInfo(filename, sha, repoLocation)
const commit = {
contents: fileContents,0 1 2 3 4 5
import util from 'util'
import childProcess from 'child_process'
const exec = util.promisify(childProcess.exec)
import { getGitDiffsFromPatchText} from '../../helpers.ts'
import { type Repository } from '../../dataTypes.ts'
export const getFileList = async (0 1 2 3 4 5
import util from 'util'
import childProcess from 'child_process'
const exec = util.promisify(childProcess.exec)
import { getGitDiffsFromPatchText, readChunkedCommandOutput } from '../../helpers.ts'
import { type Repository } from '../../dataTypes.ts'
export const getFileList = async (99 100 101 102 103
return !line.startsWith('Ignore-this: ')
}).join("\n").trim()
const diffs = getGitDiffsFromPatchText(currentPatch.slice(diffStart).join("\n"))
commits.set(hash, {
hash,99 100 101 102 103 104
return !line.startsWith('Ignore-this: ')
}).join("\n").trim()
// TODO: this is very slow on commits that have a huge 20k line package-lock.json change
const diffs = getGitDiffsFromPatchText(currentPatch.slice(diffStart).join("\n"))
commits.set(hash, {
hash,122 123 124 125 126 127 128 129
filename: string, sha: string, repoLocation: string
) : Promise<Array<BlameInfo>> => {
const regex = RegExp(".* [0-9]+ [0-9]+")
const command = `git -C ${repoLocation} blame --porcelain ${sha} ${filename}`
const res = await exec(command)
const output = res.stdout
const outputLines = output.split("\n")
const initialValue: Array<Array<string>> = [[outputLines[0]]]
const chunked = outputLines.reduce((accumulator, currentLine, currentIndex) => {122 123 124 125 126 127
filename: string, sha: string, repoLocation: string
) : Promise<Array<BlameInfo>> => {
const regex = RegExp(".* [0-9]+ [0-9]+")
const output = await readChunkedCommandOutput('git', ['-C', repoLocation, 'blame', '--porcelain', sha, filename])
const outputLines = output.split("\n")
const initialValue: Array<Array<string>> = [[outputLines[0]]]
const chunked = outputLines.reduce((accumulator, currentLine, currentIndex) => {