Shell mode
A run string is passed to sh -c. Use it for short commands. It cannot be combined with command.
{ "name": "tests", "run": "cargo test" }
auto-push reads .auto-push.json, runs each step in order, and pushes HEAD to the branch your local branch already tracks.
Homebrew on macOS. You also need git and a local AI CLI. claude is the default. codex, ollama, or any other CLI can take the generate step. Linux and source builds are below.
brew tap dickwu/tap brew install dickwu/tap/auto-push
The names are the step ids --skip uses. This is the documented pipeline, not a guess at your repo. On first run, auto-push writes .auto-push.json with defaults for the AI CLI and project it finds.
git stash push -m 'auto-push' || truegit pullgit stash pop || truegit add -Agenerate calls claude directly in the documented pipeline and stores stdout in commit_message. The staged diff is the {{ diff }} argument. Commit style in that config is conventional commits, a 72-character subject, and a body. max_diff_bytes there is 20000.
commit runs git commit -m '{{ commit_message }}', then records the short hash and the subject. push runs git push {{ upstream_remote }} {{ push_refspec }}. If that push fails, the documented on_error waits 2 seconds, pulls the upstream branch, and pushes again.
The example pipeline also runs cargo test and cargo clippy -- -D warnings before stage. Those are project steps. Smart init may add commands that match the repo, such as npm run lint or pnpm build.
The subject in the generate window is the example from auto-push -m "feat: add user auth". It shows the conventional style. It is not a recorded run.
A push lands on the branch's upstream, by its name on the remote. That is the same branch git pull follows. main tracking origin/main pushes main. A release worktree checked out as rel-1 from origin/main still pushes main. {{ push_refspec }} is HEAD:main, not a new remote branch named rel-1.
A branch with no upstream pushes its own name to the default remote. While the pipeline runs, git sees push.default=upstream through GIT_CONFIG_* environment variables. auto-push does not write your git config. A bare git push inside any step follows the same rule.
Preflight
[preflight] rel-1 -> origin/main
auto-push --smart-init builds a project pipeline and walks you through it before anything is written.
Reads manifests such as package.json, Cargo.toml, and pyproject.toml, CI config, Docker files, and git remotes. Credentials in remote URLs are redacted before anything is sent to the AI.
Finds sub-workspaces and monorepos: npm workspaces, Cargo workspace, Lerna, Nx, and pnpm-workspace.yaml. Known directories such as src-tauri or packages/* are labeled.
Sends the project fingerprint and file tree. The reply is a JSON pipeline: the seven core steps, plus project commands. --provider chooses the CLI and writes that provider into the generated generate step.
Shows the command, a confidence of high, medium, or low, and any alternatives. Accept, edit, or remove each step.
Writes .auto-push.json. If a config file is already there, you are asked before it is overwritten.
Patterns such as curl | sh, eval, sudo, rm -rf /, and a pipe to a shell are rejected. They are neither shown nor written. auto-push --smart-init --yes skips the interactive prompts, including that overwrite check. If claude, codex, and ollama are all missing, smart init falls back to its heuristic init.
Each layer deep-merges into the one below it. Arrays, including pipeline, are replaced, not merged. The flag you type outranks the file in the repo.
One run. Nothing is written to a config file.
Glob keys such as main or feature/* replace settings for that branch. The documented example sets an empty pipeline on main, and raises the subject length to 100 on feature/*.
Project pipeline, generate style, and user variables. Created on first run when it is missing.
Preferences that apply in every repository.
The standard pipeline and commit style, used until a file replaces them.
Template variables have to resolve by the step that uses them. A forward reference is an error at load. Captured names, user vars, and built-ins such as {{ branch }}, {{ diff }}, {{ push_refspec }}, and {{ commit_message }} share one namespace. JSON fields and a regex extractor are available when a value has that shape. The full list is in the README.
Older configs that still use pre_push or after_push are migrated to pipeline at runtime, with a deprecation warning. --no-pull, --no-push, --no-generate, and --no-stash remain for one major version. --rebase means setting git pull --rebase in the pipeline.
A run string is passed to sh -c. Use it for short commands. It cannot be combined with command.
{ "name": "tests", "run": "cargo test" }
command and args are passed directly, so quotes, newlines, and a large diff do not go through a shell. Use this for the AI CLI.
{
"name": "generate",
"command": "claude",
"args": ["-p", "{{ diff }}", "--system-prompt", "{{ system_prompt }}"],
"capture": "commit_message"
}
Every flag below is in the CLI reference. Copy the line you want to run.
auto-push
Pull, stage all, generate a commit message, commit, and push.
auto-push --confirm
Prompt before each step.
auto-push --dry-run
Preview without executing.
auto-push --skip pull --skip tests
Skip pipeline commands by name. --skip is repeatable.
auto-push --skip push
Commit, and skip the push step.
auto-push -m "feat: add user auth"
Use a manual commit message. Generation is skipped.
auto-push --var slack_channel=#urgent
Override or add a template variable. --var is repeatable.
auto-push --provider codex
Override the generate command's provider for this run.
auto-push --show-config
Show the merged config for the current branch and exit.
auto-push --smart-init
Scan the project and generate a tailored pipeline.
auto-push --smart-init --yes
Auto-accept non-dangerous steps. Requires --smart-init.
auto-push --force
Auto-accept all confirmation prompts.
Prebuilt binaries exist for macOS (Apple silicon and Intel) and Linux (aarch64 and x86_64). The formula installs 0.9.0. The script installs the latest GitHub release. Release tag: v0.9.0.
Downloads the release tarball for this machine and installs the auto-push binary into /usr/local/bin. If that directory is not writable, the script uses sudo.
curl -fsSL https://raw.githubusercontent.com/dickwu/auto-push/main/install.sh | bash
Same script. INSTALL_DIR replaces /usr/local/bin.
INSTALL_DIR=~/.local/bin curl -fsSL https://raw.githubusercontent.com/dickwu/auto-push/main/install.sh | bash
Builds with Cargo from the git repository. The formula homepage and the source are the same repo.
cargo install --git https://github.com/dickwu/auto-push