Skip to content

Commit 2430e50

Browse files
committed
#12 Revert, cherry-pick & merge git commands available from context menus
1 parent 50d3ef8 commit 2430e50

File tree

4 files changed

+136
-15
lines changed

4 files changed

+136
-15
lines changed

src/dataSource.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,18 @@ export class DataSource {
201201
return this.runGitCommand('git branch -m ' + escapeRefName(oldName) + ' ' + escapeRefName(newName));
202202
}
203203

204+
public mergeBranch(branchName: string){
205+
return this.runGitCommand('git merge ' + escapeRefName(branchName));
206+
}
207+
208+
public cherrypickCommit(commitHash: string, parentIndex: number) {
209+
return this.runGitCommand('git cherry-pick ' + commitHash + (parentIndex > 0 ? ' -m ' + parentIndex : ''));
210+
}
211+
212+
public revertCommit(commitHash: string, parentIndex: number) {
213+
return this.runGitCommand('git revert --no-edit ' + commitHash + (parentIndex > 0 ? ' -m ' + parentIndex : ''));
214+
}
215+
204216
public resetToCommit(commitHash: string, resetMode: GitResetMode) {
205217
return this.runGitCommand('git reset --' + resetMode + ' ' + commitHash);
206218
}

src/gitGraphView.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ export class GitGraphView {
6060
status: await this.dataSource.checkoutBranch(msg.branchName, msg.remoteBranch)
6161
});
6262
return;
63+
case 'cherrypickCommit':
64+
this.sendMessage({
65+
command: 'cherrypickCommit',
66+
status: await this.dataSource.cherrypickCommit(msg.commitHash, msg.parentIndex)
67+
});
68+
return;
6369
case 'commitDetails':
6470
this.sendMessage({
6571
command: 'commitDetails',
@@ -99,6 +105,12 @@ export class GitGraphView {
99105
... await this.dataSource.getCommits(msg.branchName, msg.maxCommits, msg.showRemoteBranches, msg.currentBranch)
100106
});
101107
return;
108+
case 'mergeBranch':
109+
this.sendMessage({
110+
command: 'mergeBranch',
111+
status: await this.dataSource.mergeBranch(msg.branchName)
112+
});
113+
return;
102114
case 'renameBranch':
103115
this.sendMessage({
104116
command: 'renameBranch',
@@ -111,6 +123,12 @@ export class GitGraphView {
111123
status: await this.dataSource.resetToCommit(msg.commitHash, msg.resetMode)
112124
});
113125
return;
126+
case 'revertCommit':
127+
this.sendMessage({
128+
command: 'revertCommit',
129+
status: await this.dataSource.revertCommit(msg.commitHash, msg.parentIndex)
130+
});
131+
return;
114132
case 'viewDiff':
115133
this.viewDiff(msg.commitHash, msg.oldFilePath, msg.newFilePath, msg.type);
116134
return;

src/types.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ export interface ResponseCheckoutBranch {
8989
status: GitCommandStatus;
9090
}
9191

92+
export interface RequestCherrypickCommit {
93+
command: 'cherrypickCommit';
94+
commitHash: string;
95+
parentIndex: number;
96+
}
97+
export interface ResponseCherrypickCommit {
98+
command: 'cherrypickCommit';
99+
status: GitCommandStatus;
100+
}
101+
92102
export interface RequestCommitDetails {
93103
command: 'commitDetails';
94104
commitHash: string;
@@ -158,6 +168,15 @@ export interface ResponseLoadCommits {
158168
moreCommitsAvailable: boolean;
159169
}
160170

171+
export interface RequestMergeBranch {
172+
command: 'mergeBranch';
173+
branchName: string;
174+
}
175+
export interface ResponseMergeBranch {
176+
command: 'mergeBranch';
177+
status: GitCommandStatus;
178+
}
179+
161180
export interface RequestRenameBranch {
162181
command: 'renameBranch';
163182
oldName: string;
@@ -178,6 +197,16 @@ export interface ResponseResetToCommit {
178197
status: GitCommandStatus;
179198
}
180199

200+
export interface RequestRevertCommit {
201+
command: 'revertCommit';
202+
commitHash: string;
203+
parentIndex: number;
204+
}
205+
export interface ResponseRevertCommit {
206+
command: 'revertCommit';
207+
status: GitCommandStatus;
208+
}
209+
181210
export interface RequestViewDiff {
182211
command: 'viewDiff';
183212
commitHash: string;
@@ -193,27 +222,33 @@ export interface ResponseViewDiff {
193222
export type RequestMessage =
194223
RequestAddTag
195224
| RequestCheckoutBranch
225+
| RequestCherrypickCommit
196226
| RequestCommitDetails
197227
| RequestCopyCommitHashToClipboard
198228
| RequestCreateBranch
199229
| RequestDeleteBranch
200230
| RequestDeleteTag
201231
| RequestLoadBranches
202232
| RequestLoadCommits
233+
| RequestMergeBranch
203234
| RequestRenameBranch
204235
| RequestResetToCommit
236+
| RequestRevertCommit
205237
| RequestViewDiff;
206238

207239
export type ResponseMessage =
208240
ResponseAddTag
209241
| ResponseCheckoutBranch
242+
| ResponseCherrypickCommit
210243
| ResponseCommitDetails
211244
| ResponseCopyCommitHashToClipboard
212245
| ResponseCreateBranch
213246
| ResponseDeleteBranch
214247
| ResponseDeleteTag
215248
| ResponseLoadBranches
216249
| ResponseLoadCommits
250+
| ResponseMergeBranch
217251
| ResponseRenameBranch
218252
| ResponseResetToCommit
253+
| ResponseRevertCommit
219254
| ResponseViewDiff;

web/main.ts

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,42 @@
514514
}, sourceElem);
515515
}
516516
},
517+
{
518+
title: 'Cherry Pick this Commit',
519+
onClick: () => {
520+
if (this.commits[this.commitLookup[hash]].parentHashes.length === 1) {
521+
showConfirmationDialog('Are you sure you want to cherry pick commit <b><i>' + abbrevCommit(hash) + '</i></b>?', () => {
522+
sendMessage({ command: 'cherrypickCommit', commitHash: hash, parentIndex: 0 });
523+
}, sourceElem);
524+
} else {
525+
let options = this.commits[this.commitLookup[hash]].parentHashes.map((hash, index) => ({
526+
name: abbrevCommit(hash) + (typeof this.commitLookup[hash] === 'number' ? ': ' + this.commits[this.commitLookup[hash]].message : ''),
527+
value: (index + 1).toString()
528+
}));
529+
showSelectDialog('Are you sure you want to cherry pick merge commit <b><i>' + abbrevCommit(hash) + '</i></b>? Choose the parent hash on the main branch, to cherry pick the commit relative to:', '1', options, 'Yes, cherry pick commit', (parentIndex) => {
530+
sendMessage({ command: 'cherrypickCommit', commitHash: hash, parentIndex: parseInt(parentIndex) });
531+
}, sourceElem);
532+
}
533+
}
534+
},
535+
{
536+
title: 'Reverse this Commit',
537+
onClick: () => {
538+
if (this.commits[this.commitLookup[hash]].parentHashes.length === 1) {
539+
showConfirmationDialog('Are you sure you want to reverse commit <b><i>' + abbrevCommit(hash) + '</i></b>?', () => {
540+
sendMessage({ command: 'revertCommit', commitHash: hash, parentIndex: 0 });
541+
}, sourceElem);
542+
} else {
543+
let options = this.commits[this.commitLookup[hash]].parentHashes.map((hash, index) => ({
544+
name: abbrevCommit(hash) + (typeof this.commitLookup[hash] === 'number' ? ': ' + this.commits[this.commitLookup[hash]].message : ''),
545+
value: (index + 1).toString()
546+
}));
547+
showSelectDialog('Are you sure you want to reverse merge commit <b><i>' + abbrevCommit(hash) + '</i></b>? Choose the parent hash on the main branch, to reverse the commit relative to:', '1', options, 'Yes, reverse commit', (parentIndex) => {
548+
sendMessage({ command: 'revertCommit', commitHash: hash, parentIndex: parseInt(parentIndex) });
549+
}, sourceElem);
550+
}
551+
}
552+
},
517553
{
518554
title: 'Reset current branch to this Commit',
519555
onClick: () => {
@@ -570,22 +606,33 @@
570606
}
571607
}];
572608
if (sourceElem.className === 'gitRef head') {
573-
menu.push({
574-
title: 'Rename Branch',
575-
onClick: () => {
576-
showInputDialog('Enter the new name for branch <b><i>' + escapeHtml(refName) + '</i></b>:', refName, 'Rename Branch', (newName) => {
577-
sendMessage({ command: 'renameBranch', oldName: refName, newName: newName });
578-
}, null);
579-
}
580-
});
581-
menu.push({
582-
title: 'Delete Branch',
583-
onClick: () => {
584-
showCheckboxDialog('Are you sure you want to delete the branch <b><i>' + escapeHtml(refName) + '</i></b>?', 'Force Delete', 'Delete Branch', (forceDelete) => {
585-
sendMessage({ command: 'deleteBranch', branchName: refName, forceDelete: forceDelete });
586-
}, null);
609+
menu.push(
610+
{
611+
title: 'Rename Branch',
612+
onClick: () => {
613+
showInputDialog('Enter the new name for branch <b><i>' + escapeHtml(refName) + '</i></b>:', refName, 'Rename Branch', (newName) => {
614+
sendMessage({ command: 'renameBranch', oldName: refName, newName: newName });
615+
}, null);
616+
}
617+
}, {
618+
title: 'Delete Branch',
619+
onClick: () => {
620+
showCheckboxDialog('Are you sure you want to delete the branch <b><i>' + escapeHtml(refName) + '</i></b>?', 'Force Delete', 'Delete Branch', (forceDelete) => {
621+
sendMessage({ command: 'deleteBranch', branchName: refName, forceDelete: forceDelete });
622+
}, null);
623+
}
587624
}
588-
});
625+
);
626+
if (this.branchOptions.length > 0 && this.branchOptions[0] !== refName) {
627+
menu.push({
628+
title: 'Merge into current branch',
629+
onClick: () => {
630+
showConfirmationDialog('Are you sure you want to merge branch <b><i>' + escapeHtml(refName) + '</i></b> into the current branch?', () => {
631+
sendMessage({ command: 'mergeBranch', branchName: refName });
632+
}, null);
633+
}
634+
});
635+
}
589636
}
590637
}
591638
showContextMenu(<MouseEvent>e, menu, sourceElem);
@@ -698,6 +745,9 @@
698745
case 'checkoutBranch':
699746
refreshGraphOrDisplayError(msg.status, 'Unable to Checkout Branch');
700747
break;
748+
case 'cherrypickCommit':
749+
refreshGraphOrDisplayError(msg.status, 'Unable to Cherry Pick Commit');
750+
break;
701751
case 'commitDetails':
702752
if (msg.commitDetails === null) {
703753
gitGraph.hideCommitDetails();
@@ -724,12 +774,18 @@
724774
case 'loadCommits':
725775
gitGraph.loadCommits(msg.commits, msg.moreCommitsAvailable);
726776
break;
777+
case 'mergeBranch':
778+
refreshGraphOrDisplayError(msg.status, 'Unable to Merge Branch');
779+
break;
727780
case 'renameBranch':
728781
refreshGraphOrDisplayError(msg.status, 'Unable to Rename Branch');
729782
break;
730783
case 'resetToCommit':
731784
refreshGraphOrDisplayError(msg.status, 'Unable to Reset to Commit');
732785
break;
786+
case 'revertCommit':
787+
refreshGraphOrDisplayError(msg.status, 'Unable to Reverse Commit');
788+
break;
733789
case 'viewDiff':
734790
if (msg.success === false) showErrorDialog('Unable to view diff of file', null, null);
735791
break;

0 commit comments

Comments
 (0)