#3080 Added support for cherry pick commits

This commit is contained in:
ashishj 2022-06-07 20:32:43 +02:00
parent 7a4acb5c36
commit c147404d1c
4 changed files with 155 additions and 4 deletions

View File

@ -126,12 +126,11 @@ describe('Git Graph diagram', () => {
branch branch8
branch branch9
checkout branch1
commit
commit id: "1"
`,
{}
);
});
it('9: should render a simple gitgraph with rotated labels', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
@ -160,4 +159,25 @@ describe('Git Graph diagram', () => {
{}
);
});
it('11: should render a simple gitgraph with cherry pick commit', () => {
imgSnapshotTest(
`
gitGraph
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
});

View File

@ -235,6 +235,85 @@ export const merge = function (otherBranch, tag) {
log.debug('in mergeBranch');
};
export const cherryPick = function (sourceId, targetId) {
sourceId = common.sanitizeText(sourceId, configApi.getConfig());
targetId = common.sanitizeText(targetId, configApi.getConfig());
if (!sourceId || typeof commits[sourceId] === 'undefined') {
let error = new Error(
'Incorrect usage of "cherryPick". Source commit id should exist and provided'
);
error.hash = {
text: 'cherryPick ' + sourceId + ' ' + targetId,
token: 'cherryPick ' + sourceId + ' ' + targetId,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
}
let sourceCommit = commits[sourceId];
let sourceCommitBranch = sourceCommit.branch;
if (sourceCommit.type === commitType.MERGE) {
let error = new Error(
'Incorrect usage of "cherryPick". Source commit should not be a merge commit'
);
error.hash = {
text: 'cherryPick ' + sourceId + ' ' + targetId,
token: 'cherryPick ' + sourceId + ' ' + targetId,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
}
if (!targetId || typeof commits[targetId] === 'undefined') {
// cherry-pick source commit to current branch
if (sourceCommitBranch === curBranch) {
let error = new Error(
'Incorrect usage of "cherryPick". Source commit is already on current branch'
);
error.hash = {
text: 'cherryPick ' + sourceId + ' ' + targetId,
token: 'cherryPick ' + sourceId + ' ' + targetId,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
}
const currentCommit = commits[branches[curBranch]];
if (typeof currentCommit === 'undefined' || !currentCommit) {
let error = new Error(
'Incorrect usage of "cherry-pick". Current branch (' + curBranch + ')has no commits'
);
error.hash = {
text: 'cherryPick ' + sourceId + ' ' + targetId,
token: 'cherryPick ' + sourceId + ' ' + targetId,
line: '1',
loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
expected: ['cherry-pick abc'],
};
throw error;
}
const commit = {
id: seq + '-' + getId(),
message: 'cherry-picked ' + sourceCommit + ' into ' + curBranch,
seq: seq++,
parents: [head == null ? null : head.id, sourceCommit.id],
branch: curBranch,
type: commitType.CHERRY_PICK,
tag: 'cherry-pick:' + sourceCommit.id,
};
head = commit;
commits[commit.id] = commit;
branches[curBranch] = commit.id;
log.debug(branches);
log.debug('in cheeryPick');
}
};
export const checkout = function (branch) {
branch = common.sanitizeText(branch, configApi.getConfig());
if (typeof branches[branch] === 'undefined') {
@ -390,6 +469,7 @@ export const commitType = {
REVERSE: 1,
HIGHLIGHT: 2,
MERGE: 3,
CHERRY_PICK: 4,
};
export default {
@ -401,6 +481,7 @@ export default {
commit,
branch,
merge,
cherryPick,
checkout,
//reset,
prettyPrint,

View File

@ -14,6 +14,7 @@ const commitType = {
REVERSE: 1,
HIGHLIGHT: 2,
MERGE: 3,
CHERRY_PICK: 4,
};
let branchPos = {};
@ -103,6 +104,9 @@ const drawCommits = (svg, commits, modifyGraph) => {
case commitType.MERGE:
typeClass = 'commit-merge';
break;
case commitType.CHERRY_PICK:
typeClass = 'commit-cherry-pick';
break;
default:
typeClass = 'commit-normal';
}
@ -139,6 +143,43 @@ const drawCommits = (svg, commits, modifyGraph) => {
typeClass +
'-inner'
);
} else if (commit.type === commitType.CHERRY_PICK) {
gBullets
.append('circle')
.attr('cx', x)
.attr('cy', y)
.attr('r', 10)
.attr('class', 'commit ' + commit.id + ' ' + typeClass);
gBullets
.append('circle')
.attr('cx', x - 3)
.attr('cy', y + 2)
.attr('r', 2.75)
.attr('fill', '#fff')
.attr('class', 'commit ' + commit.id + ' ' + typeClass);
gBullets
.append('circle')
.attr('cx', x + 3)
.attr('cy', y + 2)
.attr('r', 2.75)
.attr('fill', '#fff')
.attr('class', 'commit ' + commit.id + ' ' + typeClass);
gBullets
.append('line')
.attr('x1', x + 3)
.attr('y1', y + 1)
.attr('x2', x)
.attr('y2', y - 5)
.attr('stroke', '#fff')
.attr('class', 'commit ' + commit.id + ' ' + typeClass);
gBullets
.append('line')
.attr('x1', x - 3)
.attr('y1', y + 1)
.attr('x2', x)
.attr('y2', y - 5)
.attr('stroke', '#fff')
.attr('class', 'commit ' + commit.id + ' ' + typeClass);
} else {
const circle = gBullets.append('circle');
circle.attr('cx', x);
@ -175,7 +216,11 @@ const drawCommits = (svg, commits, modifyGraph) => {
const px = 4;
const py = 2;
// Draw the commit label
if (commit.type !== commitType.MERGE && gitGraphConfig.showCommitLabel) {
if (
commit.type !== commitType.CHERRY_PICK &&
commit.type !== commitType.MERGE &&
gitGraphConfig.showCommitLabel
) {
const wrapper = gLabels.append('g');
const labelBkg = wrapper.insert('rect').attr('class', 'commit-label-bkg');
@ -197,7 +242,6 @@ const drawCommits = (svg, commits, modifyGraph) => {
if (gitGraphConfig.rotateCommitLabel) {
let r_x = -7.5 - ((bbox.width + 10) / 25) * 9.5;
let r_y = 10 + (bbox.width / 25) * 8.5;
//wrapper.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + bbox.width / 2 + ') ');
wrapper.attr(
'transform',
'translate(' + r_x + ', ' + r_y + ') rotate(' + -45 + ', ' + pos + ', ' + y + ')'

View File

@ -48,6 +48,7 @@ accDescr\s*"{"\s* { this.begin("ac
"branch" return 'BRANCH';
"order:" return 'ORDER';
"merge" return 'MERGE';
"cherry-pick" return 'CHERRY_PICK';
// "reset" return 'RESET';
"checkout" return 'CHECKOUT';
"LR" return 'DIR';
@ -102,6 +103,7 @@ line
statement
: commitStatement
| mergeStatement
| cherryPickStatement
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| 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);}
@ -114,6 +116,10 @@ branchStatement
| BRANCH ID ORDER NUM {yy.branch($2, $4)}
;
cherryPickStatement
: CHERRY_PICK COMMIT_ID STR {yy.cherryPick($3)}
;
mergeStatement
: MERGE ID {yy.merge($2)}
| MERGE ID COMMIT_TAG STR {yy.merge($2, $4)}