Add a dropdown for selecting which version of a file to view

93646ac47527d6d33aeccd640a82ee19eab92ca1

Tucker McKnight <tmcknight@instructure.com> | Sat Aug 15 2026

Add a dropdown for selecting which version of a file to view

If you're looking at a commit, and looking at the diff for a file
that has since been deleted, you'll get a 404 when you click the link
to the file (it was previously just linking to that file in the main
branch and making the assumption that it still exists).

Now you'll get a dropdown menu for selecting which branch or tag
to view the file in.
js_templates/commit.ts:19
Before
18
19
20


21
22
    currentRefType: data.currentRefType,
  })

⁣
⁣
  return await htmlPage(reposConfig, eleventyConfig, data, [
    m('div', {class: "row"},
      m('div', {class: "col-auto"},
After
18
19
20
21
22
23
24
    currentRefType: data.currentRefType,
  })

  const repo = data.currentRepo

  return await htmlPage(reposConfig, eleventyConfig, data, [
    m('div', {class: "row"},
      m('div', {class: "col-auto"},
js_templates/commit.ts:61
Before
60
61
62















63

64
65







66



67

68
69
70
      ])
    ),
    m('div', {class: "row", id: "diffs"}, data.patchInfo.commit.diffs.map((hunk) => {
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
      return m('div', {class: 'hunk'}, [
⁣
        m('span', {class: "font-monospace fw-bold"},
          m('a', {
⁣
⁣
⁣
⁣
⁣
⁣
⁣
            href: nav.file(hunk.fileName)
⁣
⁣
⁣
          }, `${hunk.fileName}:${hunk.lineNumber}`)
⁣
        ),
        m('div', {class: "diff d-flex"}, [
          m('div', {class: "flex-grow-1 diff-left pe-2"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'Before'),
After
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
      ])
    ),
    m('div', {class: "row", id: "diffs"}, data.patchInfo.commit.diffs.map((hunk) => {
      // Search through the available branches and tags, seeing if we have a copy of this
      // file in the filelist for any branch or tag. Put together a list of those for
      // linking to.
      let availableInRefs = repo.branches.filter((ref) => {
        return ref.fileList.has(hunk.fileName)
      }).map((ref) => {
        return { refName: ref.name, refType: 'branch' }
      })

      availableInRefs = availableInRefs.concat(repo.tags.filter((ref) => {
        return ref.fileList.has(hunk.fileName)
      }).map((ref) => {
        return { refName: ref.name, refType: 'tag' }
      }))

      return m('div', {class: 'hunk'}, [
        m('div', [
          m('span', {class: "font-monospace fw-bold me-2"}, `${hunk.fileName}:${hunk.lineNumber}`),
          m('label', {class: 'me-2'}, 'View file in:'),
          m('div', {class: 'dropdown d-inline'}, [
            m('button', {
              class: 'btn btn-bg btn-sm dropdown-toggle',
              ['data-bs-toggle']: 'dropdown',
            }, 'Select...'),
            // TODO: use tabs for branches and tags, like in the top menu?
            // TODO: Have a special case for if availableInRefs is empty (e.g. the file has since been deleted).
            m('ul', {class: 'dropdown-menu'}, availableInRefs.map((ref) => {
              return m('li', {class: 'dropdown-item'}, m('a', {
                href: nav.file(hunk.fileName, ref)
              }, ref.refName))
            }))
          ])
        ]),
        m('div', {class: "diff d-flex"}, [
          m('div', {class: "flex-grow-1 diff-left pe-2"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'Before'),