Search Composal documentation

Search public documentation, commands, and release notes.

CI

MagicMerge

Automatically combine remaining text conflicts after Mergiraf when landing through the native merge queue, or retry them locally with the CLI.

On this page

Enabled on the native queue: after ordinary line merge and Mergiraf, Composal runs MagicMerge on remaining UTF-8 text conflicts while it prepares the landing candidate. MagicMerge is last resort: it does not run when line merge or Mergiraf already produced a clean file. You do not enable a merge-queue setting for this.

MagicMerge is separate from Mergiraf. Mergiraf understands supported syntax trees. MagicMerge classifies take-ours / take-theirs, and otherwise synthesizes a patch when both intents can coexist. Pull requests merged by GitHub use GitHub's merge behavior.

What happens when you land

Land your Change as usual. For each remaining text conflict, MagicMerge first asks TypeSafe Jev whether the current file already includes the incoming intent, the incoming file already includes the current intent, the edits are independent, or they assign incompatible meaning. Code then takes the current file, takes the incoming file, or asks Luna (gpt-5.6-luna, medium reasoning) for one apply_patch envelope that code applies.

A clean result continues through the usual review and required checks. If MagicMerge is unsure or the result is invalid, the conflict stays visible for you to address.

Automatic resolution does not replace code review or tests. Combining two edits successfully does not guarantee that the resulting code behaves as intended.

Watch MagicMerge on Queue health

The merge queue's Queue health panel graphs MagicMerge next to merge conflicts for the selected 7, 14, or 30-day window. Compare those two daily series to see whether rebase conflicts go down after this is on.

Each MagicMerge event is one native candidate that used it, not a landing attempt, so it does not change landing success. Queue health shows Mergiraf and last-resort MagicMerge as one series. File paths and conflict text are not stored in analytics. See Merge queue CI for the rest of queue behavior, and submit and stacking for how landing success is counted.

Know the limits

MagicMerge considers remaining UTF-8 text files up to 1 MiB per version, with a common base for the two edited versions. Binary files, NULs, conflict markers in the synthesized result, and incompatible meaning on the same fact still need manual resolution. The hosted queue includes MagicMerge when it is configured for your deployment.

Retry a conflict locally

To use MagicMerge with local JJ merges and rebases, sign in with com login so com magic-merge can reach Composal. Normal JJ rebases use it when merge.magicmerge is enabled (the default).

Terminal
com magic-merge --git base ours theirs -p src/main.rs
com resolve --tool com

com merge remains the alias for com land.

Use MagicMerge as your Git merge strategy

Git only calls MagicMerge when a merge driver is installed. Sign in, then enable the Magic Merge section in com setup, or register it from the command line:

Terminal
com login
com setup --yes --with-magic-merge

That is the same as com magic-merge --install-driver --global --gitattributes. It writes two things:

  1. A global Git merge driver named com that runs com magic-merge --git.
  2. * merge=com in your global Git attributes file, so Git uses that driver for files in every repository.

Git's default global attributes path is ~/.config/git/attributes (or $XDG_CONFIG_HOME/git/attributes). If core.attributesFile is not set, the installer points it at that file.

After this, ordinary git merge, git pull, and git rebase invoke that driver on text conflicts. The driver tries ordinary line merge, then Mergiraf, and only then MagicMerge. You still need to be signed in with com login when MagicMerge has to run.

To install it for only the current repository, omit --global:

Terminal
com magic-merge --install-driver --gitattributes

That writes the same driver into this repository's Git config and appends * merge=com to .gitattributes in the current directory.

See local counts

com magic-merge stats prints two numbers from $HOME/.composal/magic-merge-stats.json on this machine. It does not call the network.

Terminal
com magic-merge stats
Terminal
Successful merges  12
MagicMerge          8
Log                 /Users/you/.composal/magic-merge-log.jsonl

Successful merges are clean three-way resolutions. MagicMerge is when Mergiraf or last-resort MagicMerge produced the file; the command does not split those. Server-side analytics keep the Mergiraf vs MagicMerge and Jev vs Luna detail.

Inspect a MagicMerge decision

com magic-merge log reads $HOME/.composal/magic-merge-log.jsonl on this machine. It does not call the network. Each MagicMerge kick-in stores the folder the merge ran in, the file, the time, the unified diff of ours → the resolution, and the unified diff of ours → theirs so a later agent can keep MagicMerge's decision or take the other side.

Terminal
com magic-merge log
com magic-merge log --json

JSON includes an engine field (mergiraf, jev, or luna) for the behind-the-scenes split. The text listing still treats every kick-in as MagicMerge. Paths and diffs stay in this local file; they are never sent as product-analytics events.

Turn MagicMerge off locally

If you prefer to turn off automatic MagicMerge attempts during local JJ rebases:

Terminal
com config set --user merge.magicmerge false

Use true to turn them back on. This setting affects your local CLI, not the hosted merge queue, and it does not disable a Git merge driver you already installed.

To stop Git from calling MagicMerge, remove the * merge=com line from the attributes file you installed. For a global install, that file is git config --global --get core.attributesFile (often ~/.config/git/attributes). For a repository install, it is .gitattributes.

Next: land stacks in the merge queue, or return to source control.