Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLIPublic
AssigneesNone

Relationships

#2297 git: idempotent clone-or-update (ensure_checkout), and an idempotent branch option

Opened by usefulish · 9/20/2026

The gap

clone fails when the destination path already exists. That makes any re-runnable workflow awkward: the first run clones, and every run after it fails unless something clears the workspace first. There is no supported way to express "make sure a checkout of this repo is at this ref, whatever state the path is in."

The same applies to branch. With create: true it runs git checkout -b <name>, which fails when the branch already exists, so a workflow that creates a working branch is also single-use.

Why it matters

This bites any workflow that operates on a checkout it manages itself — CI-style pipelines, scheduled jobs, and especially fan-out over many repositories, where clearing a workspace per repo before each run is both extra machinery and a destructive operation the workflow author has to get right.

Guards are not a clean fix here. A guard keyed on prior clone data skips the clone, but it cannot tell whether the directory still exists or has drifted, so it silently skips when it should re-clone.

What we ended up doing

We extended the type locally with export const extension, adding a single method. It works well and has been running against real repositories, but it reimplements logic that belongs upstream — and it means every consumer of the workflow needs our extension alongside @swamp/git.

Proposed shape

ensure_checkout(url, path, ref?, depth?, reset?, branch?, token?)

  • Path absent: clone (honouring depth and ref).
  • Path present and a checkout of the same repository: fetch --prune, then when reset is on, checkout --force -B <ref> origin/<ref> and clean -fd so the tree matches the remote exactly.
  • Path present but a checkout of a different repository: refuse. reset discards local changes, so this guard matters — comparing owner/name across the various remote spellings (https, scp-style, ssh://) is enough.
  • Path present, non-empty, and not a git checkout: refuse rather than clone over it.
  • branch: create or move a working branch with checkout -B, so re-running is a no-op instead of a "branch already exists" failure.
  • Output: a resource carrying path, url (credentials scrubbed), ref, branch, sha, and an action of cloned / updated / reused, so a later step can tell what actually happened.

A smaller alternative, if a new method is unwanted: an ifExists option on clone (fail | update | reuse), and a force option on branch that selects checkout -B. That would cover most of it, though without the different-repository safety check, which we would not want to lose.

Happy to contribute

We have a working implementation and would be glad to turn it into a PR against @swamp/git if the shape above looks right — or to adjust it to whatever shape you prefer.

Upstream repository: https://github.com/swamp-club/swamp-extensions

Environment

  • Extension: @swamp/git@2026.09.15.1
  • swamp: 20260918.211634.0-sha.bcaa9695
  • OS: darwin (aarch64)
  • Deno: 2.9.7
  • Shell: /bin/zsh
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED

Open

9/20/2026, 6:11:57 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.