CodeHerderSearch⌘KRequest access →

← All docs

Connecting repositories

How to register a git repository with your workspace, list and inspect repos, edit a repo's name or Git URL, set which repo a workspace's tasks build in, and archive or restore one.

A repository is a git repo connected to your workspace. When an agent picks up a task, CodeHerder cuts a fresh branch from that repo and gives the agent an isolated checkout to work in. See Core concepts for where repositories fit in the full object model.

Registering a repository

You need CH_WORKSPACE_ID set before running any ch repo command.

Register a repo with its display name and clone URL:

ch repo create --name my-app --url https://github.com/acme/my-app

Agents branch from main by default. If your repo’s default branch has a different name, set it with --branch:

ch repo create --name my-app --url https://github.com/acme/my-app --branch develop

Pass the name of your actual default branch (develop, master, trunk, or whatever it is). CodeHerder does not auto-detect it from the remote — if you omit --branch, agents always branch from main.

Which clone URLs work

CodeHerder accepts a Git URL in one of two forms, and clones it over HTTPS either way:

  • An HTTPS URL, .git suffix optional: https://github.com/acme/my-app.git or https://github.com/acme/my-app. This works for any git host reachable over HTTPS — GitHub, GitLab, Bitbucket, or a self-hosted server.
  • GitHub’s or GitLab’s SSH-style address, written exactly in lower case: git@github.com:acme/my-app.git or git@gitlab.com:acme/my-app.git. CodeHerder rewrites this to an HTTPS clone before it ever reaches git — see Git access to clone the repository, below.

Everything else is rejected when you try to save it:

  • ssh:// or git:// addresses, including ssh://git@github.com/acme/my-app.git
  • plain http:// (unencrypted)
  • an SSH-style address for any host other than github.com or gitlab.com — for example git@bitbucket.org:acme/app.git
  • a bare file-system path
  • a URL with a password in it, e.g. https://user:token@github.com/acme/app.git

If you have an SSH-style address for a host other than GitHub or GitLab, convert it to HTTPS instead: git@bitbucket.org:acme/app.git becomes https://bitbucket.org/acme/app.git.

The host also needs to be reachable over HTTPS from the public internet; CodeHerder Cloud can’t register a repo on an internal-only git host. A self-managed deployment can lift that restriction, and re-admit http:// and the SSH/ssh:///git:// forms above, with the CH_ALLOW_INTERNAL_GIT_HOSTS setting — applied on the server and on every device that clones.

Even a form CodeHerder does accept — a plain https://<token>@github.com/acme/app.git, with no password — isn’t a safe place for a token: a repo’s Git URL is visible to every workspace member. Keep the credential on the device instead — see Git access to clone the repository, below.

This rule applies wherever you set a repo’s Git URL — the CLI or the web app — and to an edit exactly as it does to a new registration.

You can also register a repo from the web app instead of the CLI: open Set up → Repos in the sidebar and click Register repo. Either way, once it’s registered the repo appears under Set up → Repos.

Listing and inspecting repositories

List all active repos in your workspace:

ch repo list

Include archived repos too:

ch repo list --all

Show the full details for one repo:

ch repo show <name|id>

You can refer to a repo by its name or its full UUID — see Referring to things on the command line for how name matching works.

Editing a connected repository

You can update a repo’s name and Git URL from its detail page in the web app — open Set up → Repos in the sidebar and click the repo.

Both fields are click-to-edit: click the value, type the new one, and click Save (or press Enter) to commit it. Press Escape or click Cancel to discard your change and keep the current value.

Editing the Git URL is how you repoint a repo whose remote has moved — an org rename, a move to a different git host, or a URL that was mistyped when you registered it — without archiving and re-registering the repo (which would detach its task history). The same accepted forms described in Which clone URLs work, above, apply to an edit: a URL outside that list is rejected and the current value is left in place. CodeHerder uses the new URL the next time an agent clones the repo, so confirm the device still has git access to it — see What the device needs, below.

A couple of guardrails apply: the name can’t be empty, and you can’t rename a repo to a name already used by another repo in your workspace, or point two repos at the same Git URL — CodeHerder rejects the change and leaves the existing value in place. Re-saving a repo’s current URL is a no-op.

The default branch is set when you register the repo (--branch) and is shown on the detail page but isn’t editable there — see Registering a repository, above, if you need a different default branch.

This is a web-app-only capability; the ch CLI has no repo-edit command.

Archiving and restoring

ch repo archive soft-archives the repo — it is not deleted and all history is preserved. Archiving removes the repo from the active list so it is not considered for new task assignments, but the record and any associated history remain intact and can be restored at any time.

ch repo archive my-app

To bring an archived repo back into service:

ch repo unarchive my-app

ch repo restore is an alias for ch repo unarchive.

What the device needs

Registering a repository tells CodeHerder where your code lives. For that registration to translate into running tasks, the device that executes agent sessions also needs to be set up correctly — CodeHerder does not provision or manage the credentials described below, and the default workflow does not route work around a device that is missing them.

Git access to clone the repository

When a task starts, the device clones the repository over HTTPS — even one registered with a git@github.com: or git@gitlab.com: address (see Which clone URLs work, above). What the device needs is an HTTPS git credential, not an SSH key; an SSH key on the device is never used to clone, whichever form the Git URL takes.

The simplest way to set this up doubles as something you’ll want anyway — signing in with the host CLI:

  • GitHub repositories: run gh auth login on the device (or gh auth setup-git, if gh is already signed in but git itself isn’t). See Host CLI for opening and landing pull requests, below — this same sign-in also covers opening pull requests, so it’s one setup step, not two.
  • GitLab repositories: glab auth login covers the same ground for glab.

Any HTTPS git credential helper that supplies a valid token for the host also works, if you’d rather manage it that way.

Public repositories need no credentials; git clone succeeds without authentication.

If the clone fails — for example, because the HTTPS credential is missing or has expired — the sandbox fails to provision and the task stays at its current stage. The failure is visible under the task’s Sessions view, where the abandoned sandbox shows the clone error, and under the device’s Git credentials check in its health snapshot — see Readiness checks. Fix the credential on the device and the task picks up on the next automatic retry.

Host CLI for opening and landing pull requests

Agents open pull requests and land them through the host’s own command-line tool. This CLI must be installed on the device and signed in with an account that has write access to the repository:

  • GitHub repositories: install gh and run gh auth login on the device.
  • GitLab repositories: install glab and run glab auth login on the device.

If the CLI is absent or not authenticated, the code-stage agent cannot open the pull request, or the merge-stage agent cannot land it — whichever stage runs first reports the problem as a task comment. Install and authenticate the CLI on the device to resolve it.

CodeHerder does not manage or inject these credentials. Work simply fails on a device that is missing them, and the fix is always to configure the device — not to change the repository registration.

Checking host-CLI authentication

ch githost auth-check lets you verify that the correct CLI is installed and authenticated for a given repository before you start work. Run it from inside the repository:

ch githost auth-check

CodeHerder detects the host from the repository’s origin remote and checks the matching CLI — gh for github.com, glab for gitlab.com. It prints a clear result and exits 0 on success or 1 on failure:

✓ github.com (gh) authenticated
✗ gitlab.com (glab) not authenticated

auth-check only reads credentials — it never modifies them. If the check fails, follow the remediation the command prints: gh auth login for GitHub, glab auth login for GitLab.

To check a specific remote URL without being inside a git repository, supply it with --remote:

ch githost auth-check --remote git@github.com:acme/my-app.git
ch githost auth-check --remote https://gitlab.com/acme/my-app

For scripting or machine-readable output, add --json:

ch githost auth-check --json
# → {"data":{"host":"github.com","cli":"gh","authenticated":true}}

auth-check supports github.com and gitlab.com only. Bitbucket, self-hosted GitHub Enterprise, and self-hosted GitLab instances are not recognised — the command exits 1 with an “unrecognised host” message for any other remote URL.

Which repository a task builds in

Every build session is cut from one repository, and CodeHerder picks it automatically, in order:

  1. The workspace’s default repo, if you’ve set one (see below).
  2. The workspace’s sole active repository registered directly on it — the common case: connect one repo, and CodeHerder chooses it with nothing else to configure.

Without a default set, a workspace with no active repository of its own, or more than one, leaves CodeHerder unable to tell which repository a task should use. Its session fails to provision, and the task stays at its current stage. Unlike a device credential problem, no error is recorded: the task’s Sessions view simply fills with abandoned attempts that never turn into a running agent, and left long enough the task is flagged as stalled. In ch task list, its status shows a (stalled) suffix.

Setting a default repo

If a workspace has, or might ever have, more than one repository connected to it, set a default so CodeHerder always knows which one to build in:

ch workspace edit <workspace> --default-repo <name|id>

<name|id> can name a repository registered directly on the workspace, or one connected to a parent group and inherited into it — pointing a workspace’s default at an inherited repo is a supported way to build against a shared codebase without registering a second copy directly on the workspace. The repo must be active; naming an archived one is rejected. Setting or clearing a default requires workspace owner or admin access.

Only a leaf workspace can have a default repo — a group can’t, and a group’s default doesn’t carry down to the workspaces beneath it, so each one sets its own.

Read the current setting back with:

ch workspace show <workspace>

which prints a default repo row when one is set.

To clear a default and fall back to the sole-repo rule below:

ch workspace edit <workspace> --clear-default-repo

--default-repo and --clear-default-repo are mutually exclusive on the same call. This is a CLI and API setting today — there’s no matching control in the web app yet.

One thing to watch for: archiving a repository does not clear a workspace default that names it. A default pointing at an archived repo still resolves, so that workspace’s tasks keep building in the repository you archived. When you archive a repo, repoint or clear the default on any workspace that names it in the same step.

Relying on the sole-repo rule instead

With no default repo set, a workspace with exactly one active repository registered directly on it just works — no configuration needed, and most single-repo workspaces never touch any of this. A repository inherited from a parent group is usable in the workspace and shows an inherited badge under Set up → Repos, but it doesn’t count toward this automatic choice unless you also point the workspace’s default repo at it (above) or register it directly on the workspace.

If a workspace has more than one active repository registered directly on it and you’d rather not set a default, archive the extras and keep exactly one — see Archiving and restoring, above. If you regularly work across several codebases, either give each one its own workspace (see Managing workspaces) or set each workspace’s default repo to the codebase it should build.

For the full symptom-to-fix walkthrough, see No repository resolves to build in in Why isn’t my task moving?.

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch what's happening, see what's stuck, and know what it's costing you, live.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close