Skip to content

fix(mcp): mergeBranch source deletion is opt-in + guards main/contentrain (data-loss regression)#68

Merged
ABB65 merged 1 commit into
mainfrom
fix/merge-source-delete-optin-guard
Jul 9, 2026
Merged

fix(mcp): mergeBranch source deletion is opt-in + guards main/contentrain (data-loss regression)#68
ABB65 merged 1 commit into
mainfrom
fix/merge-source-delete-optin-guard

Conversation

@ABB65

@ABB65 ABB65 commented Jul 9, 2026

Copy link
Copy Markdown
Member

The bug (data-loss regression)

The GitHub/GitLab providers' mergeBranch deleted the merged source branch by default (opt-out only via removeSourceBranch: false), and cleanupSourceBranch had no guard — it deleted whatever branch it was handed. Because a driver can merge a long-lived branch as the source:

  • mergeBranch('contentrain', 'main') (publish content to main) → deletes contentrain (the content SSOT)
  • mergeBranch('main', 'contentrain') (sync main in) → deletes main

This shipped as a destructive default in a minor (introduced in ee8da2d, "delete remote cr/* branches on merge"). It's the cause of the reported main/contentrain deletion. Ironically, the same commit already contained the correct pattern — the LocalProvider's deleteRemoteBranch guard (cr/*-only, never contentrain) — but it was never applied to the remote providers.

The fix

Option A + a mandatory guard (not the optional-guard framing):

  • Opt-in, not opt-out. Like git merge and the platform merge APIs, mergeBranch now leaves the source branch in place by default. removeSourceBranch: true is required to delete it.
  • Mandatory guard. Even when opted in, cleanupSourceBranch NEVER deletes:
    • the merge target into (head/base confusion),
    • the contentrain content branch,
    • the repo default branch (via 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 explicit removeSourceBranch: false pin remains valid and harmless.

Tests

github/gitlab branch-ops: default → no delete; removeSourceBranch: true → deletes cr/*; false → keeps; guard → refuses into / default branch / contentrain even 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 + tsc clean.

Ship

@contentrain/mcp patch, with a changelog note that the auto-delete default was a regression. No Studio coordination needed.

🤖 Generated with Claude Code

… 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.
@netlify

netlify Bot commented Jul 9, 2026

Copy link
Copy Markdown

Deploy Preview for contentrain-ai ready!

Name Link
🔨 Latest commit c444561
🔍 Latest deploy log https://app.netlify.com/projects/contentrain-ai/deploys/6a4f8a6ddebcc00008a82c4c
😎 Deploy Preview https://deploy-preview-68--contentrain-ai.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ABB65
ABB65 merged commit 5c8ad4f into main Jul 9, 2026
6 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 9, 2026
@ABB65
ABB65 deleted the fix/merge-source-delete-optin-guard branch July 9, 2026 11:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant