Git AutoMerge is a CLI tool to automate merging multiple remote Git branches into a temporary branch, tagging that branch with an environment-specific tag, pushing the tag to origin, and cleaning up afterward.
- Reads configuration from a YAML file defining multiple environments
- Supports read the configuration YAML from origin default branch
- Supports wildcard patterns for included remote branches to merge
- Creates a temporary branch from a base branch before merging
- Tags the merge commit with an environment name and timestamp
- Pushes the tag to the remote repository
- Automatically cleans up the temporary branch and local tag
- Supports optional customizable tag prefix per environment
- Auto-resolves merge conflicts using configurable strategies
- Records and replays conflict resolutions with
git rerere
Via curl
curl -sSL https://raw.githubusercontent.com/git-automerge/automerge/main/install.sh | sudo bashVia wget
wget -qO - https://raw.githubusercontent.com/git-automerge/automerge/main/install.sh | sudo bashDownload directly
curl -L https://github.com/git-automerge/automerge/blob/main/bin/git-automerge -o /usr/local/bin/git-automerge
chmod +x /usr/local/bin/git-automergeAdd .tmp_automerge-config.yaml to the .gitignore
git automerge --helpCreate a automerge-config.yaml file in your project root with this structure:
config_source: origin/main:automerge-config.yaml # Optional; Read config from remote branch
envs:
staging:
base: main
branches:
- "bugfix/*"
tag_prefix: "prod-" # Optional; Default is "automerge-" if empty or false, no prefix used
feature:
base: develop
branches:
- "feature/*"
tag_prefix: false # omitted here; no prefix will be used- Check your working directory is clean.
- Fetch all remote branches.
- Create a temporary branch from the base branch.
- Merge all matching remote branches.
- Push mode option for "tag" or "branch"
- Tag the commit with a timestamp and environment name.
- Push the tag to the remote.
- Clean up local temporary branch and tag, and restore your original branch.
---
config:
theme: redux
layout: dagre
---
flowchart LR
cliStage(["git automerge --env=staging"]) --> envStage
cliProd(["git automerge --env=production"]) --> envProd
subgraph envStage["Env Staging"]
direction LR
stageMain(["main"]) --> stagingAutomerge["automerge-***"]
stageFeature1(["feature/1"]) --> stagingAutomerge
stageFeature2(["feature/1"]) --> stagingAutomerge
end
subgraph envProd["Env Production"]
direction LR
prodMain(["main"]) --> prodAutomerge["automerge-***"]
prodFeature1(["feature/1"]) --> prodAutomerge
prodFeature2(["feature/1"]) --> prodAutomerge
end
stagingAutomerge -.-> pipeline
prodAutomerge -.-> pipeline
By default, git-automerge reads its configuration from a local automerge-config.yaml file. However, this can create inconsistencies if developers run the tool from different branches with outdated or incomplete config files.
To solve this, you can define a remote config source using the config_source option at the top level of your config file.
🔒 Consistency: Always uses the canonical config from the main branch, even when running the tool on a feature branch.
🌐 Centralized Control: Ensures all developers and CI runners use the same rules for branching, tagging, and merging.
🔄 Dynamic Updates: Changes to the config take effect immediately without requiring a rebase or manual update on local clones.
- The local config file is read first.
- If config_source is set, the script fetches the config from the specified Git reference (e.g. origin/main:automerge-config.yaml) using git show.
- The fetched config replaces the local one for the current operation.
- If config_source is missing or empty, the local config is used as fallback.
By default, when a merge conflict is detected git-automerge pauses and prompts you to resolve it manually, then continues once you press ENTER.
You can configure an automatic conflict resolution strategy so that unambiguous conflicts are resolved without human input. The strategy can be set globally or overridden per environment — the per-environment value takes precedence.
conflict_strategy: theirs # global default
envs:
staging:
base: main
branches:
- "feature/*"
conflict_strategy: ours # overrides global for this env| Strategy | Behaviour |
|---|---|
ours |
Keeps the current branch's version of every conflict |
theirs |
Accepts the incoming branch's version of every conflict |
ours+whitespace |
ours, also ignoring whitespace-only differences |
theirs+whitespace |
theirs, also ignoring whitespace-only differences |
whitespace |
Auto-resolves whitespace-only conflicts; manual resolution for all others |
When a strategy is active, git-automerge prints the selected strategy before merging begins. If Git still cannot auto-resolve every conflict with the chosen strategy, it falls back to the interactive prompt so you can resolve the remainder by hand.
Pass --no-conflict-strategy on the command line to ignore any configured conflict_strategy for the current run and fall back to interactive (manual) conflict resolution:
git automerge --env=staging --no-conflict-strategyThis is useful for one-off runs where the configured strategy should not auto-resolve conflicts — for example, when merging branches with intentional divergence that needs human review. The flag has no effect on rerere; recorded resolutions are still replayed if rerere: true is set.
Setting rerere: true enables git rerere (reuse recorded resolution) for the duration of the run. When enabled, Git records how you resolve each conflict the first time it appears. On future runs that encounter the same conflict, Git replays the recorded resolution automatically — no manual intervention needed.
rerere: true
envs:
staging:
base: main
branches:
- "feature/*"rerere is disabled by default. When enabled, git-automerge temporarily sets rerere.enabled = true in the local repo config for the run, then restores the previous value (or unsets it) on exit, so it does not permanently alter your repository configuration.
rerere pairs well with conflict_strategy: the strategy handles simple conflicts automatically on the first encounter, and rerere handles them automatically on every subsequent run.
By default, the remote tag or branch created by git-automerge is kept after push. Set cleanup_remote: true to delete it automatically once the push succeeds.
cleanup_remote: true # default: false
envs:
staging:
base: main
branches:
- "feature/*"This is useful when the pushed tag or branch serves only as a transient deployment trigger and should not accumulate in the remote repository.