Skip to content

Repository files navigation

✈  C L E A R E D    F O R    P U S H

Know before you push.

Catch merge conflicts before you push — not during CI, not in PR review,
not when your teammate pings you at 5 p.m.


Crates.io License Rust Git


Quick Start  ·   How It Works  ·   Install  ·   Usage  ·   Config


Cleared for Push — clean check

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

▸  The Problem

Every developer knows this pain:

$ git push origin feature-branch
  ✓ Pushed! Time for coffee ☕

  ... 20 minutes later ...

  ✗ CI failed: merge conflicts in 4 files
  ✗ Or worse — your reviewer finds them
  ✗ Or worse still — you discover them mid-rebase

By the time conflicts surface, you've lost all context. The code is cold, the CI queue is backed up, and a teammate is blocked. A 2-minute fix becomes a 30-minute detour.


▸  The Solution

Cleared for Push tells you the moment a conflict exists — before you push.

✓  All clear

╭──────────────────────────────╮
│      CLEAR FOR TAKEOFF       │
│                              │
│  No conflicts. Safe to push! │
╰──────────────────────────────╯

Push with confidence.

✗  Conflicts ahead

╭──────────────────────────────╮
│  HOLD FOR CLEARANCE          │
│                              │
│  Conflicts detected.         │
╰──────────────────────────────╯
  ✗ src/auth.rs
  ✗ src/main.rs

Fix now, while it's fresh.

Fast. Safe. Zero setup. It never touches your working directory.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◈  How It Works

Under the hood, Cleared for Push shells out to Git's own merge-tree --write-tree plumbing to simulate a merge in memory. Nothing on disk is ever modified.

YOU                            CLEARED FOR PUSH                 GIT
  │                              │                                │
  │                              clearedforpush check             │
  ├──────────────────────────────▶                                │
  │                              │                                │
  │                              ①  detect current & base branch │
  │                              ├────────────────────────────────▶
  │                              │                                │
  │                              ②  fetch base branch (read-only) │
  │                              ├────────────────────────────────▶
  │                              │                                │
  │                              ③  merge-tree --write-tree      │
  │                              ├────────────────────────────────▶
  │                              │                                │
  │                              simulated merge tree             │
  │                              ◀────────────────────────────────┤
  │                              │                                │
  │                              ④  parse conflict markers       │
  │                                  (+ open-PR awareness)        │
  │                              │                                │
  │                              ✓ CLEAR  /  ✗ HOLD               │
  ◀──────────────────────────────┤
  exit 0  /  exit 1

┌────────────────────────────────────────────────────────────────────────────┐
│  READ-ONLY GUARANTEE                                                       │
│  ✗ no working-dir changes    ✗ no index writes                             │
│  ✗ no branch updates         ✗ no stash operations                         │
└────────────────────────────────────────────────────────────────────────────┘

Why not git merge --no-commit?  That still mutates your index and can leave you in a half-merged state. We use the lower-level plumbing so your repo is guaranteed untouched.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚡  Quick Start

# 1. Install
cargo install clearedforpush

# 2. Check before you push
cd your-git-repo
clearedforpush check

That's the whole thing. If there's a conflict, you'll know instantly — with the exact files listed.


✦  Why You'll Love It

Beautiful CLI

An aviation-themed interface that makes conflict checking genuinely pleasant.

Lightning Fast

Powered by Git's native merge-tree. Typically under 2 seconds.

100% Safe

Read-only. Never touches your working directory, index, or branches.

Smart Stats

See ahead/behind counts, files changed, and line diffs at a glance.

PR Awareness

Detects conflicts with open pull requests targeting the same base.

CI Friendly

Text, JSON, and compact output formats. Stable exit codes.


⏱  Before & After

Without Cleared for Push With Cleared for Push
Feedback Push → wait for CI → CI fails Check locally in ~1 second
Context Lost, code gone cold Fresh in your head
Team Blocked on your branch Stays unblocked
CI Wasted minutes and queue time Clean runs, every time
Rebase Surprise conflicts mid-rebase Know exactly what collides

One command saves you a broken CI run, a context switch, and a frustrating rebase.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⬇  Installation

Cargo  ·  recommended

cargo install clearedforpush

Homebrew  ·  macOS / Linux

brew install sanjayrohith/tap/clearedforpush

AUR  ·  Arch Linux

yay -S clearedforpush

From source

git clone https://github.com/sanjayrohith/clearedforpush
cd clearedforpush
cargo install --path .

Requirements

  • Git 2.38+  ·  git --version
  • Rust 1.70+  ·  source builds only

Prebuilt binaries — grab the latest from Releases:

Platform Asset
◆  Linux (x86_64) clearedforpush-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz
◆  macOS (Intel) clearedforpush-vX.Y.Z-x86_64-apple-darwin.tar.gz
◆  macOS (Apple Silicon) clearedforpush-vX.Y.Z-aarch64-apple-darwin.tar.gz
◆  Windows (x86_64) clearedforpush-vX.Y.Z-x86_64-pc-windows-msvc.zip
# Example: Linux
curl -LO https://github.com/sanjayrohith/clearedforpush/releases/latest/download/clearedforpush-v0.1.0-x86_64-unknown-linux-musl.tar.gz
tar xzf clearedforpush-*.tar.gz
sudo mv clearedforpush /usr/local/bin/

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠  Troubleshooting

