diff --git a/src/diagrams/git/gitGraphAst.js b/src/diagrams/git/gitGraphAst.js index b41da81348..44a36589cf 100644 --- a/src/diagrams/git/gitGraphAst.js +++ b/src/diagrams/git/gitGraphAst.js @@ -15,6 +15,8 @@ import { let mainBranchName = getConfig().gitGraph.mainBranchName; let commits = {}; let head = null; +let branchesConfig = {}; +branchesConfig[mainBranchName] = { name: mainBranchName, order: 0 }; let branches = {}; branches[mainBranchName] = head; let curBranch = mainBranchName; @@ -123,10 +125,11 @@ export const commit = function (msg, id, type, tag) { log.debug('in pushCommit ' + commit.id); }; -export const branch = function (name) { +export const branch = function (name, order) { name = common.sanitizeText(name, configApi.getConfig()); if (typeof branches[name] === 'undefined') { branches[name] = head != null ? head.id : null; + branchesConfig[name] = { name, order: order ? parseInt(order, 10) : null }; checkout(name); log.debug('in createBranch'); } else { @@ -334,18 +337,26 @@ export const clear = function () { let mainBranch = getConfig().gitGraph.mainBranchName; branches = {}; branches[mainBranch] = null; + branchesConfig = {}; + branchesConfig[mainBranch] = { name: mainBranch, order: 0 }; curBranch = mainBranch; seq = 0; commonClear(); }; export const getBranchesAsObjArray = function () { - const branchArr = []; - for (let branch in branches) { - // branchArr.push({ name: branch, commit: commits[branches[branch]] }); - branchArr.push({ name: branch }); - } - return branchArr; + const branchesArray = Object.values(branchesConfig) + .map((branchConfig, i) => { + if (branchConfig.order !== null) return branchConfig; + return { + ...branchConfig, + order: parseFloat(`0.${i}`, 10), + }; + }) + .sort((a, b) => a.order - b.order) + .map(({ name }) => ({ name })); + + return branchesArray; }; export const getBranches = function () { diff --git a/src/diagrams/git/gitGraphParserV2.spec.js b/src/diagrams/git/gitGraphParserV2.spec.js index 9d740d5aeb..ecbba2a66a 100644 --- a/src/diagrams/git/gitGraphParserV2.spec.js +++ b/src/diagrams/git/gitGraphParserV2.spec.js @@ -364,6 +364,46 @@ describe('when parsing a gitGraph', function () { expect(parser.yy.getDirection()).toBe('LR'); expect(Object.keys(parser.yy.getBranches()).length).toBe(2); }); + it('should handle new branch checkout with order', function () { + const str = `gitGraph: + commit + branch test1 order: 3 + branch test2 order: 2 + branch test3 order: 1 + `; + + parser.parse(str); + const commits = parser.yy.getCommits(); + expect(Object.keys(commits).length).toBe(1); + expect(parser.yy.getCurrentBranch()).toBe('test3'); + expect(Object.keys(parser.yy.getBranches()).length).toBe(4); + expect(parser.yy.getBranchesAsObjArray()).toStrictEqual([ + { name: 'main' }, + { name: 'test3' }, + { name: 'test2' }, + { name: 'test1' }, + ]); + }); + it('should handle new branch checkout with and without order', function () { + const str = `gitGraph: + commit + branch test1 order: 1 + branch test2 + branch test3 + `; + + parser.parse(str); + const commits = parser.yy.getCommits(); + expect(Object.keys(commits).length).toBe(1); + expect(parser.yy.getCurrentBranch()).toBe('test3'); + expect(Object.keys(parser.yy.getBranches()).length).toBe(4); + expect(parser.yy.getBranchesAsObjArray()).toStrictEqual([ + { name: 'main' }, + { name: 'test2' }, + { name: 'test3' }, + { name: 'test1' }, + ]); + }); it('should handle new branch checkout & commit', function () { const str = `gitGraph: diff --git a/src/diagrams/git/parser/gitGraph.jison b/src/diagrams/git/parser/gitGraph.jison index bb2ff9ae67..7d524f3737 100644 --- a/src/diagrams/git/parser/gitGraph.jison +++ b/src/diagrams/git/parser/gitGraph.jison @@ -46,6 +46,7 @@ accDescr\s*"{"\s* { this.begin("ac "HIGHLIGHT" return 'HIGHLIGHT'; "tag:" return 'COMMIT_TAG'; "branch" return 'BRANCH'; +"order:" return 'ORDER'; "merge" return 'MERGE'; // "reset" return 'RESET'; "checkout" return 'CHECKOUT'; @@ -59,6 +60,7 @@ accDescr\s*"{"\s* { this.begin("ac ["] this.begin("string"); ["] this.popState(); [^"]* return 'STR'; +[0-9]+ return 'NUM'; [a-zA-Z][-_\./a-zA-Z0-9]*[-_a-zA-Z0-9] return 'ID'; <> return 'EOF'; @@ -103,10 +105,14 @@ statement | acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);} - | BRANCH ID {yy.branch($2)} + | branchStatement | CHECKOUT ID {yy.checkout($2)} // | RESET reset_arg {yy.reset($2)} ; +branchStatement + : BRANCH ID {yy.branch($2)} + | BRANCH ID ORDER NUM {yy.branch($2, $4)} + ; mergeStatement : MERGE ID {yy.merge($2)}