{"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":1518,"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":1500,"sourceCodeEnd":1536,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/shadow.rs#L1500-L1536","documentation":"mise failed to run `git merge-base --all` while determining whether two dotfile history refs share ancestry. Exit code 1 means no common ancestor and is handled normally, but any other failure (corrupt repo, bad ref, git error) triggers this error carrying git's stderr. It guards the shadow history repo used to record dotfile state.","triggerScenarios":"Calling the dotfile history merge/ancestry check when the shadow git repository is corrupted, the local/remote ref names are invalid, or git itself fails (e.g. broken .git directory, packed-refs corruption, disk full).","commonSituations":"A dotfile history repo damaged by an interrupted sync or manual `git` fiddling inside the state directory; a remote ref deleted upstream so the plumbing call gets an unusable ref; running on a filesystem where git operations fail.","solutions":["Read the stderr text in the message to identify the underlying git failure.","Run `git fsck` (or inspect the repo at mise's history/state dir) to repair or confirm corruption.","If the repo is corrupt and history is dispensable, re-initialize the dotfile history repo or remove it so mise recreates it.","Verify the local and remote ref names still exist: `git rev-parse --verify <ref>` inside the history repo."],"exampleFix":"// before: shadow history repo has a broken ref\n$ mise dotfiles pull\nError: cannot determine dotfile Git ancestry: fatal: bad object HEAD\n\n// after: re-initialize the history repo\n$ rm -rf ~/.local/share/mise/dotfiles-history && mise dotfiles pull","handlingStrategy":"try-catch","validationCode":"// verify the refs resolve before invoking the ancestry check\nfor ref in [local, remote] {\n  let ok = git([\"rev-parse\", \"--verify\", \"--quiet\", ref]).is_ok();\n  if !ok { println!(\"ref {ref} missing from history repo\"); }\n}","typeGuard":"fn refs_resolvable(local: &str, remote: &str) -> bool {\n  git_ok([\"rev-parse\", \"--verify\", \"--quiet\", local])\n    && git_ok([\"rev-parse\", \"--verify\", \"--quiet\", remote])\n}","tryCatchPattern":"match result {\n  Err(e) if e.to_string().contains(\"cannot determine dotfile Git ancestry\") => {\n    // inspect/repair the shadow history repo or re-init it\n  }\n  other => other?,\n}","preventionTips":["Do not manually run git commands inside mise's dotfile history repo.","Run `git fsck` periodically on long-lived history repos.","Keep git updated to a supported version."],"tags":["git","dotfiles","history-repo","corruption"],"backgroundTag":"git-command-failed","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}