{"record":{"id":"8c7d6ce31d533b74","repo":"jdx/mise","slug":"cannot-determine-dotfile-git-ancestry","errorCode":null,"errorMessage":"cannot determine dotfile Git ancestry: {}","messagePattern":"cannot determine dotfile Git ancestry: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/shadow.rs","lineNumber":1267,"sourceCode":"    /// Deletes a ref if it exists.\n    pub(crate) fn delete_ref(&self, name: &str) -> Result<()> {\n        if self.ref_oid(name)?.is_some() {\n            self.git\n                .run(PlumbingCall::new([\"update-ref\", \"-d\", name]))?;\n        }\n        Ok(())\n    }\n\n    /// Find all common ancestors without treating Git failures as absence.\n    pub(crate) fn merge_bases(&self, local: &str, remote: &str) -> Result<Vec<String>> {\n        let output =\n            self.git\n                .output_unchecked(PlumbingCall::new([\"merge-base\", \"--all\", local, remote]))?;\n        if output.status.code() == Some(1) {\n            return Ok(vec![]);\n        }\n        if !output.status.success() {\n            bail!(\n                \"cannot determine dotfile Git ancestry: {}\",\n                String::from_utf8_lossy(&output.stderr).trim()\n            );\n        }\n        let text = String::from_utf8(output.stdout)?;\n        Ok(text.lines().map(str::to_owned).collect())\n    }\n\n    /// Merge complete ordinary trees using Git's recursive merge-base handling.\n    /// Conflict trees are never adopted or written into live configuration.\n    pub(crate) fn merge_tree(&self, local: &str, remote: &str) -> Result<(String, Vec<String>)> {\n        let output = self.git.output_unchecked(PlumbingCall::new([\n            \"merge-tree\",\n            \"--write-tree\",\n            \"--name-only\",\n            \"--no-messages\",\n            \"-z\",\n            local,","sourceCodeStart":1249,"sourceCodeEnd":1285,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/history/shadow.rs#L1249-L1285","documentation":"This fires when `git merge-base --all <local> <remote>` exits with a status other than the expected 0 (ancestors found) or 1 (no common ancestor). Since the command cannot determine whether the two dotfile history tips share ancestry, the operation aborts and surfaces git's stderr. It guards the merge/rebase logic that relies on knowing the common history.","triggerScenarios":"Calling the ancestry check when the `merge-base --all` plumbing call fails for reasons other than 'no common ancestor' — e.g. one of the refs does not exist, the repository is corrupt, or git itself is broken.","commonSituations":"A dotfile shadow repo whose branch was force-deleted or garbage-collected while a local ref still points at it; a hand-edited or corrupted .git directory; running with a broken or partial git installation.","solutions":["Run `git merge-base --all <local> <remote>` inside the shadow repo yourself and read the stderr echoed in the error.","Check that both refs/commits exist: `git rev-parse <local> <remote>`.","If refs are dangling after a force-push or GC, re-sync the dotfile history (`mise dot` pull/push) to rebuild the shared base.","As a last resort, `git fsck` the shadow repository and restore it from a fresh clone or backup."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"for r in [&local, &remote] {\n    if !repo_rev_parse_ok(r) { eprintln!(\"ref {r} missing from shadow repo\"); }\n}","typeGuard":null,"tryCatchPattern":"match history.common_ancestors(local, remote) {\n    Ok(ans) => merge_with(ans),\n    Err(e) if e.to_string().contains(\"cannot determine dotfile Git ancestry\") => {\n        eprintln!(\"shadow repo inconsistent; re-syncing history\");\n        resync_history()?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Don't manually reset or GC the dotfile shadow repo","Run `git fsck` after machine restores or disk-full events","Re-sync history after force-pushes instead of merging across rewrites"],"tags":["git","dotfiles","merge-base","plumbing"],"backgroundTag":"git-command-failed","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"}