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.
- 🔍 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
npm install -g cherrypick-interactive(You can also run it directly without installing globally using npx.)
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
cherrypick-interactiveLists commits in origin/dev that aren't in origin/main, filtered by the last week.
cherrypick-interactive --all-yescherrypick-interactive --dry-runcherrypick-interactive --ignore-commits "^chore\(deps\)|^ci:"Excludes commits starting with chore(deps) or ci: from the selection list.
cherrypick-interactive --ignore-semver "bump|dependencies"Treats commits containing "bump" or "dependencies" as chores (no version bump).
| 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 | — |
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"When cherry-picking encounters conflicts, the tool provides an interactive wizard:
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
✅ 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
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
- 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)
cherrypick-interactive --ignore-commits "^ci:|^chore\(deps\):|Merge branch"Exclude CI updates, dependency bumps, and merge commits from selection.
cherrypick-interactive --ignore-semver "bump|dependencies|merge"Prevent certain commits from affecting semantic version calculation.
cherrypick-interactive --draft-prCreates draft PRs so your team can review before merging.
cherrypick-interactive --dry-runSee what would happen without making any changes.
MIT — free to use, modify, and distribute.
- 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.
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-releaseUse the interactive wizard to resolve conflicts file-by-file or in bulk.
This issue has been fixed! The tool now preserves the original commit message using git commit -C <hash>.
Use --ignore-semver to exclude commits that shouldn't affect versioning:
cherrypick-interactive --ignore-semver "bump|chore\(deps\)"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.