feat: implement single commit cherry pick#2282
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds cherry-pick support: new public Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant API as cherryPick API
participant Cmd as _cherryPick Command
participant Git as Git Ops
participant Merger as mergeTree
participant Index as Index/Worktree Manager
User->>API: cherryPick({ oid, options })
API->>API: validate params / normalize committer
API->>Cmd: _cherryPick({ oid, options })
Cmd->>Git: readCommit(oid)
Git-->>Cmd: commitObj
Cmd->>Git: readCommit(HEAD)
Git-->>Cmd: headCommit
Cmd->>Git: readCommit(parent of oid)
Git-->>Cmd: baseCommit
Cmd->>Merger: mergeTree(our=HEAD.tree, base=base.tree, their=oid.tree, mergeDriver)
Merger-->>Cmd: mergedTree or MergeConflictError
alt MergeConflictError & abortOnConflict
Cmd-->>API: throw MergeConflictError
else Conflicts handled / merged
Cmd->>Git: commit(tree=mergedTree, parent=HEAD, author=orig, committer=new)
Git-->>Cmd: newOid
Cmd->>Index: applyTreeChanges(newOid) (unless dryRun/noUpdateBranch)
Index-->>Cmd: index/worktree updated
Cmd-->>API: return newOid
end
API-->>User: newOid or error
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@jcubic Requesting review 😄 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@__tests__/test-cherryPick.js`:
- Around line 19-20: Reorder the import statements to satisfy ESLint import
grouping: move the package import "isomorphic-git/internal-apis"
(GitIndexManager) above the relative import './__helpers__/FixtureFS.js'
(makeFixture), and add a blank line between the external package import and the
relative import so there is a clear separation.
- Around line 186-188: Replace the dynamic import of merge with a static import
and use that symbol directly: add merge to the existing static import list at
the top (alongside any existing import like mergeApi) and then remove the
dynamic line "const merge = await import('isomorphic-git').then(m => m.merge)"
and call the statically imported merge(...) directly in the test where you
currently call merge({ fs, dir, gitdir, theirs: 'a' }).
🧹 Nitpick comments (4)
src/errors/CherryPickMergeCommitError.js (1)
1-18: Error class follows established patterns — LGTM.The structure mirrors other error classes in the codebase (code, name, data pattern).
One minor observation: the message says "require specifying which parent to use as the base" (Line 11), but the current
cherryPickAPI doesn't expose a parameter to do so. Consider adjusting the message to avoid implying unsupported functionality, or add a note that this may be supported in the future.src/commands/cherryPick.js (1)
118-130: NosigningKey/onSignsupport — acceptable for initial implementation.The
_commitcall doesn't forward signing-related parameters. Users who require GPG-signed cherry-pick commits won't be able to use this directly. Consider noting this as a known limitation or a future enhancement.src/index.js (1)
87-88:cherryPickis listed beforecheckoutin exports — reversed alphabetical order.The imports (Lines 12–13) correctly place
checkoutbeforecherryPick, but the named exports have them swapped. Same issue in the default export (Lines 162–163).Proposed fix
Named exports:
branch, - cherryPick, checkout, + cherryPick, clone,Default export:
branch, - cherryPick, checkout, + cherryPick, clone,__tests__/test-cherryPick-in-submodule.js (1)
22-137: Extract repeated submodule setup into a helper function.The submodule wiring boilerplate (makeFixture, mkdir, cp, writeFile gitdir pointer, init) is duplicated verbatim across all 6 tests (~20 lines each). This makes the tests harder to maintain — any change to the setup pattern requires updating every test.
Suggested helper
async function setupSubmoduleRepo(fixtureName, submoduleName) { const { fs: fssp, dir: dirsp } = await makeFixture('superproject-test') const { dir, gitdir } = await makeFixture(fixtureName) await fssp._mkdir(join(dirsp, '.git')) await fssp._mkdir(join(dirsp, '.git', 'modules')) const gitdirsmfullpath = join(dirsp, '.git', 'modules', submoduleName) await fssp._cp(gitdir, gitdirsmfullpath, { recursive: true }) const officialSubmoduleDir = join(dirsp, submoduleName) await fssp._cp(dir, officialSubmoduleDir, { recursive: true }) const submoduleGitFile = join(officialSubmoduleDir, '.git') await fssp._writeFile( submoduleGitFile, `gitdir: ../.git/modules/${submoduleName}\n` ) await init({ fs: fssp, dir: officialSubmoduleDir, gitdir: submoduleGitFile }) return { fs: fssp, dir: officialSubmoduleDir, gitdir: submoduleGitFile } }Each test then becomes:
const { fs, dir, gitdir } = await setupSubmoduleRepo('tmp-cherry-sub', 'mysubmodule')
|
Thanks for the PR. Will try to check tomorrow. |
There was a problem hiding this comment.
Pull request overview
This PR adds a new cherryPick public API to isomorphic-git to support single-commit cherry-picking onto the current branch, including conflict handling, dry-run, and no-update options (closing #1736).
Changes:
- Exposes a new
cherryPickAPI viasrc/index.jsand export tests. - Implements cherry-pick logic via a three-way merge + commit creation, with optional workdir/index update.
- Adds a new
CherryPickMergeCommitErrorand comprehensive test coverage (including submodule scenarios).
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/index.js | Exports the new cherryPick API (named + default export). |
| src/api/cherryPick.js | Public API wrapper: parameter validation, gitdir discovery, committer normalization, delegates to command. |
| src/commands/cherryPick.js | Core cherry-pick implementation (read commits, merge trees, commit result, update workdir/index). |
| src/errors/CherryPickMergeCommitError.js | New error type for rejecting merge commits. |
| src/errors/index.js | Re-exports the new error from the Errors bundle. |
| tests/test-exports.js | Ensures cherryPick is part of the public exports. |
| tests/test-exports-in-submodule.js | Ensures cherryPick export works in submodule test harness. |
| tests/test-cherryPick.js | New test suite for cherry-pick behavior and options. |
| tests/test-cherryPick-in-submodule.js | Cherry-pick test suite in submodule scenario. |
| README.md | Adds contributor entry. |
| .all-contributorsrc | Adds contributor metadata. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@jcubic I have updated the PRs after fixing the comments. Let me know if anything else needs to be fixed. |
|
Looks good. Can you add one more check for the happy path? You only check the message of the commit. It would be a good idea to check if the work tree has content from the cherry-picked commit and if the staging area is empty. You can use the git.status on the file that was changed or git.statusMatrix. The command just uses mergeTree, but it will not hurt if we check if the state of the Git repo is correct. |
@jcubic Done |
|
🎉 This PR is included in version 1.37.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
I'm fixing a bug or typo
npm run add-contributorand follow the prompts to add yourself to the READMEI'm adding a parameter to an existing command X:
src/api/X.js(andsrc/commands/X.jsif necessary)__tests__/test-X.jsif possiblenpm run add-contributorand follow the prompts to add yourself to the READMEI'm adding a new command:
src/api(andsrc/commandsif necessary)src/index.js__tests__/test-exports.jssrc/__tests__website/sidebars.jsonwebsite/versioned_sidebars/version-1.x-sidebars.jsonnpm run add-contributorand follow the prompts to add yourself to the READMEShould close: #1736
Summary by CodeRabbit