From b9f8e191628693b94c0fa4ee96b32442ea6c6878 Mon Sep 17 00:00:00 2001 From: David Nelson Date: Thu, 18 Apr 2019 20:57:29 -0500 Subject: [PATCH] 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. --- __tests__/git.spec.js | 24 ++++++++++++++++++ src/js/git/commands.js | 15 ++--------- src/js/git/index.js | 47 +++++++++++------------------------ src/js/models/commandModel.js | 14 ++++++----- 4 files changed, 49 insertions(+), 51 deletions(-) diff --git a/__tests__/git.spec.js b/__tests__/git.spec.js index 73c46a82..fd10ad41 100644 --- a/__tests__/git.spec.js +++ b/__tests__/git.spec.js @@ -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'); + }); + }); }); }); diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 83e21e80..50e93d5a 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -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); } }, diff --git a/src/js/git/index.js b/src/js/git/index.js index ff811f8e..c0c64024 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -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; diff --git a/src/js/models/commandModel.js b/src/js/models/commandModel.js index 76e94d61..138f9024 100644 --- a/src/js/models/commandModel.js +++ b/src/js/models/commandModel.js @@ -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) ?