Remove darcs functionality :(

2376512fc3745b47f8cb9446f92c85d3fe25488b

Tucker McKnight | Sun Oct 12 2025

Remove darcs functionality :(

I'd like to come back to darcs later, when I've come up with a
way of making some kind of plugin system for making this work
with multiple VCSes.

In the meantime, development will be faster if I just focus
on git.
frontend/main.ts:62
Before
62
63
64
    const isDarcs = event.target.dataset.vcs === "darcs"
    const copiedPrefix = isDarcs ? `darcs pull ${jsVars.baseUrl} -h ` : ""
    navigator.clipboard.writeText(`${copiedPrefix}${hash}`).then(() => {
After
62
63
64
    navigator.clipboard.writeText(hash).then(() => {
main.ts:55
Before
55
56
57
58
59
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
98
        if (repoConfig._type === "darcs") {
          for (let branch in repoConfig.branches) {
            const repoPath = eleventyConfig.dir.output + reposPath + "/" + eleventyConfig.getFilter("slugify")(repoName) + "/branches/" + branch
            const originalLocation = cwd + "/" + repoConfig.branches[branch].location
            // If it is there, do darcs pull
            if (fsImport.existsSync(repoPath + "/_darcs")) {
              await exec(`(cd ${repoPath} && darcs pull --no-interactive)`)
            } else {
              // If it is not there, do darcs clone
              await exec(`(cd ${repoPath} && mkdir -p temp; darcs clone ${originalLocation} temp/${branch} --no-working-dir; mv temp/${branch}/_darcs .; rm -R temp)`)
            }
          }
        } else if (repoConfig._type === "git") {
          const repoPath = eleventyConfig.dir.output + reposPath + "/" + eleventyConfig.getFilter("slugify")(repoName)
          const gitRepoName = eleventyConfig.getFilter("slugify")(repoName) + ".git"
          // If it is there, do git pull
          if (fsImport.existsSync(repoPath + ".git")) {
            // git repos are just in the repos folder, not in their subdir
            // create string of commands saying 'git fetch origin branch:branch' for each branch
            const fetchCommands = repoConfig.branchesToPull.map(branch => `git fetch origin ${branch}:${branch}`).join('; ')
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && ${fetchCommands}; git update-server-info)`)
          } else {
            // If it is not there, do git clone
            const originalLocation = cwd + "/" + repoConfig.location
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/"} && git clone ${originalLocation} ${gitRepoName} --bare)`)
            await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && git update-server-info)`)
          }
          if (typeof repoConfig.artifactSteps !== 'undefined') {
            // make a temp directory for things to run in
            const tempDirName = `temp_${Math.floor(Math.random() * 10000).toString()}`
            const tempDir = `${directories.output}${reposPath}${tempDirName}`
            const tempDirRepoPath = `${tempDir}/${eleventyConfig.getFilter("slugify")(repoName)}`
            const mkdirresult = await exec(`mkdir ${tempDir}`)
            await exec(`git clone -s ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}.git ${tempDirRepoPath}`)
            for (let branch of repoConfig.branchesToPull) {
              await exec(`(cd ${tempDirRepoPath} && git checkout ${branch})`)
              for (let artifactStep of repoConfig.artifactSteps) {
                // Run the command for each step in each branch
                await exec(`(cd ${tempDirRepoPath} && ${artifactStep.command})`)
                // Copy the specified folders from the "from" to the "to" dir
                await exec(`cp -r --remove-destination ${tempDirRepoPath}/${artifactStep.copyFrom} ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branch)}/${artifactStep.copyTo}`)
              }
            // delete the temp dirs
            await exec(`rm -r ${tempDir}`)
After
55
56
57
58
59
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
98
        const repoPath = eleventyConfig.dir.output + reposPath + "/" + eleventyConfig.getFilter("slugify")(repoName)
        const gitRepoName = eleventyConfig.getFilter("slugify")(repoName) + ".git"
        // If it is there, do git pull
        if (fsImport.existsSync(repoPath + ".git")) {
          // git repos are just in the repos folder, not in their subdir
          // create string of commands saying 'git fetch origin branch:branch' for each branch
          const fetchCommands = repoConfig.branchesToPull.map(branch => `git fetch origin ${branch}:${branch}`).join('; ')
          await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && ${fetchCommands}; git update-server-info)`)
        } else {
          // If it is not there, do git clone
          const originalLocation = cwd + "/" + repoConfig.location
          await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/"} && git clone ${originalLocation} ${gitRepoName} --bare)`)
          await exec(`(cd ${eleventyConfig.dir.output + reposPath + "/" + gitRepoName} && git update-server-info)`)
        }
        if (typeof repoConfig.artifactSteps !== 'undefined') {
          // make a temp directory for things to run in
          const tempDirName = `temp_${Math.floor(Math.random() * 10000).toString()}`
          const tempDir = `${directories.output}${reposPath}${tempDirName}`
          const tempDirRepoPath = `${tempDir}/${eleventyConfig.getFilter("slugify")(repoName)}`
          const mkdirresult = await exec(`mkdir ${tempDir}`)
          await exec(`git clone -s ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}.git ${tempDirRepoPath}`)
          for (let branch of repoConfig.branchesToPull) {
            await exec(`(cd ${tempDirRepoPath} && git checkout ${branch})`)
            for (let artifactStep of repoConfig.artifactSteps) {
              // Run the command for each step in each branch
              await exec(`(cd ${tempDirRepoPath} && ${artifactStep.command})`)
              // Copy the specified folders from the "from" to the "to" dir
              await exec(`cp -r --remove-destination ${tempDirRepoPath}/${artifactStep.copyFrom} ${directories.output}${eleventyConfig.getFilter("slugify")(repoName)}/branches/${eleventyConfig.getFilter("slugify")(branch)}/${artifactStep.copyTo}`)
          // delete the temp dirs
          await exec(`rm -r ${tempDir}`)
main.ts:210
Before
210
211
212
213
214
215
216
    let command = ''
    if (config._type === "git") {
      command = `git show ${branch}:${filename}`
    }
    else if (config._type === "darcs") {
      command = `darcs show contents ${filename}`
    }
After
210
211
212
213
214
215
216
    const command = `git show ${branch}:${filename}`
main.ts:237
Before
237
238
239
240
241
242
243
    let command = ''
    if (config._type === "git") {
      command = `git show ${branchName}:README.md`
    }
    else if (config._type === "darcs") {
      command = `darcs show contents README.md`
    }
After
237
238
239
240
241
242
243
    const command = `git show ${branchName}:README.md`
partial_templates/main_top.njk:10
Before
10
11
12
13
14
15
16
17
18
19
        window.jsVars['cloneDiv'] = `{%- if reposConfig.repos[nav.repoName]._type == "darcs" -%}{% set url = repos[nav.repoName].cloneUrl + (nav.branchName | slugify) %}
&lt;label class="form-label">HTTPS URL</label>
<div class="input-group d-flex flex-nowrap">
  <span class="clone overflow-hidden input-group-text">
    {{ url }}
  </span>
  <button data-clone-url="{{url}}" class="btn btn-primary" id="clone-button">Copy</button>
</div>{%- elif reposConfig.repos[nav.repoName]._type == "git" -%}<label class="form-label">HTTPS URL</label>
</div>
{%- endif -%}`;
After
10
11
12
13
14
15
16
17
18
19
        window.jsVars['cloneDiv'] = `<label class="form-label">HTTPS URL</label>
</div>`;
schemas/ReposConfiguration.json:2
Before
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    "DarcsConfig": {
      "additionalProperties": false,
      "description": "A configuration object for a darcs repository.",
      "properties": {
        "_type": {
          "const": "darcs",
          "description": "Must be set to `\"darcs\"`.",
          "type": "string"
        },
        "artifactSteps": {
          "items": {
            "additionalProperties": false,
            "properties": {
              "command": {
                "type": "string"
              },
              "copyFrom": {
                "type": "string"
              },
              "copyTo": {
                "type": "string"
              }
            },
            "required": [
              "command",
              "copyFrom",
              "copyTo"
            ],
            "type": "object"
          },
          "type": "array"
        },
        "branches": {
          "additionalProperties": {
            "additionalProperties": false,
            "description": "Each key in this object will be the name that is used for that branch.",
            "properties": {
              "description": {
                "description": "A description of this branch. You may want to clarify what this branch is used for here.",
                "type": "string"
              },
              "location": {
                "description": "The absolute path to the repository for this branch.",
                "type": "string"
              }
            },
            "required": [
              "location"
            ],
            "type": "object"
          },
          "description": "The branches of this repository to generate pages for. Since darcs doesn't have branches in the same way that other VCSs do, a \"branch\" in this case is an entirely separate repository. So, these \"branches\" are more like repos that are grouped under the same project name. That is why you need to specify a separate location for each branch.",
          "type": "object"
        },
        "defaultBranch": {
          "description": "The name of the default branch. Should match one of the keys in  {@link  DarcsConfig.branches } .",
          "type": "string"
        },
        "languageExtensions": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "If your repository has any uncommon file extensions that should be treated like a different type of file, list them here. If you include `{njk: \"html\"}` here, that will tell the syntax highlighter to highlight an `njk` file like an `html` file. The key is the file extension in your code, and the value is the file extension that the syntax highlighter will know about.",
          "type": "object"
        }
      },
      "required": [
        "_type",
        "defaultBranch",
        "branches"
      ],
      "type": "object"
    },
After
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
schemas/ReposConfiguration.json:137
Before
137
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nThis static site generator works with both git and darcs repositories. Because of the differences between these two version control systems, the configuration for them looks a little different. Both types of configuration objects can be nested underneath the  {@link  ReposConfiguration.repos }  key.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
After
137
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
schemas/ReposConfiguration.json:149
Before
149
150
151
152
153
154
155
156
157
            "anyOf": [
              {
                "$ref": "#/definitions/GitConfig"
              },
              {
                "$ref": "#/definitions/DarcsConfig"
              }
            ],
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definitions of  {@link  GitConfig }  and  {@link  DarcsConfig }  for more details about what goes in these configuration objects."
After
149
150
151
152
153
154
155
156
157
            "$ref": "#/definitions/GitConfig",
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definition of  {@link  GitConfig }  for more details about what goes in these configuration objects."
src/configTypes.ts:3
Before
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * This static site generator works with both git and darcs repositories. Because of the
 * differences between these two version control systems, the configuration for them
 * looks a little different. Both types of configuration objects can be nested underneath
 * the {@link ReposConfiguration.repos} key.
 * 
 *     "My Darcs Project": {
 *       _type: "darcs",
 *       branches: {
 *         'main': {
 *           location: "/home/alice/projects/my_darcs_project",
 *           description: &quot;Main branch of this project."
 *         },
 *         &#39;drafts': {
 *           location: "/home/alice/projects/my_darcs_project_drafts/",
 *           description: "Some things that are a work in progress",
 *         },
 *       },
 *       languageExtensions: {
 *         "njk": "html",
 *       },
After
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *     "My Git Project": {
 *       _type: "git",
 *       branches: ['main', 'develop']
src/configTypes.ts:40
Before
40
41
    * definitions of {@link GitConfig} and {@link DarcsConfig} for more details
    [repoName: string]: GitConfig | DarcsConfig
After
40
41
    * definition of {@link GitConfig} for more details
    [repoName: string]: GitConfig
src/configTypes.ts:78
Before
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

/**
* A configuration object for a darcs repository.
*
* @example
* "My Darcs Project": {
*   _type: "darcs",
*   baseUrl: "https://repos.tuckerm.us",
*   defaultBranch: 'main',
*   branches: {
*     'main': {
*       location: "/home/alice/projects/my_darcs_project",
*       description: "Main branch of this project."
*     },
*     'drafts': {
*       location: "/home/alice/projects/my_darcs_project_drafts/",
*       description: "Some things that are a work in progress",
*     },
*   },
*   languageExtensions: {
*     "njk": "html",
*   },
* }
*/
export type DarcsConfig = {
  /** Must be set to `"darcs"`. */
  _type: "darcs",
  /**
  * The name of the default branch. Should match one of the keys in {@link DarcsConfig.branches}.
  * @example defaultBranch: "main"
  * */
  defaultBranch: string,
  /** The branches of this repository to generate pages for. Since darcs doesn't have
  * branches in the same way that other VCSs do, a "branch" in this case is an entirely
  * separate repository. So, these "branches" are more like repos that are grouped under
  * the same project name. That is why you need to specify a separate location for each
  * branch.
  * @example
  * branches: {
  *   main: {
  *     location: "/home/alice/projects/my-project/main",
  *     description: "The main release branch of this project."
  *   },
  *   drafts: {
  *     location: "/home/alice/projects/my-project/drafts",
  *     description: "Undeployed works-in-progress for this project."
  *   }
  * }
  */
  branches: {
    /**
    * Each key in this object will be the name that is used for that branch.
    */
    [branchName: string]: {
      /**
      * The absolute path to the repository for this branch.
      * @example location: "/home/alice/projects/darcs_repo_main"
      */
      location: string,
      /**
      * A description of this branch. You may want to clarify what this branch is used for here.
      */
      description?: string,
    }
  },
  /**
  * If your repository has any uncommon file extensions that should be treated like a different
  * type of file, list them here. If you include `{njk: "html"}` here, that will tell the
  * syntax highlighter to highlight an `njk` file like an `html` file. The key is the file
  * extension in your code, and the value is the file extension that the syntax highlighter
  * will know about.
  * @example
  * languageExtensions: {
  *   njk: "html",
  *   jss: "js",
  *   madeupformat: "txt"
  * }
  */
  languageExtensions?: {
    [fileExtension: string]: string
  },
  artifactSteps?: {
      command: string,
      copyFrom: string,
      copyTo: string,
  }[]
}
After
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
src/helpers.ts:85
Before
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/** @hidden */
const getDarcsDiffsFromPatchText = (patchText: string): Array<DiffInfo> => {
  const lines = patchText.split("\n")
  const hunks: Array<Hunk> = []
  let previousHunk = -1
  lines.forEach((line, index) => {
    if (line.startsWith("hunk") || index === lines.length - 1) {
      if (previousHunk === -1) {
        previousHunk = index
        return
      }
      // get diff from previous hunk to this next one
      const lastHunk = lines.slice(previousHunk, index + 1) // slice is non-inclusive for the end argument
      let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n")
      let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n")
      lastHunkBefore = _.escape(lastHunkBefore)
      lastHunkAfter = _.escape(lastHunkAfter)
      let filename = lines[previousHunk].replace("hunk ./", "")
      const changeObject = Diff.diffWords(lastHunkBefore, lastHunkAfter)
      let previousText = ""
      let afterText = ""

      changeObject.forEach((obj) => {
        if (!obj.added && !obj.removed) {
          previousText = previousText + obj.value
          afterText = afterText + obj.value
        }
        if (obj.added) {
          afterText = afterText + "<mark>" + obj.value + "</mark>"
        }
        if (obj.removed) {
          previousText = previousText + "<mark>" + obj.value + "</mark>"
        }
      })
      const regex = RegExp(/(.*) ([0-9]+)$/)
      const matches = filename.match(regex)
      const file = matches[1]
      const lineNumber: number = parseInt(matches[2])

      hunks.push({
        file,
        lineNumber,
        previousText,
        afterText,
      })
      previousHunk = index
    }
  })
  return hunks
}

  if (config._type === "darcs") {
    return config.branches[branchName].location
  }
  else if (config._type === "git") {
    return config.location
  }
  getDarcsDiffsFromPatchText,
After
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  return config.location
src/repos.ts:1
Before
1
  type DarcsConfig,
After
1
src/repos.ts:20
Before
20
21
22
23
24
25
26
const getBranchNames = (repoConfig: DarcsConfig | GitConfig): Array<string> => {
  if (repoConfig._type === 'darcs') {
    return Object.keys(repoConfig.branches)
  }
  else if (repoConfig._type === 'git') {
    return repoConfig.branchesToPull
  }
After
20
21
22
23
24
25
26
const getBranchNames = (repoConfig: GitConfig): Array<string> => {
  return repoConfig.branchesToPull
src/vcses/darcs/helpers.ts:1
Before
1
2
3
4
5
export default {
    cloneUrl: (baseUrl: string, repoName: string) => {
        return `${baseUrl}/${repoName.toLowerCase().replaceAll(" ", "-")}/branches/`
    }
}
After
1
2
3
4
5
src/vcses/darcs/operations.ts:1
Before
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import util from 'util'
import childProcess from 'child_process'
const exec = util.promisify(childProcess.exec)
import {getDarcsDiffsFromPatchText} from '../../helpers.ts'

export const getFileList = async(repoName: string, branchName: string, repoLocation: string) => {
  const command = "darcs show files"

  const result = await exec(`(cd ${repoLocation} && ${command})`)
  const files = result.stdout.split("\n").filter(item => item.length > 0 && item != ".")
  return files
}

export const getBranchInfo = async (repoName: string, branchName: string, repoLocation: string) => {
  const patches = new Map()

  const totalPatchesCountRes = await exec(`(cd ${repoLocation} && darcs log --count)`)
  const totalPatchesCount = parseInt(totalPatchesCountRes.stdout)
  let hunkRegex = RegExp(/^ *hunk /)
  // Get 100 patches at a time and parse those
  for (let i = 1; i <= totalPatchesCount; i = i + 100) {
    let patchesSubsetRes = await exec(`(cd ${repoLocation} && darcs log --index=${i}-${i+100} -v)`)
    let patchesSubset = patchesSubsetRes.stdout.split("\n")
    do {
      const nextPatchStart = patchesSubset.findIndex((line, index) => {
        return (index > 0 && line.startsWith("patch ")) || index === patchesSubset.length - 1
      })
      const isEndOfFile = nextPatchStart === patchesSubset.length - 1
      const currentPatch = patchesSubset.slice(0, isEndOfFile ? nextPatchStart : nextPatchStart - 1)
      patchesSubset = patchesSubset.slice(nextPatchStart)
      const hash = currentPatch[0].replace("patch ", "").trim()
      const author = currentPatch[1].replace("Author: ", "").trim()
      const date = currentPatch[2].replace("Date: ", "").trim()
      const name = currentPatch[3].replace("  * ", "").trim()
      const diffStart = currentPatch.findIndex((line) => {
        return line.match(hunkRegex)
      })
      const description = currentPatch.slice(5, diffStart).map(str => str.replace("  ", "")).join("\n").trim()
      const diffs = getDarcsDiffsFromPatchText(currentPatch.slice(diffStart).map(str => str.trimStart()).join("\n"))
      patches.set(hash, {
        name,
        description,
        author,
        date,
        hash,
        diffs,
      })
    } while (patchesSubset.length > 1)
  }

  return Array.from(patches.values())
}

export const getFileLastTouchInfo = async (repoName: string, branchName: string, filename: string, repoLocation: string) => {
  const command = `darcs annotate --machine-readable ${filename}`
  const res = await exec(`(cd ${repoLocation} && ${command})`)
  const output = res.stdout
  const outputLines = output.split("\n").map((line) => {
    return line.split(' ')[0]
  })

  return outputLines.map((line) => {
    return {sha: line, author: ''}
  })
}
After
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
src/vcses/helpers.ts:1
Before
1
2
import darcsHelpers from './darcs/helpers.ts'
    darcs: darcsHelpers
After
1
2
src/vcses/operations.ts:3
Before
3
4
5
6
7
import {
  getBranchInfo as getDarcsBranchInfo,
  getFileList as getDarcsFileList,
  getFileLastTouchInfo as getDarcsFileLastTouchInfo,
} from './darcs/operations.ts'
After
3
4
5
6
7
src/vcses/operations.ts:24
Before
24
25
26
27
28
  darcs: {
    getBranchInfo: getDarcsBranchInfo,
    getFileList: getDarcsFileList,
    getFileLastTouchInfo: getDarcsFileLastTouchInfo,
  }
After
24
25
26
27
28
templates/patch.njk:10
Before
10
11
12
13
14
15
16
17
18
      {% if reposConfig.repos[patchInfo.repoName]._type == "darcs" %}
      <div class="input-group mb-3 d-flex flex-nowrap">
        <span id="clone-command" class="clone input-group-text overflow-hidden">
          {% set url = [reposConfig.baseUrl, reposPath, "/", patchInfo.repoName | slugify, "/branches/", patchInfo.branchName | slugify] | join | url %}
          darcs pull {{ url }} -h {{patchInfo.patch.hash}}
        </span>
        <button class="btn btn-primary" id="clone-button" onclick="copyCommand()">Copy</button>
      </div>
      {% endif %}
After
10
11
12
13
14
15
16
17
18
templates/repo.njk:24
Before
24
25
26
27
28
29
            {% if reposConfig.repos[branch.repoName]._type == "darcs" %}
            <button data-hash="{{patch.hash}}" data-vcs="darcs" class="copy-btn btn btn-sm btn-outline-primary ms-2">
              <i class="bi-copy bi me-1"></i>darcs pull {{patch.hash | truncate(6, true, "")}}
            </button>
            {% elif reposConfig.repos[branch.repoName]._type == "git" %}
            {% endif %}
After
24
25
26
27
28
29