{"record":{"id":"b01be4ac544a5e8a","repo":"jdx/mise","slug":"global-configuration-at-shown-cannot-be-fast-for","errorCode":null,"errorMessage":"global configuration at {shown} cannot be fast-forwarded to the transferred revision","messagePattern":"global configuration at (.+?) cannot be fast-forwarded to the transferred revision","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote_repository.rs","lineNumber":276,"sourceCode":"        }\n        if update {\n            if git(destination, &[\"symbolic-ref\", \"--short\", \"HEAD\"])? != branch {\n                bail!(\"global configuration branch differs from the transferred branch\");\n            }\n            if dry_run {\n                // the bundle holds the history from the checkout's commit on,\n                // so the fast-forward is checked there without fetching into\n                // the destination\n                let head = git(destination, &[\"rev-parse\", \"HEAD\"])?;\n                if head == revision {\n                    miseprintln!(\n                        \"Would keep {shown} at {revision}, already the transferred revision\"\n                    );\n                } else if git(&checkout, &[\"merge-base\", \"--is-ancestor\", &head, revision]).is_ok()\n                {\n                    miseprintln!(\"Would fast-forward {shown} from {head} to {revision}\");\n                } else {\n                    bail!(\n                        \"global configuration at {shown} cannot be fast-forwarded to the transferred revision\"\n                    );\n                }\n                return Ok(destination.to_path_buf());\n            }\n            git(\n                destination,\n                &[\n                    \"fetch\",\n                    \"--no-tags\",\n                    bundle\n                        .to_str()\n                        .ok_or_else(|| eyre::eyre!(\"invalid bundle path\"))?,\n                    \"HEAD\",\n                ],\n            )?;\n            git(\n                destination,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/remote_repository.rs#L258-L294","documentation":"During a dry-run `--update`, install_at checks whether the destination's current HEAD is an ancestor of the transferred revision (`git merge-base --is-ancestor`). If HEAD has diverged — containing commits the transferred revision does not have — a fast-forward is impossible and the tool aborts rather than performing a merge or rebase. Only strictly-behind or identical states are updatable.","triggerScenarios":"Running `--update` (dry-run) where the destination checkout has local commits not present in the transferred revision, e.g. the bundle was created from a different, older, or diverged clone of the same origin.","commonSituations":"User committed directly in the destination config repo and never pushed; the transfer source was cloned from a stale state; history was rewritten (rebase/amend) on either side making the histories diverge.","solutions":["Push/commit the destination's local commits to the source repository and regenerate the transfer bundle so it contains them.","Discard divergent local commits if unwanted: `git -C <destination> reset --hard origin/<branch>` (verify first with `git log`).","Rebase local commits onto the transferred revision manually, then retry so histories are linear again.","If histories were rewritten intentionally, reset the destination to the transferred revision (after backing up local work)."],"exampleFix":"// before: destination has local commit not in transferred revision\ngit -C ~/.config/mise log --oneline origin/main..HEAD   # abc123 local change\n# push it into the source repo, regenerate the bundle, then retry\n// after: HEAD is an ancestor of the transferred revision; dry-run reports a fast-forward","handlingStrategy":"validation","validationCode":"const head = execFileSync('git', ['-C', dest, 'rev-parse', 'HEAD']).toString().trim();\n// ancestor check must run against the transferred revision; approximate by checking local-only commits\nconst ahead = execFileSync('git', ['-C', dest, 'log', '--oneline', `origin/${branch}..HEAD`]).toString();\nif (ahead.trim().length > 0) throw new Error('destination has commits not in the transferred revision');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always push local config changes to the shared origin before generating transfer bundles.","Never commit directly in the destination checkout; edit in the source repo.","Avoid history rewrites (rebase/amend) on the config repo's shared branch."],"tags":["git","fast-forward","diverged-history"],"backgroundTag":"invalid-state-transition","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}