mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-26 16:08:34 +02:00
Improve parsing of relative references
Support parsing of references like HEAD~^2~3^ . Previously, ~ required a following number, ^ didn't allow a following number, and chaining wasn't supported. If at any point in the resolving of the chain the requested parent isn't found report the error by specifying the id of the last commit that was found along with the parent specification to help the user to figure out where the problem arose.
This commit is contained in:
parent
4928e71a4b
commit
e5de32f977
1 changed files with 45 additions and 23 deletions
|
@ -621,6 +621,36 @@ GitEngine.prototype.resolveID = function(idOrTarget) {
|
|||
return this.resolveStringRef(idOrTarget);
|
||||
};
|
||||
|
||||
GitEngine.prototype.resolveRelativeRef = function(commit, relative) {
|
||||
var regex = /([~^])(\d*)/g;
|
||||
var matches;
|
||||
|
||||
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 = "Commit " + commit.id + " doesn't have a " + matches[0];
|
||||
throw new GitError({
|
||||
msg: msg
|
||||
});
|
||||
}
|
||||
|
||||
commit = next;
|
||||
}
|
||||
|
||||
return commit;
|
||||
};
|
||||
|
||||
GitEngine.prototype.resolveStringRef = function(ref) {
|
||||
if (this.refs[ref]) {
|
||||
return this.refs[ref];
|
||||
|
@ -630,33 +660,21 @@ GitEngine.prototype.resolveStringRef = function(ref) {
|
|||
return this.refs[ref.toUpperCase()];
|
||||
}
|
||||
|
||||
// may be something like HEAD~2 or master^^
|
||||
var relativeRefs = [
|
||||
[/^([a-zA-Z0-9]+)~(\d+)\s*$/, function(matches) {
|
||||
return parseInt(matches[2], 10);
|
||||
}],
|
||||
[/^([a-zA-Z0-9]+)(\^+)\s*$/, function(matches) {
|
||||
return matches[2].length;
|
||||
}]
|
||||
];
|
||||
|
||||
// Attempt to split ref string into a reference and a string of ~ and ^ modifiers.
|
||||
var startRef = null;
|
||||
var numBack = null;
|
||||
_.each(relativeRefs, function(config) {
|
||||
var regex = config[0];
|
||||
var parse = config[1];
|
||||
if (regex.test(ref)) {
|
||||
var matches = regex.exec(ref);
|
||||
numBack = parse(matches);
|
||||
startRef = matches[1];
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (!startRef) {
|
||||
var relative = null;
|
||||
var regex = /^([a-zA-Z0-9]+)(([~^]\d*)*)/;
|
||||
var matches = regex.exec(ref);
|
||||
if (matches) {
|
||||
startRef = matches[1];
|
||||
relative = matches[2];
|
||||
}
|
||||
else {
|
||||
throw new GitError({
|
||||
msg: 'unknown ref ' + ref
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.refs[startRef]) {
|
||||
throw new GitError({
|
||||
msg: 'the ref ' + startRef +' does not exist.'
|
||||
|
@ -664,7 +682,11 @@ GitEngine.prototype.resolveStringRef = function(ref) {
|
|||
}
|
||||
var commit = this.getCommitFromRef(startRef);
|
||||
|
||||
return this.numBackFrom(commit, numBack);
|
||||
if (relative) {
|
||||
commit = this.resolveRelativeRef( commit, relative );
|
||||
}
|
||||
|
||||
return commit;
|
||||
};
|
||||
|
||||
GitEngine.prototype.getCommitFromRef = function(ref) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue