fix(mcp): mergeBranch source deletion is opt-in + guards main/contentrain (data-loss regression)#68
Merged
Merged
Conversation
… branches The GitHub/GitLab providers' mergeBranch deleted the merged SOURCE branch by default (opt-out via removeSourceBranch: false), with no guard. Because it deletes whatever `branch` it is given, a driver merging a long-lived branch — contentrain→main (publish) or main→contentrain (sync) — would delete contentrain or main. A destructive default that shipped in a minor: a regression, and a data-loss hazard. - Opt-in, not opt-out: like git merge and the platform merge APIs, mergeBranch now leaves the source branch alone by default. Callers that want cr/* cleanup pass removeSourceBranch: true. - Mandatory guard: even when opted in, cleanupSourceBranch never deletes the merge target (into), the contentrain content branch, or the repo default branch (getDefaultBranch; fail-safe skips if unresolvable). Mirrors the LocalProvider's cr/*-only guard; defends against head/base confusion. Both providers. LocalProvider path unchanged (merges only cr/* + guards its own remote cleanup). Studio's explicit removeSourceBranch: false stays valid. Tests: github+gitlab branch-ops — default no-delete, opt-in deletes, guard protects into/default/contentrain even when opted in, fail-safe on unresolvable default. 112/112 across providers + http integration.
✅ Deploy Preview for contentrain-ai ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug (data-loss regression)
The GitHub/GitLab providers'
mergeBranchdeleted the merged source branch by default (opt-out only viaremoveSourceBranch: false), andcleanupSourceBranchhad no guard — it deleted whateverbranchit was handed. Because a driver can merge a long-lived branch as the source:mergeBranch('contentrain', 'main')(publish content to main) → deletescontentrain(the content SSOT)mergeBranch('main', 'contentrain')(sync main in) → deletesmainThis shipped as a destructive default in a minor (introduced in
ee8da2d, "delete remote cr/* branches on merge"). It's the cause of the reportedmain/contentraindeletion. Ironically, the same commit already contained the correct pattern — the LocalProvider'sdeleteRemoteBranchguard (cr/*-only, nevercontentrain) — but it was never applied to the remote providers.The fix
Option A + a mandatory guard (not the optional-guard framing):
git mergeand the platform merge APIs,mergeBranchnow leaves the source branch in place by default.removeSourceBranch: trueis required to delete it.cleanupSourceBranchNEVER deletes:into(head/base confusion),contentraincontent branch,getDefaultBranch; fail-safe — skips the delete if the default can't be resolved).Both providers. The LocalProvider path is untouched (it merges only
cr/*and already guards its own remote cleanup). Studio's explicitremoveSourceBranch: falsepin remains valid and harmless.Tests
github/gitlabbranch-ops: default → no delete;removeSourceBranch: true→ deletescr/*;false→ keeps; guard → refusesinto/ default branch /contentraineven when opted in; fail-safe when the default branch can't be resolved; 404/422 → not-found; other failure → warning; merge failure → no cleanup. 112/112 across all providers + http integration;oxlint+tscclean.Ship
@contentrain/mcppatch, with a changelog note that the auto-delete default was a regression. No Studio coordination needed.🤖 Generated with Claude Code