Fix bug and type errors in the ahead/behind logic

4eaa3dddd63389489930c933e2fb2e90d60c5520

Tucker McKnight <tucker@pangolin.lan> | Tue Jan 20 2026

Fix bug and type errors in the ahead/behind logic

Also display the ahead/behidn count on the branches page.
js_templates/branches.ts:19
Before
18
19
20



21
22
23
                  ${branch.branchName === data.branchInfo.branchName ? '<div class="badge rounded-pill bg-secondary mx-1">current</div>' : ''}
                  ${branch.branchName === data.reposConfig.repos[branch.repoName].defaultBranch ? '<div class="badge rounded-pill bg-info text-dark mx-1">default</div>' : ''}
                </div>
⁣
⁣
⁣
                <div class="card-body">${branch.description || ''}</div>
              </div>
            `
            : ''
After
18
19
20
21
22
23
24
25
26
                  ${branch.branchName === data.branchInfo.branchName ? '<div class="badge rounded-pill bg-secondary mx-1">current</div>' : ''}
                  ${branch.branchName === data.reposConfig.repos[branch.repoName].defaultBranch ? '<div class="badge rounded-pill bg-info text-dark mx-1">default</div>' : ''}
                </div>
                <div class="card-body">
                  <p>${branch.description || ''}</p>
                  <p>${branch.ahead} commits ahead, ${branch.behind} commits behind <span class="font-monospace">${branch.compareTo}</span></p>
                </div>
              </div>
            `
            : ''
src/branches.ts:13
Before
12
13
14
15



16
17
18
19
      const result = {
        branchName: branch.name,
        repoName: repo.name,
      }
⁣
⁣
⁣
      if (branch.description) { result['description'] = branch.description }
      if (branch.compareTo) { result['compareTo'] = branch.compareTo }
      return result
    })
  })
After
12
13
14

15
16
17
18
19
20
21
      const result = {
        branchName: branch.name,
        repoName: repo.name,
⁣
        compareTo: branch.compareTo,
        ahead: branch.ahead,
        behind: branch.behind,
      }
      if (branch.description) { result['description'] = branch.description }
      return result
    })
  })
src/dataTypes.ts:6
Before
5
6
7


8
9
10
  branches: Array<{
    name: string,
    description?: string,
⁣
⁣
    compareTo?: string,
    head: string,
    fileList: Array<string>,
  }>,
After
5
6
7
8
9
10
11
12
  branches: Array<{
    name: string,
    description?: string,
    ahead: number,
    behind: number,
    compareTo: string,
    head: string,
    fileList: Array<string>,
  }>,
src/repos.ts:121
Before
120
121
122
123
124
125
126
127
128
      return result
    }))

    branches.forEach((branch) => {
      const branchDescription = branchesToAdd.find(branchToAdd => branchToAdd.name === branch.name)
      const compareTo = branchDescription.compareTo || reposConfig.repos[repoName].defaultBranch
      const compareToBranch = branches.find((test) => test.name = compareTo)

      const compareToBranchCommits = new Set()
      let currentCommit = commits.get(compareToBranch.head)
After
120
121
122
123
124
125
126
127
128
      return result
    }))

    const branchesWithCompareToInfo: Repository['branches'] = branches.map((branch) => {
      const branchDescription = branchesToAdd.find(branchToAdd => branchToAdd.name === branch.name)
      const compareTo = branchDescription.compareTo || reposConfig.repos[repoName].defaultBranch
      const compareToBranch = branches.find((test) => test.name === compareTo)

      const compareToBranchCommits = new Set()
      let currentCommit = commits.get(compareToBranch.head)
src/repos.ts:142
Before
141
142
143
144
145
146

147
148
149



150
151
152
153
154
155
156
157

      // At this point, we have all commits in the compareTo branch in one set, and
      // all commits from this branch in another set.
      const onlyInThisBranch = thisBranchCommits.difference(compareToBranchCommits).size
      const onlyInCompareToBranch = compareToBranchCommits.difference(thisBranchCommits).size
      branch['ahead'] = onlyInThisBranch
      branch['behind'] = onlyInCompareToBranch
      branch['compareTo'] = compareTo
⁣
⁣
⁣
    })

    cachedRepos.push({
      name: repoName,
      description: reposConfig.repos[repoName].description,
      branches,
      cloneUrl: cloneUrl.cloneUrl(reposConfig.baseUrl, repoName),
      defaultBranch: reposConfig.repos[repoName].defaultBranch,
      tags: [], // todo
After
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

      // At this point, we have all commits in the compareTo branch in one set, and
      // all commits from this branch in another set.
      const onlyInThisBranch = Array.from(thisBranchCommits).filter(thisBranchCommit => !compareToBranchCommits.has(thisBranchCommit)).length
      const onlyInCompareToBranch = Array.from(compareToBranchCommits).filter(compareToBranchCommit => !thisBranchCommits.has(compareToBranchCommit)).length

      const compareToInfo = {
        ahead: onlyInThisBranch,
        behind: onlyInCompareToBranch,
        compareTo: compareTo,
      }

      return {...branch, ...compareToInfo}
    })

    cachedRepos.push({
      name: repoName,
      description: reposConfig.repos[repoName].description,
      branches: branchesWithCompareToInfo,
      cloneUrl: cloneUrl.cloneUrl(reposConfig.baseUrl, repoName),
      defaultBranch: reposConfig.repos[repoName].defaultBranch,
      tags: [], // todo