cherrypick-interactive
v1.6.1
Published
Interactively cherry-pick commits that are in dev but not in main, using subject-based comparison.
Downloads
19
Maintainers
Readme
🪶 cherrypick-interactive
Cherry-pick missing commits from dev to main — interactively and safely.
🚧 Motivation
When you maintain long-lived branches like dev and main, keeping them in sync can get messy.
Sometimes you rebase, sometimes you cherry-pick, sometimes you merge release branches — and every time, it's easy to lose track of which commits actually made it into production.
This CLI solves that pain point:
- It compares two branches (e.g.
origin/devvsorigin/main) - Lists commits in
devthat are not yet inmain - Lets you choose which ones to cherry-pick interactively
- Handles merge conflicts with an interactive resolution wizard
- Preserves original commit messages perfectly (even with squashed commits)
- (Optionally) bumps your semantic version, creates a release branch, updates
package.json, and opens a GitHub draft PR for review
No manual git log diffing. No risky merges. No guesswork.
🧭 What it does
- 🔍 Finds commits in
devnot present inmain - 🗂️ Lets you select which commits to cherry-pick (or pick all)
- 🪜 Cherry-picks in the correct order (oldest → newest)
- ⚔️ Interactive conflict resolution wizard with multiple strategies
- 🎯 Preserves exact commit messages from squashed commits
- 🪄 Detects semantic version bump (
major,minor,patch) from conventional commits - 🧩 Creates a
release/x.y.zbranch frommain - 🧾 Generates a Markdown changelog from commits
- 🧰 Optionally:
- updates
package.jsonversion - commits and pushes it
- opens a GitHub PR (draft or normal)
- updates
📦 Installation
npm install -g cherrypick-interactive(You can also run it directly without installing globally using npx.)
🚀 Quick Start
cherrypick-interactive \
--semantic-versioning \
--version-file ./package.json \
--create-release \
--push-release \
--draft-pr✅ This will:
- Fetch
origin/devandorigin/main - List commits in
devmissing frommain - Let you select which to cherry-pick
- Compute the next version from commit messages
- Create
release/<next-version>frommain - Cherry-pick the selected commits (with conflict resolution if needed)
- Update your
package.jsonversion and commit it - Push the branch and open a draft PR on GitHub
🧩 Common Use Cases
1. Compare branches manually
cherrypick-interactiveLists commits in origin/dev that aren't in origin/main, filtered by the last week.
2. Cherry-pick all missing commits automatically
cherrypick-interactive --all-yes3. Preview changes without applying them
cherrypick-interactive --dry-run4. Filter commits by pattern
cherrypick-interactive --ignore-commits "^chore\(deps\)|^ci:"Excludes commits starting with chore(deps) or ci: from the selection list.
5. Ignore certain commits from semantic versioning
cherrypick-interactive --ignore-semver "bump|dependencies"Treats commits containing "bump" or "dependencies" as chores (no version bump).
⚙️ Options
| Flag | Description | Default |
|------|--------------|----------|
| --dev | Source branch (commits to copy) | origin/dev |
| --main | Target branch (commits already merged here will be skipped) | origin/main |
| --since | Git time window filter (e.g. "2 weeks ago") | 1 week ago |
| --no-fetch | Skip git fetch --prune | false |
| --all-yes | Cherry-pick all missing commits without prompt | false |
| --dry-run | Show what would happen without applying changes | false |
| --semantic-versioning | Detect semantic version bump from commits | true |
| --current-version | Current version (if not reading from file) | — |
| --version-file | Path to package.json (to read & update version) | ./package.json |
| --create-release | Create release/x.y.z branch from main | true |
| --push-release | Push release branch to origin | true |
| --draft-pr | Create the GitHub PR as a draft | false |
| --version-commit-message | Template for version bump commit | chore(release): bump version to {{version}} |
| --ignore-semver | Comma-separated regex patterns to ignore for semver | — |
| --ignore-commits | Comma-separated regex patterns to exclude commits | — |
🧠 How Semantic Versioning Works
The tool analyzes commit messages using Conventional Commits:
| Prefix | Example | Bump |
|---------|----------|------|
| BREAKING CHANGE: | feat(auth): BREAKING CHANGE: require MFA | major |
| feat: | feat(ui): add dark mode | minor |
| fix: / perf: | fix(api): correct pagination offset | patch |
Use --ignore-semver to treat certain commits as chores:
cherrypick-interactive --ignore-semver "^chore\(deps\)|bump|merge"⚔️ Interactive Conflict Resolution
When cherry-picking encounters conflicts, the tool provides an interactive wizard:
Conflict Resolution Options:
Per-file resolution:
- Use ours — Keep the current branch's version
- Use theirs — Accept the cherry-picked commit's version
- Open in editor — Manually resolve conflicts in your editor
- Show diff — View the conflicting changes
- Mark resolved — Stage the file as-is
Bulk actions:
- Use ours for ALL — Apply current branch's version to all conflicts
- Use theirs for ALL — Accept cherry-picked version for all conflicts
- Stage ALL — Mark all files as resolved
- Launch mergetool — Use Git's configured merge tool
Key Features:
✅ Preserves original commit messages — Even when resolving conflicts, the commit message from the original commit in dev is maintained exactly
✅ Handles squashed commits — Works correctly with squashed commits that contain multiple changes
✅ Resume cherry-picking — After resolving conflicts, automatically continues with remaining commits
🧹 Why This Helps
If your team:
- Rebases or cherry-picks from
dev→main - Uses temporary release branches
- Works with squashed commits
- Needs to handle merge conflicts gracefully
- Tracks semantic versions via commits
…this CLI saves time and reduces errors.
It automates a tedious, error-prone manual process into a single command that behaves like yarn upgrade-interactive, but for Git commits.
Special features:
- ✅ Preserves exact commit messages (critical for squashed commits)
- ✅ Interactive conflict resolution without leaving the terminal
- ✅ Smart pattern-based filtering for commits and version detection
- ✅ Automatic changelog generation
🧰 Requirements
- Node.js ≥ 18
- Git ≥ 2.0
- GitHub CLI (
gh) — Optional, only required if using--push-release- Install from: https://cli.github.com/
- The tool will check if
ghis installed and offer to continue without it
- A clean working directory (no uncommitted changes)
🎯 Best Practices
1. Use --ignore-commits to filter noise
cherrypick-interactive --ignore-commits "^ci:|^chore\(deps\):|Merge branch"Exclude CI updates, dependency bumps, and merge commits from selection.
2. Use --ignore-semver for version accuracy
cherrypick-interactive --ignore-semver "bump|dependencies|merge"Prevent certain commits from affecting semantic version calculation.
3. Always use --draft-pr for review
cherrypick-interactive --draft-prCreates draft PRs so your team can review before merging.
4. Test with --dry-run first
cherrypick-interactive --dry-runSee what would happen without making any changes.
🧾 License
MIT — free to use, modify, and distribute.
🧑💻 Contributing
- Clone the repo
- Run locally:
node cli.js --dry-run - Test edge cases before submitting PRs:
- Squashed commits with conflicts
- Empty cherry-picks
- Multiple conflict resolutions
- Please follow Conventional Commits for your changes.
🐛 Troubleshooting
"GitHub CLI (gh) is not installed"
The tool automatically checks for gh CLI when using --push-release. If not found, you'll be prompted to:
- Install it from https://cli.github.com/ and try again
- Or continue without creating a PR (the release branch will still be pushed)
You can also run without --push-release to skip PR creation entirely:
cherrypick-interactive --create-release --no-push-release"Cherry-pick has conflicts"
Use the interactive wizard to resolve conflicts file-by-file or in bulk.
"Commit message changed after conflict resolution"
This issue has been fixed! The tool now preserves the original commit message using git commit -C <hash>.
"Version not detected correctly"
Use --ignore-semver to exclude commits that shouldn't affect versioning:
cherrypick-interactive --ignore-semver "bump|chore\(deps\)""Too many commits to review"
Use --ignore-commits to filter out noise, or adjust --since to a shorter time window:
cherrypick-interactive --since "3 days ago" --ignore-commits "^ci:|^docs:"Created to make release management simpler and safer for teams who value clean Git history, predictable deployments, and efficient conflict resolution.
