Sync a namespace from git
Copy page
This guide shows you how to keep the files of a namespace in a git repository. Sluice reads one branch, turns each commit into a version of the namespace, and sends edits back as new branches.
| Term | Meaning |
|---|---|
| Git source | One branch of one repository, with its credentials, poll interval and webhook secret. |
| Mapping | A directory of the branch and the namespace that gets its files. One source has 1 to 100 mappings. |
| Sync run | One read of the branch head. Sluice records each run with its result. |
| Git namespace | A namespace whose files come only from sync. Sluice shows it as read-only. |
Before you start
Section titled “Before you start”- You need the admin role to create a git source.
- Store the credential as a global secret, for example
GIT_TOKEN. Sluice reads the credential and the webhook secret from the global scope only. The secret can use any provider. See Use secrets and variables. - Run
sluice validateon the directory. A sync stores invalid flows too, but their triggers do not fire.
Create a git source
Section titled “Create a git source”-
Open Settings → Git sources and click Add git source.
-
Fill in the form:
Field Value Name A unique name, for example pipelines. It cannot change later.Repository URL https://…,ssh://…oruser@host:path. Plainhttp://works only forlocalhostand loopback addresses.Branch The branch to track, for example main.Authentication none,https_tokenorssh_key.Credential secret key The key of the global secret with the token or the private key. Known hosts For ssh_key: lines in OpenSSHknown_hostsformat.Poll interval in seconds From 15 to 86 400. Default 60. Webhook secret key Optional. The key of the global secret for webhook calls. -
Under Mappings, add a Repository path and a Namespace for each directory. An empty path is the repository root.
-
Click Add git source. The first sync starts within about one second.
The API takes the same fields:
curl -X POST "$SLUICE_URL/api/v1/git-sources" \ -H "Authorization: Bearer $SLUICE_TOKEN" -H "Content-Type: application/json" \ -d '{ "name": "pipelines", "repo_url": "https://github.com/acme/pipelines.git", "branch": "main", "auth_type": "https_token", "credential_secret_key": "GIT_TOKEN", "poll_interval": 300, "webhook_secret_key": "GIT_WEBHOOK_SECRET", "mappings": [{"repo_path": "pipelines/elt", "namespace": "data.elt"}] }'The response holds the secret keys, never the secret values. It also holds webhook_url, last_synced_sha, last_sync_at, last_sync_status and last_error.
Credentials
Section titled “Credentials”auth_type |
URL | Credential in the secret | How Sluice uses it |
|---|---|---|---|
none |
Any allowed URL. | None. | No authentication. |
https_token |
https://, or loopback http://. |
An access token, for example of GitHub or GitLab. | HTTP basic auth with the user x-access-token. |
ssh_key |
ssh:// or user@host:path. |
A private key in PEM format, without a passphrase. | The SSH user comes from the URL. Without a user, it is git. |
Mappings
Section titled “Mappings”- A mapped namespace that does not exist becomes a new git namespace.
- A mapping to a managed namespace returns 409
namespace_managed. A namespace keeps its source for its whole life. - A mapping to a namespace of another source returns 409
namespace_mapped. - In one source, two mappings cannot share a path or a namespace.
- An update of a source replaces all mappings. A namespace that loses its mapping keeps its versions, stays read-only and does not sync again. A delete of the source has the same effect.
How a sync works
Section titled “How a sync works”The instance that holds the git sync lease checks the sources every second. A source syncs in three cases. It has never synced, a user or a webhook asked for a sync, or poll_interval seconds have passed since the last sync started.
A sync does these steps:
- It fetches the head of the branch as a shallow clone with depth 1, into a temporary directory. It checks out no files.
- For each mapping, it reads the files below the repository path from the git object store.
- It compares the files with the head version of the namespace. It creates a new version only when a file changed.
- It refreshes the flows and triggers of the namespace from the new version.
- It records the sync run and deletes the temporary directory.
The message of a version is git <first 12 characters of the SHA>: <commit subject>, and the version records the SHA. A commit that changes only one mapping gives a new version of that namespace only.
A flow file that you remove in git removes the flow and stops its triggers. Old executions of the flow stay visible.
Sluice reads only regular and executable files. It skips symbolic links, submodules and invalid paths, and records a warning for each. A file larger than SLUICE_MAX_FILE_BYTES fails the sync.
Watch the sync
Section titled “Watch the sync”The page of a git namespace shows a Git source panel. It lists the repository, the branch, the path, Last sync with the commit, and Last error. Below it, a table lists the last 50 sync runs with State, Commit, Snapshots and Details. The Details column shows the error or the number of warnings.
A failed sync keeps the previous version as the head, so new executions use the last good files. last_synced_sha changes only after a successful sync. A run that stays running for more than 30 minutes becomes failed with the error the sync stopped before it ended.
Sync now
Section titled “Sync now”Sync now on Settings → Git sources, or on the Git source panel of a namespace, asks for a sync at once. You need the operator role or a higher role.
curl -X POST "$SLUICE_URL/api/v1/git-sources/<source_id>/sync" \ -H "Authorization: Bearer $SLUICE_TOKEN"The answer is 202. The sync starts at the next check of the lease holder, normally within one second.
Sync on push with a webhook
Section titled “Sync on push with a webhook”A webhook makes a push sync at once, so you can set a long poll interval.
-
Create a global secret, for example
GIT_WEBHOOK_SECRET, with a long random value. -
Set Webhook secret key of the source to
GIT_WEBHOOK_SECRET. -
Copy the
webhook_urlof the source:SLUICE_PUBLIC_URLfollowed by/hooks/git/<source_id>. -
Configure the git host with one of the tabs below.
- In the repository, open Settings → Webhooks → Add webhook.
- Set Payload URL to the
webhook_urlof the source. - Set Content type to
application/json. - Set Secret to the value of
GIT_WEBHOOK_SECRET. - Select the push event and save.
GitHub signs each call with X-Hub-Signature-256. Sluice checks the HMAC-SHA256 of the body with the secret.
Send the secret itself in the header X-Sluice-Token:
curl -X POST "https://sluice.example.com/hooks/git/<source_id>" \ -H "X-Sluice-Token: $GIT_WEBHOOK_SECRET"| Request | Answer |
|---|---|
| Unknown source ID | 404 git_source_not_found |
| No webhook secret on the source, or a wrong signature or token | 401 invalid_signature |
| A body larger than 1 MiB | 413 body_too_large |
A valid GitHub ping event |
202 {"queued":false} |
A valid JSON body whose ref is not refs/heads/<branch> |
202 {"queued":false} |
| Any other valid request | 202 {"queued":true}, and a sync starts |
Change files of a git namespace
Section titled “Change files of a git namespace”A git namespace is read-only. A save, upload, rename or delete returns 409 namespace_read_only. The repository stays the only source of the files. To change a file, commit to the tracked branch, or push an edit from Sluice to a new branch.
Push to a branch from the editor
Section titled “Push to a branch from the editor”You need the editor role.
-
Open the git namespace and select the file on the Files tab. The editor shows the file, and you can type in it.
-
Edit the file. The server validates flow files and
namespace.yamlwhile you type. -
Click Push to branch, or press Cmd+S or Ctrl+S.
-
Type a Commit message and click Push. The dialog shows the name of the new branch.
-
Open a pull request for the branch in your git host, and merge it. The next sync brings the change into Sluice.
Sluice builds the commit from the last synced commit, not from the newest commit of the branch. It pushes only a new branch, sluice/<user-slug>/<yyyymmdd-hhmmss>. The tracked branch and the namespace do not change.
| Part | Value |
|---|---|
<user-slug> |
The part of the user email before @, in lower case. Each run of characters other than a-z and 0-9 becomes one -. |
<yyyymmdd-hhmmss> |
The push time in UTC. |
| Author and committer | The user slug as the name, and the user email. |
For example, dana@example.com at 14:03:07 UTC on 24 September 2026 pushes the branch sluice/dana/20260924-140307.
| Error | Cause |
|---|---|
404 git_source_not_found |
No git source maps the namespace. |
409 not_synced |
The source has not synced yet, so no base commit exists. |
413 file_too_large |
A file is larger than SLUICE_MAX_FILE_BYTES. |
422 validation_failed |
A bad path, a missing file, or changes that change no file. |
The API is POST /api/v1/namespaces/{namespace}/git/push with a message and a list of changes. Each successful push writes the audit event git.push.
Push from the assistant
Section titled “Push from the assistant”The assistant writes a change to a git namespace in the same way. It proposes the files, and it refuses a change with validation errors. After you confirm the change, Sluice pushes a new branch and the assistant names it. See Set up the assistant.