Implement log using RevisionRange

This changes the implementation of the "log" command to use the RevisionRange
functionality. RevisionRange sorts the results in order of reverse create time,
to match real git. This is a change from the previous implementation of log,
which essentially produced a breadth-first ordering.
This commit is contained in:
David Nelson 2019-04-18 20:57:29 -05:00
parent 8529a3aac7
commit b9f8e19162
4 changed files with 49 additions and 51 deletions

View file

@ -351,5 +351,29 @@ describe('Git', function() {
expect(commandMsg).toContain('Commit: C6\n');
});
});
it('multiple included revisions', function() {
runCommand(SETUP + 'git log right left', function(commandMsg) {
expect(commandMsg).toContain('Commit: C0\n');
expect(commandMsg).toContain('Commit: C1\n');
expect(commandMsg).toContain('Commit: C2\n');
expect(commandMsg).toContain('Commit: C3\n');
expect(commandMsg).toContain('Commit: C4\n');
expect(commandMsg).toContain('Commit: C5\n');
expect(commandMsg).not.toContain('Commit: C6\n');
});
});
it('multiple excluded revisions', function() {
runCommand(SETUP + 'git log all ^right ^left', function(commandMsg) {
expect(commandMsg).not.toContain('Commit: C0\n');
expect(commandMsg).not.toContain('Commit: C1\n');
expect(commandMsg).not.toContain('Commit: C2\n');
expect(commandMsg).not.toContain('Commit: C3\n');
expect(commandMsg).not.toContain('Commit: C4\n');
expect(commandMsg).not.toContain('Commit: C5\n');
expect(commandMsg).toContain('Commit: C6\n');
});
});
});
});

View file

@ -592,19 +592,8 @@ var commandConfig = {
execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
if (generalArgs.length == 2) {
// do fancy git log branchA ^branchB
if (generalArgs[1][0] == '^') {
engine.logWithout(generalArgs[0], generalArgs[1]);
} else {
throw new GitError({
msg: intl.str('git-error-options')
});
}
}
command.oneArgImpliedHead(generalArgs);
engine.log(generalArgs[0]);
command.impliedHead(generalArgs, 0);
engine.log(generalArgs);
}
},

View file

@ -2744,9 +2744,8 @@ GitEngine.prototype.revlist = function(refs) {
var range = new RevisionRange(this, refs);
// now go through and collect ids
var bigLogStr = '';
range.revisions.forEach(function(c) {
bigLogStr += c.id + '\n';
var bigLogStr = range.formatRevisions(function(c) {
return c.id + '\n';
});
throw new CommandResult({
@ -2754,37 +2753,13 @@ GitEngine.prototype.revlist = function(refs) {
});
};
GitEngine.prototype.log = function(ref, omitSet) {
// omit set is for doing stuff like git log branchA ^branchB
omitSet = omitSet || {};
// first get the commit we referenced
var commit = this.getCommitFromRef(ref);
// then get as many far back as we can from here, order by commit date
var toDump = [];
var pQueue = [commit];
var seen = {};
while (pQueue.length) {
var popped = pQueue.shift(0);
if (seen[popped.get('id')] || omitSet[popped.get('id')]) {
continue;
}
seen[popped.get('id')] = true;
toDump.push(popped);
if (popped.get('parents') && popped.get('parents').length) {
pQueue = pQueue.concat(popped.get('parents'));
}
}
GitEngine.prototype.log = function(refs) {
var range = new RevisionRange(this, refs);
// now go through and collect logs
var bigLogStr = '';
toDump.forEach(function (c) {
bigLogStr += c.getLogEntry();
}, this);
var bigLogStr = range.formatRevisions(function(c) {
return c.getLogEntry();
});
throw new CommandResult({
msg: bigLogStr
@ -3158,6 +3133,14 @@ RevisionRange.prototype.addIncluded = function(setToInclude) {
});
};
RevisionRange.prototype.formatRevisions = function(revisionFormatter) {
var output = "";
this.revisions.forEach(function(c) {
output += revisionFormatter(c);
});
return output;
};
exports.GitEngine = GitEngine;
exports.Commit = Commit;
exports.Branch = Branch;

View file

@ -126,18 +126,14 @@ var Command = Backbone.Model.extend({
oneArgImpliedHead: function(args, option) {
this.validateArgBounds(args, 0, 1, option);
// and if it's one, add a HEAD to the back
if (args.length === 0) {
args.push('HEAD');
}
this.impliedHead(args, 0);
},
twoArgsImpliedHead: function(args, option) {
// our args we expect to be between 1 and 2
this.validateArgBounds(args, 1, 2, option);
// and if it's one, add a HEAD to the back
if (args.length == 1) {
args.push('HEAD');
}
this.impliedHead(args, 1);
},
oneArgImpliedOrigin: function(args) {
@ -151,6 +147,12 @@ var Command = Backbone.Model.extend({
this.validateArgBounds(args, 0, 2);
},
impliedHead: function(args, min) {
if(args.length == min) {
args.push('HEAD');
}
},
// this is a little utility class to help arg validation that happens over and over again
validateArgBounds: function(args, lower, upper, option) {
var what = (option === undefined) ?