{"record":{"id":"9f2c438cc3742123","repo":"pcottle/learnGitBranching","slug":"git-error-relative-ref","errorCode":null,"errorMessage":"git-error-relative-ref","messagePattern":"git-error-relative-ref","errorType":"validation","errorClass":"GitError","httpStatus":null,"severity":"error","filePath":"src/js/git/index.js","lineNumber":1778,"sourceCode":"\n  while (matches = regex.exec(relative)) {\n    var next = commit;\n    var num = matches[2] ? parseInt(matches[2], 10) : 1;\n\n    if (matches[1] == '^') {\n      next = commit.getParent(num-1);\n    } else {\n      while (next && num--) {\n        next = next.getParent(0);\n      }\n    }\n\n    if (!next) {\n      var msg = intl.str('git-error-relative-ref', {\n        commit: commit.id,\n        match: matches[0]\n      });\n      throw new GitError({\n        msg: msg\n      });\n    }\n\n    commit = next;\n  }\n\n  return commit;\n};\n\nGitEngine.prototype.doesRefExist = function(ref) {\n  return !!this.refs[ref]\n};\n\nGitEngine.prototype.resolveStringRef = function(ref) {\n  ref = this.crappyUnescape(ref);\n\n  if (this.refs[ref]) {","sourceCodeStart":1760,"sourceCodeEnd":1796,"githubUrl":"https://github.com/pcottle/learnGitBranching/blob/5b09d0ff9678cad164f5a7488a279a44f90d7256/src/js/git/index.js#L1760-L1796","documentation":"Relative ref resolution failed: a suffix like ~2 or ^1 walked off the graph — the requested parent/ancestor does not exist for the given commit. Matches git's 'unknown revision or path not in the working tree' for over-long ancestry chains.","triggerScenarios":"Calling the ref resolver with something like 'HEAD~5' or 'main^2' where following the ~/^ chain yields a falsy next commit (too few ancestors, or ^N on a commit with fewer parents).","commonSituations":"Counting commits wrong in a level solution (main~9 when only 3 exist); using ^2 on a non-merge commit; walking past the root commit.","solutions":["Count actual ancestors and shorten the chain (use git log / the visualization)","Use ^ only up to the commit's parent count (merges have 2)","Resolve the intermediate ref first to verify it exists"],"exampleFix":"// before\ngit checkout main~7 // only 3 commits\n// after\ngit checkout main~3","handlingStrategy":"validation","validationCode":"// verify each hop exists before resolving\nvar c = engine.getCommitFromRef(baseName);\nvar steps = relative.match(/[~^]\\d*/g) || [];\nsteps.forEach(function(s){\n  c = s[0] === '~' ? engine.getCommitFromRef(c.id+'~'+(s.slice(1)||1))\n                    : c.get('parents')[parseInt(s.slice(1)||1,10)-1];\n  if (!c) throw new Error('chain too long');\n});","typeGuard":"function refChainResolves(engine, ref) {\n  try { engine.resolveID(ref); return true; } catch (e) { return false; }\n}","tryCatchPattern":"try { engine.resolveID(ref); } catch (e) { if (e instanceof GitError) showUsageHint(); else throw e; }","preventionTips":["Count ancestors with log/visualization before using ~N","Never use ^2 on non-merge commits"],"tags":["git","ref","relative-ref","ancestry"],"backgroundTag":"git-invalid-revision-range","analyzedSha":"5b09d0ff9678cad164f5a7488a279a44f90d7256","analyzedAt":"2026-08-27T13:53:49.057Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}