clearedforpush: command not found after cargo install

cargo install places the binary in ~/.cargo/bin. If that directory isn't on your PATH, your shell can't find the command — even though the install succeeded. This is the most common post-install issue and it affects every command, including --help.

Quick check — confirm the binary exists and where it lives:

ls ~/.cargo/bin/clearedforpush     # should print the path
echo $PATH | tr ':' '\n' | grep -q "$HOME/.cargo/bin" && echo "on PATH" || echo "NOT on PATH"

Fix — add ~/.cargo/bin to your PATH (pick your shell):

# bash
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc

# zsh
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

# fish
fish_add_path "$HOME/.cargo/bin"
# Windows (PowerShell) — add %USERPROFILE%\.cargo\bin permanently
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:USERPROFILE\.cargo\bin", "User")

If you installed Rust via rustup, the installer normally appends this line for you. A fresh terminal (or source-ing your rc file) is required for the change to take effect.

Verify:

clearedforpush --help     # should now print usage

Prefer not to touch your PATH? Install a prebuilt binary straight into a directory that's already on it (see Installation) — e.g. sudo mv clearedforpush /usr/local/bin/.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

▶  Usage

Basic check

clearedforpush check

Checks your current branch against the base branch (auto-detected as main or master).

With statistics

clearedforpush check --stats
clearedforpush check --stats

Adds a detailed breakdown:

Symbol Meaning
Commits you're ahead of base
Commits base is ahead of you
Number of files changed
± Insertions and deletions

Custom base branch

clearedforpush check --base develop

Show conflict diffs

clearedforpush check --diff

When conflicts exist, prints the actual diff hunks with syntax highlighting (additions in green, deletions in red).

JSON output  ·  for CI / scripting

clearedforpush check --format json --skip-prs
clearedforpush check --format json

A stable, versioned schema:

{
  "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": []
}

Compact output

clearedforpush check --format compact

Single line:  OK: no conflicts  or  CONFLICT: file1.rs, file2.rs

In a script or CI

clearedforpush check && git push

Exits 0 when clean and 1 when conflicts exist — composes cleanly with && and CI pipelines.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⎇  Git Hook  ·  auto-check on every push

clearedforpush install-hook
clearedforpush install-hook

Now every push runs a conflict check first. If conflicts exist, the push is blocked.

# Bypass when you really need to:
git push --no-verify

Already have a pre-push hook? It won't clobber it — it warns you, and --force chains onto the existing hook instead of overwriting:

clearedforpush install-hook --force     # append safely
clearedforpush uninstall-hook           # remove only our section

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚙  Configuration

Generate a .clearedforpush.toml in your repo root:

clearedforpush init
# Base branch (auto-detected if not set)
base = "develop"

# Check open PRs for conflicts (default: true)
check_prs = true

# Default output format: "text", "json", or "compact"
format = "text"

# Show statistics by default
stats = true

# Show conflict diffs by default
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.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⌨  Command Reference

clearedforpush --help
clearedforpush --help
Command Description
check Run conflict detection (PR-aware by default)
check --stats Include ahead/behind and diff statistics
check --diff Show conflicting diff hunks with highlighting
check --base <branch> Check against a specific base branch
check --skip-prs Skip checking against open PRs
check --format <fmt> Output as text, json, or compact
install-hook [--force] Install as a pre-push git hook
uninstall-hook Remove the pre-push hook
init Generate a .clearedforpush.toml template

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

❔  FAQ

Does it modify my repository?
No. It only reads. Your working directory, index, HEAD, and branches remain completely untouched. This is a hard guarantee.
What Git version do I need?
Git 2.38.0 or later (October 2022), which introduced the --write-tree flag for merge-tree. Check with git --version.
Can I use a base branch other than main?
Yes — clearedforpush check --base develop works with any branch.
Does it work with remote branches?
Yes. It fetches the latest state of the base branch from origin before checking, so you always compare against the most recent remote state.
Can I use it in CI?
Absolutely. Use --format json for structured output with a stable schema, or rely on exit codes (0 = clean, 1 = conflicts) in shell scripts.
Is it fast enough for a git hook?
Yes — designed to run in under 2 seconds for typical repos.
I installed it but get command not found — why?
cargo install puts the binary in ~/.cargo/bin. If that directory isn't on your PATH, the shell can't find clearedforpush even though the install succeeded. See Troubleshooting for the one-line fix per shell.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⬢  Roadmap

[✓] Core conflict detection
[✓] Statistics display
[✓] Git hook integration        install-hook / uninstall-hook
[✓] GitHub PR awareness         conflicts against open PRs
[✓] Better reporting            diff hunks · JSON · compact
[✓] Configuration               .clearedforpush.toml
[✓] Distribution                CI/CD · binaries · AUR · Homebrew
[ ] CI integrations             GitHub Actions · GitLab CI templates

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚑  Contributing

Contributions are welcome. See CONTRIBUTING.md to get started.

§  License

Licensed under either of MIT (LICENSE-MIT) or Apache-2.0 (LICENSE-APACHE), at your option.


Built with ♥ by developers, for developers

Report a Bug  ·  Request a Feature



Clear skies and clean merges.  ✈

About

Catch merge conflicts before you push

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages