Know before you push. Catch merge conflicts locally in about a second, instead of 20 minutes later in CI.
Install · Usage · Git hook · Configuration · How it works · FAQ
Conflicts almost never surface when you create them. They surface after the push, in a CI log or a reviewer's comment, once the code has gone cold and a teammate is already blocked. A two-minute fix turns into a thirty-minute detour.
clearedforpush simulates the merge before you push and tells you immediately.
|
Clear Exit code |
Conflicts ahead Exit code |
It is strictly read-only. Your working directory, index, and branches are never touched.
Linux and macOS
curl -fsSL https://raw.githubusercontent.com/sanjayrohith/clearedforpush/main/scripts/install.sh | shWindows (PowerShell)
irm https://raw.githubusercontent.com/sanjayrohith/clearedforpush/main/scripts/install.ps1 | iexNo Rust toolchain required. The installer detects your platform, installs to
~/.local/bin (or %LOCALAPPDATA%\Programs\clearedforpush on Windows), and tells
you if that directory is not on your PATH.
With Cargo, or from source
cargo install clearedforpushgit clone https://github.com/sanjayrohith/clearedforpush
cd clearedforpush
cargo install --path .cargo install places the binary in ~/.cargo/bin. If clearedforpush: command not found
follows a successful install, that directory is not on your PATH:
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc # bash
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc # zsh
fish_add_path "$HOME/.cargo/bin" # fishInstaller options
| Variable | Default | Purpose |
|---|---|---|
CFP_VERSION |
latest release | Install a specific tag, e.g. v0.1.1 |
CFP_INSTALL_DIR |
~/.local/bin |
Install somewhere else |
curl -fsSL .../install.sh | CFP_INSTALL_DIR="$HOME/bin" sh$env:CFP_INSTALL_DIR = "D:\tools"; irm .../install.ps1 | iexPrefer to read before you run? See install.sh and
install.ps1.
Manual download
Grab an archive from Releases,
extract it, and move the binary onto your PATH.
| Platform | Asset |
|---|---|
| Linux (x86_64) | clearedforpush-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz |
| macOS (Apple Silicon) | clearedforpush-vX.Y.Z-aarch64-apple-darwin.tar.gz |
| macOS (Intel) | clearedforpush-vX.Y.Z-x86_64-apple-darwin.tar.gz |
| Windows (x86_64) | clearedforpush-vX.Y.Z-x86_64-pc-windows-msvc.zip |
On Linux prefer the musl archive. It is statically linked and runs on any distro regardless of glibc version.
On macOS, a binary downloaded through a browser is quarantined by Gatekeeper and will
refuse to open. Clear the flag with xattr -d com.apple.quarantine clearedforpush, or
use the one-line installer, which handles it for you.
Requires Git 2.38 or newer, which introduced git merge-tree --write-tree.
Check with git --version.
cd your-repo
clearedforpush checkThat is the whole thing. If a conflict exists you get the exact file list and a non-zero exit code.
| Command | What it does |
|---|---|
check |
Conflict detection against the auto-detected base, PR-aware |
check --base develop |
Check against a specific base branch |
check --stats |
Add ahead/behind counts, files changed, line diffs |
check --diff |
Print the conflicting diff hunks |
check --skip-prs |
Skip checking against open pull requests |
check --format <fmt> |
Emit text, json, or compact |
install-hook [--force] |
Install the pre-push hook |
uninstall-hook |
Remove the pre-push hook |
init |
Write a .clearedforpush.toml template |
clearedforpush check --stats| Symbol | Meaning |
|---|---|
| ↑ | Commits you are ahead of base |
| ↓ | Commits base is ahead of you |
| ◫ | Files changed |
| ± | Insertions and deletions |
Exit codes are stable: 0 when clean, 1 when conflicts exist.
clearedforpush check && git push--format json emits a versioned schema suited to parsing:
{
"version": 1,
"current_branch": "feature-x",
"base_branch": "main",
"has_conflicts": false,
"exit_code": 0,
"conflicted_files": [],
"conflict_diffs": [],
"stats": { "ahead": 3, "behind": 1, "files_changed": 5 },
"pr_conflicts": []
}--format compact reduces it to one line: OK: no conflicts or
CONFLICT: file1.rs, file2.rs.
clearedforpush install-hookEvery push now runs a conflict check first, and a push carrying conflicts is blocked.
git push --no-verify # bypass when you need toAn existing pre-push hook is never clobbered. You get a warning, and --force chains
onto it rather than overwriting:
clearedforpush install-hook --force
clearedforpush uninstall-hook # removes only our sectionclearedforpush init# Base branch, auto-detected when unset
base = "develop"
# Check open PRs for conflicts (default: true)
check_prs = true
# Default output format: "text", "json", or "compact"
format = "text"
stats = true
diff = false
# Paths to ignore when reporting conflicts
ignore = ["*.lock", "docs/**", "*.generated.*"]
[github]
# Alternative to the GITHUB_TOKEN env var
token = "ghp_..."CLI flags always override config-file values.
clearedforpush shells out to Git's own merge-tree --write-tree plumbing to simulate
the merge in memory. Nothing on disk is modified.
sequenceDiagram
autonumber
participant You
participant CFP as clearedforpush
participant Git
You->>CFP: clearedforpush check
CFP->>Git: detect current and base branch
CFP->>Git: fetch base branch (read-only)
CFP->>Git: merge-tree --write-tree
Git-->>CFP: simulated merge tree
CFP->>CFP: parse conflicts, check open PRs
CFP-->>You: CLEAR (exit 0) or HOLD (exit 1)
Why not git merge --no-commit? That mutates your index and can strand you in a
half-merged state. The lower-level plumbing leaves the repository provably untouched:
no working-directory changes, no index writes, no branch updates, no stashing.
Does it modify my repository?
No. It only reads. Your working directory, index, HEAD, and branches are untouched.
What Git version do I need?
Git 2.38.0 or later (October 2022), which introduced
--write-tree for merge-tree.
Can I check against a branch other than main?
Yes.
clearedforpush check --base develop works with any branch, and you can set base in .clearedforpush.toml to make it the default.
Does it need network access?
It fetches the base branch from
origin so you compare against current remote state, so yes for check. Pull request awareness additionally needs either the gh CLI authenticated or a GITHUB_TOKEN; use --skip-prs to turn it off.
Is it fast enough to run on every push?
Yes. It is designed to finish in under two seconds on typical repositories, which is why the pre-push hook is practical.
Can I use it in CI?
Yes. Use
--format json for a stable, versioned schema, or rely on the exit codes in a shell script.
- Core conflict detection
- Branch statistics
- Pre-push hook integration
- GitHub pull request awareness
- Diff hunks, JSON and compact output
-
.clearedforpush.tomlconfiguration - Prebuilt binaries and one-line installers
- GitHub Actions and GitLab CI templates
Contributions are welcome. See CONTRIBUTING.md to get started.
Licensed under either of MIT or Apache-2.0, at your option.