{"record":{"id":"2b1cbde65c706574","repo":"jdx/mise","slug":"changed-in-the-complete-repository-merge-recon","errorCode":null,"errorMessage":"{} changed in the complete repository merge; reconcile again","messagePattern":"(.+?) changed in the complete repository merge; reconcile again","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/sync/apply.rs","lineNumber":482,"sourceCode":"                .iter()\n                .map(|step| {\n                    Ok(crate::system::history::shadow::Overlay {\n                        path: step.pending.branch_path.clone(),\n                        object: repo.object_at(local, &step.pending.branch_path)?,\n                    })\n                })\n                .collect::<Result<Vec<_>>>()?;\n            if repo.compose(&repo.output_tree_of(current)?, &restore_planned)?\n                != repo.output_tree_of(local)?\n            {\n                bail!(\"local files were saved after enrollment planning; retry pull\");\n            }\n            // Do not let a divergent text merge or a stale resolution differ\n            // from the complete tree that will be adopted.\n            for step in &ready {\n                if repo.restored_object_at(tree, &step.pending.branch_path)? != step.pending.object\n                {\n                    bail!(\n                        \"{} changed in the complete repository merge; reconcile again\",\n                        display_path(&step.path)\n                    );\n                }\n            }\n            let candidate = heads\n                .candidate(repo, tree)?\n                .ok_or_else(|| eyre::eyre!(\"setup branch disappeared\"))?;\n            super::files::audit_history(repo, &candidate.commit, &Default::default())?;\n        }\n        // Validate the complete batch again after acquiring the operation\n        // lock, before the first write.\n        for directory in &directories {\n            directory.validate()?;\n        }\n        for step in &ready {\n            if live_object(repo, &step.path)? != step.before\n                || live_permissions(&step.path)? != step.before_mode","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/sync/apply.rs#L464-L500","documentation":"After computing the complete repository merge, mise verifies that each ready step's pending object still matches what the merged tree contains at that branch path. If a divergent text merge or a stale prior resolution made the merged content differ from the planned application, the pull aborts with this error naming the changed path, so an unexpected merged version is never silently written.","triggerScenarios":"During pull, `repo.restored_object_at(tree, step.pending.branch_path) != step.pending.object` for a ready step — the complete repository merge produced different content than the per-path pending plan (divergent merge, or a resolution recorded earlier that no longer matches).","commonSituations":"Upstream changed a file after the plan's objects were computed; a previously stored conflict resolution is stale relative to the new upstream commit; both machines edited the same file and the text merge diverged from the recorded pending object.","solutions":["Re-run the pull/reconcile to regenerate the plan against the current upstream commit, then confirm the new plan.","Re-resolve the affected conflict explicitly with --take-remote or --keep-local so the stored resolution matches the current remote state.","If local edits caused the divergence, save or commit them into the sync store before pulling again."],"exampleFix":"# before: stale resolution/object in plan\nmise bootstrap dotfiles pull   # -> error naming the changed path\n# after: refresh resolution, then pull\nmise bootstrap dotfiles pull --take-remote <changed-path>\nmise bootstrap dotfiles pull","handlingStrategy":"retry","validationCode":"# refresh the stored resolution against the current upstream before pulling\nmise bootstrap dotfiles pull --take-remote <changed-path>   # or --keep-local, then full pull","typeGuard":null,"tryCatchPattern":"try {\n  await pull();\n} catch (e) {\n  const m = e.message.match(/^(.+?) changed in the complete repository merge/);\n  if (m) {\n    await pull({ takeRemote: [m[1]] }); // re-resolve the diverged path\n    return await pull();\n  }\n  throw e;\n}","preventionTips":["Pull frequently so upstream commits don't diverge from the planned objects.","Re-resolve conflicts after upstream moves rather than relying on stale stored resolutions.","Save local edits into the sync store before pulling."],"tags":["sync","merge-conflict","stale-plan","retry","dotfiles"],"backgroundTag":"checksum-mismatch","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}