Skip to Content
DocumentationDocumentationProvidersgit (config + clone)

git Provider

Wraps the real git CLI so hams git … behaves exactly like plain git for every subcommand, with two exceptions that hams records into a Hamsfile: hams git config keys and hams git clone targets. Every other verb (status, pull, push, log, …) passes through unchanged.

Platforms: macOS, Linux

Usage

hams git config — global git config

# Set a value (and record it to the Hamsfile) hams git config --global user.name "Your Name" hams git config --global user.email "[email protected]" # See what's managed hams git config list # Unset (drops from Hamsfile, clears on the machine) hams git config remove rerere.autoUpdate

hams git clone — pinned local clones

# Add: clone a remote repo to a local path (matches plain `git clone`) hams git clone https://github.com/zthxxx/dotfiles ~/Projects/dotfiles # See what's managed hams git clone list # Remove (stops managing; leaves the local files alone) hams git clone remove urn:hams:git-clone:dotfiles

Everything else — plain git, just prefixed

hams git status # → git status hams git pull # → git pull hams git log --oneline # → git log --oneline

Passthrough preserves stdin / stdout / stderr / exit code, so aliasing git=hams git is safe.

Hamsfile example

git-config and git-clone keep separate Hamsfiles and state files, so you can version-control your identity config and your cloned-repo list independently:

# macOS/git-config.hams.yaml schema_version: 1 provider: git-config groups: - tag: identity items: - urn: "urn:hams:git-config:user-name" step: Set git user name key: user.name value: "Your Name" - urn: "urn:hams:git-config:user-email" step: Set git user email key: user.email value: "[email protected]" - tag: workflow items: - urn: "urn:hams:git-config:rerere" step: Enable git rerere (remember conflict resolutions) key: rerere.autoUpdate value: "true"
# macOS/git-clone.hams.yaml schema_version: 1 provider: git-clone groups: - tag: personal items: - urn: "urn:hams:git-clone:dotfiles" step: Clone dotfiles repository remote: https://github.com/zthxxx/dotfiles.git local_path: ~/Projects/dotfiles default_branch: main

Fields for git-config:

  • key / value — exactly the git config key and value
  • step — a one-line description that shows up in apply logs
  • urn — hams’s internal ID. Keep it readable

Fields for git-clone:

  • remote — repo URL (HTTPS or SSH, your choice)
  • local_path — local target path, ~/ is expanded
  • default_branch — optional. Checkout to this branch after cloning. If omitted, use the remote default

How state is probed

git-config: for each entry, hams runs git config --global --get <key> and compares to the Hamsfile value. Match → ok. Different → outdated. Missing → missing.

git-clone: the check is pragmatic:

  1. Does local_path exist?
  2. If so, does git -C <local_path> remote get-url origin match the Hamsfile remote?
  3. Both match → ok.

hams doesn’t pull for you. Auto-pulling every apply would slow things down and occasionally cause conflicts. Deciding when to pull is your call.

go-git, not the system git

The hams binary bundles go-git , so the machine doesn’t need git installed for clone-based resources to work. That matters during bootstrap: you don’t need to brew install git before starting an apply.

System vs user scope (git config)

By default, hams writes to --global scope (your user’s ~/.gitconfig). Special cases:

  • Repo-scope (--local) — doesn’t belong in hams at all. That’s per-project config, and it lives with the project.
  • System-scope (--system) — use the bash provider with sudo git config --system ....

SSH authentication (git clone)

For SSH-style remotes ([email protected]:...), hams tries in order:

  1. Common key paths: ~/.ssh/id_ed25519, ~/.ssh/id_rsa, and similar
  2. Keys loaded in a running ssh-agent
  3. Falls back to interactive prompts if needed

The typical snag on a fresh machine: SSH keys haven’t been set up yet. Two workarounds: use HTTPS URLs (pair with gh auth login or a PAT), or get SSH keys in place before running apply.

Handy patterns

Separate work and personal identity. git’s includeIf directive loads different configs based on where the repo sits. hams can manage both the directive and the pointer:

- urn: "urn:hams:git-config:work-includeif" step: Include work config when under ~/work/ key: 'includeIf."gitdir:~/work/".path' value: ~/.gitconfig-work

GPG signing. The signing key ID is identity-level config, so this is a natural fit:

- urn: "urn:hams:git-config:signing-key" step: Set GPG signing key key: user.signingkey value: "AAAAAAAAAA" - urn: "urn:hams:git-config:commit-gpgsign" step: Sign all commits key: commit.gpgsign value: "true"

Don’t put sensitive values into the committed Hamsfile. Tokens, the GPG key’s private ID, anything secret — put them in git-config.hams.local.yaml (gitignored) or the system keychain.

hams git clone is for “I need this repo, at this exact path.” If you just want to run a script once, curl | bash inside a bash provider step is simpler. git-clone earns its weight when you want hams to keep ensuring the repo exists at the right location.

Last updated on