Only read from locally-cloned repo for operations that require local repos

c617a3ccbc54c566548bb3dbcecb72a47e2833b8

Tucker McKnight <tmcknight@instructure.com> | Sat Jun 20 2026

Only read from locally-cloned repo for operations that require local repos

Commands called with `git -C` would fail if the location in the repo config
was a remote URL. This is because `git -C` only works on local repos.

For git commands that require a local repo, we need to only call then on
the already-cloned, local repository. (This is what we should be doing all
the time anyway.)

Some functions now have to know the slugify function and output directory,
then, in order to find the path to the cloned repo.

This should be done more cleanly in the future, like with a globally-available
"localRepoPath" function.
main.ts:37
Before
After
main.ts:57
Before
After
main.ts:112
Before
After
main.ts:130
Before
129
130
131
132
133
134
              // Run the command for each step in each branch
              await exec(`(cd ${tempDirRepoPath} && ${buildStep.command})`)
              // Copy the specified folders from the "from" to the "to" dir
              await exec(`cp -r ${tempDirRepoPath}/${buildStep.copyFrom} ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branch)}/${buildStep.copyTo}`)
            }
          }
          for (let tag of tagNames) {
After
129
130
131
132
133
134
              // Run the command for each step in each branch
              await exec(`(cd ${tempDirRepoPath} && ${buildStep.command})`)
              // Copy the specified folders from the "from" to the "to" dir
              await exec(`cp -r ${tempDirRepoPath}/${buildStep.copyFrom} ${directories.output}${slugify(repoName)}/branches/${slugify(branch)}/${buildStep.copyTo}`)
            }
          }
          for (let tag of tagNames) {
main.ts:139
Before
138
139
140
141
142
143
              // Run the command for each step in each branch
              await exec(`(cd ${tempDirRepoPath} && ${buildStep.command})`)
              // Copy the specified folders from the "from" to the "to" dir
              await exec(`cp -r ${tempDirRepoPath}/${buildStep.copyFrom} ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}/tags/${eleventyConfig.getFilter("slugify")(tag)}/${buildStep.copyTo}`)
            }
          }
          // delete the temp dirs
After
138
139
140
141
142
143
              // Run the command for each step in each branch
              await exec(`(cd ${tempDirRepoPath} && ${buildStep.command})`)
              // Copy the specified folders from the "from" to the "to" dir
              await exec(`cp -r ${tempDirRepoPath}/${buildStep.copyFrom} ${directories.output}${slugify(repoName)}/tags/${slugify(tag)}/${buildStep.copyTo}`)
            }
          }
          // delete the temp dirs
src/repos.ts:18
Before
17
18
19
20
21


22
23
24
25

26
27
const tagsForReposMap: Map<string, Array<{name: string}>> = new Map()

const getBranchesAndTags = async (
  repoConfig: GitConfig,
  repoName: string
⁣
⁣
): Promise<{
  branches: Array<{name: string, description?: string, compareTo?: string}>,
  tags: Array<{name: string}>,
}> => {
⁣
  const cachedBranchNames = branchesForReposMap.get(repoName)
  const cachedTagNames = tagsForReposMap.get(repoName)
  if (cachedBranchNames !== undefined) {
After
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const tagsForReposMap: Map<string, Array<{name: string}>> = new Map()

const getBranchesAndTags = async (
  reposConfig: ReposConfiguration,
  repoName: string,
  outputDir: string,
  slugify: Function,
): Promise<{
  branches: Array<{name: string, description?: string, compareTo?: string}>,
  tags: Array<{name: string}>,
}> => {
  const repoConfig = reposConfig.repos[repoName]
  const cachedBranchNames = branchesForReposMap.get(repoName)
  const cachedTagNames = tagsForReposMap.get(repoName)
  if (cachedBranchNames !== undefined) {
src/repos.ts:31
Before
30
31
32



33
34
35
36
  }

  // Get all branches and tags available in the repository
⁣
⁣
⁣
  const allBranches = (await exec(`git -C ${repoConfig.location} branch --format="%(refname:short)"`)).stdout.split("\n").filter(branch => branch !== '')
  const allTags = (await exec(`git -C ${repoConfig.location} tag`)).stdout.split("\n").filter(tag => tag !== '')

  // Sort the list of branch descriptions from `branches` by the length
  // of their patterns.
After
30
31
32
33
34
35
36
37
38
39
  }

  // Get all branches and tags available in the repository
  // Get it from the local, cloned location, instead of the remote, since `git -C` commands
  // don't work on remote locations.
  const clonedLocation = getLocation(reposConfig, outputDir, repoName, slugify) 
  const allBranches = (await exec(`git -C ${clonedLocation} branch --format="%(refname:short)"`)).stdout.split("\n").filter(branch => branch !== '')
  const allTags = (await exec(`git -C ${clonedLocation} tag`)).stdout.split("\n").filter(tag => tag !== '')

  // Sort the list of branch descriptions from `branches` by the length
  // of their patterns.
src/repos.ts:151
Before
150
151
152
153
154
155
  for (const repoName of repoNames) {
    const repoLocation = getLocation(reposConfig, outputDir, repoName, slugify)
    const commits: Repository['commits'] = new Map()
    const branchesAndTags = await getBranchesAndTags(reposConfig.repos[repoName], repoName)
    const branchNames = branchesAndTags.branches.map(branch => branch.name)
    for (const branchName of branchNames) {
      await addBranchToCommitsMap(branchName, repoLocation, commits)
After
150
151
152
153
154
155
  for (const repoName of repoNames) {
    const repoLocation = getLocation(reposConfig, outputDir, repoName, slugify)
    const commits: Repository['commits'] = new Map()
    const branchesAndTags = await getBranchesAndTags(reposConfig, repoName, outputDir, slugify)
    const branchNames = branchesAndTags.branches.map(branch => branch.name)
    for (const branchName of branchNames) {
      await addBranchToCommitsMap(branchName, repoLocation, commits)
src/repos.ts:243
Before
242
243
244


245
246
              break
            }
            if (fileMap.has(`${filename}-${currentCommit.hash}`)) {
⁣
⁣
              return fileMap.get(`${filename}-${currentCommit.hash}`)
            }
After
242
243
244
245
246
247
248
              break
            }
            if (fileMap.has(`${filename}-${currentCommit.hash}`)) {
              // TODO: maybe cache here as well, so that we don't have to loop as many
              // times next time?
              return fileMap.get(`${filename}-${currentCommit.hash}`)
            }
src/repos.ts:257
Before
256
257
258


259
260
          blameLines,
        }

⁣
⁣
        fileMap.set(key, commit)
        return commit
      },
After
256
257
258
259
260
261
262
          blameLines,
        }

// TODO: cache it as deeply in the git history as it can be, so that as many other commits
// benefit from this as possible.
        fileMap.set(key, commit)
        return commit
      },