pcottle/learnGitBranching · error · GitError
git-error-relative-ref
Error message
git-error-relative-ref
What it means
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.
Source
Thrown at src/js/git/index.js:1778
while (matches = regex.exec(relative)) {
var next = commit;
var num = matches[2] ? parseInt(matches[2], 10) : 1;
if (matches[1] == '^') {
next = commit.getParent(num-1);
} else {
while (next && num--) {
next = next.getParent(0);
}
}
if (!next) {
var msg = intl.str('git-error-relative-ref', {
commit: commit.id,
match: matches[0]
});
throw new GitError({
msg: msg
});
}
commit = next;
}
return commit;
};
GitEngine.prototype.doesRefExist = function(ref) {
return !!this.refs[ref]
};
GitEngine.prototype.resolveStringRef = function(ref) {
ref = this.crappyUnescape(ref);
if (this.refs[ref]) {View on GitHub (pinned to 5b09d0ff96)
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
Example fix
// before git checkout main~7 // only 3 commits // after git checkout main~3
Defensive patterns
Strategy: validation
Validate before calling
// verify each hop exists before resolving
var c = engine.getCommitFromRef(baseName);
var steps = relative.match(/[~^]\d*/g) || [];
steps.forEach(function(s){
c = s[0] === '~' ? engine.getCommitFromRef(c.id+'~'+(s.slice(1)||1))
: c.get('parents')[parseInt(s.slice(1)||1,10)-1];
if (!c) throw new Error('chain too long');
}); Type guard
function refChainResolves(engine, ref) {
try { engine.resolveID(ref); return true; } catch (e) { return false; }
} Try / catch
try { engine.resolveID(ref); } catch (e) { if (e instanceof GitError) showUsageHint(); else throw e; } Prevention
- Count ancestors with log/visualization before using ~N
- Never use ^2 on non-merge commits
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- git-error-already-exists
- git-error-exist
- Fatal: no tags found upstream
- git-error-exist
- cannot fetch to ' + ref + ' when checked out on ' + ref
AI-assisted analysis of pcottle/learnGitBranching@5b09d0ff96 (2026-08-27).
Data as JSON: /api/errors/9f2c438cc3742123.
Report an issue: GitHub.