Git Configuration
The git section in atmos.yaml makes Git a foundational Atmos capability — a peer to Toolchain, Auth, and Hooks. Define managed repositories once under git.repositories, then clone, pull, diff, commit, and push them by logical name from the atmos git commands, kind: git lifecycle hooks, and native CI workflows — with consistent authentication, safety rules, and workdir handling. It is the foundation for GitOps workflows with Atmos: commit generated artifacts to a source-of-truth repository that Argo CD, Flux, or your CI consumes.
You will learn
- Define managed repositories by logical name under
git.repositories - Authenticate through Atmos Auth identities and integrations — credentials are never embedded in URIs
- Clone is always reconcile: idempotent and safe under restored CI caches
- Automatic workdirs under the Atmos XDG cache root are captured by the native CI cache for free
- Configure local Git hooks (
pre-commit,commit-msg, ...) that run acommandor a list ofsteps
Basic Configuration
The keys under git.repositories (flux-deploy, generated-terraform) are arbitrary, user-defined logical names — not reserved values. Components, hooks, and commands refer to repositories by these names. Repository configuration follows standard Atmos deep-merge, so repositories can be defined in imported configuration and overridden per environment.
Repository Fields
All fields a repository supports:
providerExecution backend for Git operations. Default and currently the only value:
cli(shells out to the Git CLI).cliis host-agnostic — it works with GitHub, GitLab, Bitbucket, and bare repositories.uriRemote repository URI. Credentials must never be embedded in
uri— authentication flows through the process environment and Atmos Auth, never through URL rewriting with tokens.branchBranch to check out. Empty means the current branch for existing workdirs, and Git's default-branch behavior for fresh clones.
remoteRemote name. Default:
origin.workdirExplicit workdir location, overriding the automatic XDG location (see Automatic Workdirs).
clone.depthShallow clone depth.
0(default) means full history. Also settable per invocation with--depth(flag wins: CLI > ENV > config > defaults).clone.filterPartial-clone filter spec (for example,
blob:none). Also settable per invocation with--filter.clone.single_branchLimit the clone to the configured branch. Also settable per invocation with
--single-branch.clone.submodulesInitialize submodules after clone. Default:
false.auth.identityThe Atmos Auth identity used for Git operations against this repository. See Authentication Resolution.
commit.signingCommit signing mode:
auto(default — pass no signing flag; Git config decides),always(pass-S), ornever(pass--no-gpg-sign). Overridable per invocation with--sign/--no-sign.commit.author.name/commit.author.emailCommit author identity, passed per invocation (
-c user.name=... -c user.email=...) without mutating repository or global Git config. Required in CI, where runners typically have nouser.name/user.emailconfigured. Locally, when Git already resolves an author, Atmos passes nothing — your own Git config wins.push.retriesBounded retry count for rejected non-fast-forward pushes (
pull --rebase, then re-push). Default:3.0disables retries.init.fromDefault seed source for
atmos git init— the repository URI whose content bootstraps this repository (a template, or a repository being migrated). When omitted,initcreates an empty repository. Overridable per invocation with--from(flag wins: CLI > ENV > config > defaults).init.keep_historyWhen seeding via
init.from, preserve the source's full history and keep it reachable as theupstreamremote so future updates can be pulled. Default:false(fresh history — a single initial commit). Only valid together withinit.from. Overridable per invocation with--keep-history.
Defaults
When fields are omitted:
| Field | Default |
|---|---|
provider | cli |
remote | origin |
branch | Current branch for existing repos; Git default-branch behavior for clone |
workdir | Automatic XDG cache location (see below) |
commit.signing | auto |
commit.author | Identity-derived when available; otherwise an atmos[bot]-style default |
push.retries | 3 |
clone.depth | 0 (full history) |
clone.submodules | false |
Automatic Workdirs
When workdir is omitted, Atmos resolves a deterministic location under the Atmos XDG cache root:
$XDG_CACHE_HOME/atmos/git/repositories/<name>
with the standard XDG fallbacks and ATMOS_XDG_* overrides. Because the native CI cache archives the XDG cache root, managed clones are captured and restored across CI runs for free. An explicit workdir overrides the automatic location.
Clone Destinations
The two-repo split (managed repositories vs. the current repository) extends to clone destinations:
| Clone form | Destination |
|---|---|
Named managed repository (atmos git clone flux-deploy) | Automatic XDG workdir (cache-captured) |
Single configured repository outside CI (atmos git clone with exactly one repository) | Automatic XDG workdir (cache-captured) |
No-arg current-repo checkout replacement in CI (atmos git clone with ci.enabled: true and detected CI metadata) | The working directory (e.g., GITHUB_WORKSPACE), exactly like actions/checkout — never an XDG workdir; subsequent Atmos commands expect the repo at CWD |
Ad hoc URI (atmos git clone https://...) | <cwd>/<repo-name>, like plain git clone |
--workdir=<path> overrides the destination in all forms.
Clone Is Reconcile
Workdirs persist across runs — and the native CI cache restores them, possibly stale. Clone semantics are therefore defined as reconcile, not "fail if exists":
- Workdir absent → clone.
- Workdir present and clean → fetch, check out the configured branch, fast-forward to the remote ref.
- Workdir present and dirty from a crashed or interrupted run → defined recovery: discard uncommitted changes inside managed paths only and re-reconcile; fail with a hint when unmanaged dirty files are present.
Reconcile makes clone behavior independent of cache freshness: a cache hit means fetching the delta instead of a full clone; a cache miss means a fresh clone; correctness is identical either way.
Authentication Resolution
auth.identity is the only named auth reference on a repository. Integrations are never referenced by name from git config — they attach to identities via their via link, and naming an identity on a repository brings its integrations along automatically. For example, a github/sts integration linked to platform-admin materializes GIT_CONFIG_* credentials for every Git subprocess targeting the repository, with zero Git-specific auth wiring:
Per-operation resolution order:
--identity=<name>flag (the global persistent flag).git.repositories.<name>.auth.identity.- Ambient credential broker: when no identity is configured, the lazy ambient broker runs before the first Git subprocess. This is the zero-config CI path —
atmos git cloneof a private GitHub repository works with noauthblock at all when an auto-provisiongithub/stsintegration (or an ambientGITHUB_TOKEN) is available. - Process environment passthrough: your own Git credentials (credential helpers, SSH agent) always work, since the Git CLI provider inherits the process environment.
See Authentication for identities and integrations.
Local Git Hooks
The git.hooks section maps Git hook names to commands or ordered step lists, invoked via thin .git/hooks/* shims installed by atmos git hooks install:
git.hooks.<hook-name>A Git hook name:
pre-commit,commit-msg,pre-push, and so on.git.hooks.<hook-name>.steps- An ordered list of registered Atmos steps. Use this instead of
commandto run inline scripts and other step types inside Atmos. An empty list is not a hook implementation. git.hooks.<hook-name>.commandThe command to execute when the hook fires. Hook commands should usually invoke an Atmos workflow or custom command, which preserves existing toolchain, environment, and identity behavior. Hook arguments and stdin are forwarded.
The shim that atmos git hooks install writes pins the absolute path of the atmos binary that installed it, and falls back to atmos on PATH when that binary has moved or been removed. Hooks therefore keep working from IDEs and GUI Git clients that do not have atmos on their PATH.
Local Git hooks are triggered by Git itself in the current repository. They are separate from Atmos lifecycle events — for event-bound Git publishing (e.g., commit after terraform apply), use the kind: git hook.
Inline script steps
Keep small checks inside the hook configuration. Starlark scripts run in-process and can call the step library:
git:
hooks:
pre-commit:
steps:
- name: check-instruction-size
type: script
interpreter: starlark
script: |
for path in fs.glob("CLAUDE.md"):
if fs.stat(path).size > 40000:
errors.build("CLAUDE.md exceeds 40,000 bytes").fail()
- name: report
type: script
interpreter: starlark
script: ui.success("Repository checks passed")
Choose exactly one of command or a non-empty steps list. Install the shim with
atmos git hooks install, then run it directly with atmos git hooks run pre-commit.
Existing command hooks keep their argument and stdin forwarding behavior.
Steps run in order and stop at the first failure. They run from the repository root,
even when you invoke the hook from a subdirectory. They share named outputs. A
type: env step exports variables to the processes and templates of later steps
(for example {{ .env.X }}). The env global of a Starlark step contains only the
env: that step declares, not variables exported by earlier steps. Each step supports its handler's timeout and retry
behavior; embedded scripts also have access to steps.parallel.
Git hook arguments are available as ctx.args in embedded scripts, for example
the commit-message path supplied to commit-msg, and as positional parameters in shell steps ($1, "$@"). Git's pre-commit hook supplies
no filenames: query the Git index explicitly when a check needs tracked or staged paths.
Relative paths resolve from the repository root, unless a step sets
working_directory. These checks read working-tree files; Atmos does not stash unstaged changes
or limit checks to the staged contents automatically.
Hook step lists use synchronous execution. Workflow scheduling fields (needs,
when, continue, identity, background execution, and freshness policies) are
rejected. Use an explicit container step for container operations. Background-job
handlers require a workflow context. Use a workflow when a hook needs that scheduling.
See two inline repository checks for tracked symlink validation and separate size limits for CLAUDE.md and agent files.
Hook arguments and standard input
Every step of a steps hook can read what Git passed to the hook:
- Arguments
A
shellstep receives the arguments as positional parameters ($1,"$@"), which keeps an argument that contains spaces intact. Every step's environment also holdsATMOS_GIT_HOOK_ARGS, the arguments joined by single spaces. A Starlark step reads them fromctx.args.- Standard input
Git writes data to the standard input of
pre-push,pre-receive,post-receive,post-rewrite,reference-transaction, andproc-receive. Atmos reads that input once and saves it to a temporary file. The environment variableATMOS_GIT_HOOK_STDINholds the path of the file for every step, so an embedded script can open it withfs.read_file. The firstshellstep also receives the same data on its standard input. Atmos removes the file when the hook ends. Other hooks capture nothing and leaveATMOS_GIT_HOOK_STDINunset.
For example, a pre-push hook can read the refs Git is about to update:
git:
hooks:
pre-push:
steps:
- name: refs
type: shell
command: |
echo "pushing to $1 ($2)"
while read -r local_ref local_sha remote_ref remote_sha; do
echo "$local_ref -> $remote_ref"
done
Exit codes and prompts
atmos git hooks run exits with the code of the step that failed, so Git blocks the operation with the status the step
chose. A Starlark fail() exits with 1, and errors.build("message").with_exit_code(5).fail() exits with 5.
A step that prompts for input, such as confirm or input, needs a terminal. Git often runs hooks without one, for
example from a GUI client. A prompt step without a default: fails there with a hint that setting default: lets the
step run without a terminal.
Configuration layers
When several configuration sources define the same hook, a later source that gives the hook steps: replaces an earlier
command:, and a later command: replaces earlier steps:. Atmos never runs both forms.
List Output
The git.list section configures atmos git list output, following the established <section>.list.columns pattern:
git.list.formatDefault output format:
table,json,yaml,csv, ortsv.git.list.columnsColumn definitions (
name+valuetemplate). Available row fields:name,uri,provider,branch,workdir, andstatus(populated only with--check-status). Custom columns also feed dynamic tab completion for--columns.
Native CI Lifecycle
With ci.enabled: true, Git composes with the native CI cache and Atmos Auth into a complete job lifecycle:
- Job starts. CI cache auto-restore brings back the Atmos XDG cache root — toolchain binaries and managed-repo Git workdirs from the previous run.
atmos git clone(no-arg) puts the current repository in the workspace, replacingactions/checkout. Fetch-depth guidance applies whenatmos describe affectedwill run against this clone.atmos git clone --allreconciles the restored XDG workdirs: a cache hit fetches the delta instead of performing a full clone; a cache miss performs a fresh clone.- First Git subprocess triggers the ambient broker — GitHub STS materializes
GIT_CONFIG_*credentials for Git subprocesses. - Operations run: render, publish, commit, push (with retry).
- Command end: the CI cache pending-save archives the XDG root for the next run.
A minimal GitHub Actions job replacing actions/checkout + actions/cache glue:
Cache restore/save and STS credential minting happen inside the Atmos commands — no actions/checkout, actions/cache, or token-wiring steps.
Git workdirs change on every publish, so they churn cache archives. This is safe — workdirs are regenerable and always reconciled. To keep archives lean, scope ci.cache.paths to exclude git/repositories/, trading cache hits for full clones. atmos git list --check-status shows what is currently materialized under the cache root.
Related
atmos git— the command groupkind: githooks — publish artifacts on lifecycle events- Authentication — identities and integrations
- CI Configuration — native CI detection and cache