Skip to content

Commit 3cfc74c

Browse files
authored
Git - Add setting to remember post commit command (microsoft#158449)
1 parent 45d2dd8 commit 3cfc74c

File tree

10 files changed

+229
-116
lines changed

10 files changed

+229
-116
lines changed

extensions/git/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,12 @@
21922192
"scope": "resource",
21932193
"default": "none"
21942194
},
2195+
"git.rememberPostCommitCommand": {
2196+
"type": "boolean",
2197+
"description": "%config.rememberPostCommitCommand%",
2198+
"scope": "resource",
2199+
"default": false
2200+
},
21952201
"git.openAfterClone": {
21962202
"type": "string",
21972203
"enum": [

extensions/git/package.nls.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,11 @@
163163
"config.promptToSaveFilesBeforeCommit.always": "Check for any unsaved files.",
164164
"config.promptToSaveFilesBeforeCommit.staged": "Check only for unsaved staged files.",
165165
"config.promptToSaveFilesBeforeCommit.never": "Disable this check.",
166-
"config.postCommitCommand": "Runs a git command after a successful commit.",
166+
"config.postCommitCommand": "Run a git command after a successful commit.",
167167
"config.postCommitCommand.none": "Don't run any command after a commit.",
168-
"config.postCommitCommand.push": "Run 'Git Push' after a successful commit.",
169-
"config.postCommitCommand.sync": "Run 'Git Sync' after a successful commit.",
168+
"config.postCommitCommand.push": "Run 'git push' after a successful commit.",
169+
"config.postCommitCommand.sync": "Run 'git pull' and 'git push' after a successful commit.",
170+
"config.rememberPostCommitCommand": "Remember the last git command that ran after a commit.",
170171
"config.openAfterClone": "Controls whether to open a repository automatically after cloning.",
171172
"config.openAfterClone.always": "Always open in current window.",
172173
"config.openAfterClone.alwaysNewWindow": "Always open in a new window.",

extensions/git/src/actionButton.ts

Lines changed: 22 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55

66
import * as nls from 'vscode-nls';
77
import { Command, Disposable, Event, EventEmitter, SourceControlActionButton, Uri, workspace } from 'vscode';
8-
import { ApiRepository } from './api/api1';
9-
import { Branch, Status } from './api/git';
10-
import { IPostCommitCommandsProviderRegistry } from './postCommitCommands';
8+
import { Branch, CommitCommand, Status } from './api/git';
9+
import { CommitCommandsCenter } from './postCommitCommands';
1110
import { Repository, Operation } from './repository';
1211
import { dispose } from './util';
1312

@@ -39,7 +38,7 @@ export class ActionButtonCommand {
3938

4039
constructor(
4140
readonly repository: Repository,
42-
readonly postCommitCommandsProviderRegistry: IPostCommitCommandsProviderRegistry) {
41+
readonly postCommitCommandCenter: CommitCommandsCenter) {
4342
this._state = {
4443
HEAD: undefined,
4544
isCommitInProgress: false,
@@ -52,7 +51,7 @@ export class ActionButtonCommand {
5251
repository.onDidRunGitStatus(this.onDidRunGitStatus, this, this.disposables);
5352
repository.onDidChangeOperations(this.onDidChangeOperations, this, this.disposables);
5453

55-
this.disposables.push(postCommitCommandsProviderRegistry.onDidChangePostCommitCommandsProviders(() => this._onDidChange.fire()));
54+
this.disposables.push(postCommitCommandCenter.onDidChange(() => this._onDidChange.fire()));
5655

5756
const root = Uri.file(repository.root);
5857
this.disposables.push(workspace.onDidChangeConfiguration(e => {
@@ -65,6 +64,7 @@ export class ActionButtonCommand {
6564
if (e.affectsConfiguration('git.branchProtection', root) ||
6665
e.affectsConfiguration('git.branchProtectionPrompt', root) ||
6766
e.affectsConfiguration('git.postCommitCommand', root) ||
67+
e.affectsConfiguration('git.rememberPostCommitCommand', root) ||
6868
e.affectsConfiguration('git.showActionButton', root)) {
6969
this._onDidChange.fire();
7070
}
@@ -92,14 +92,17 @@ export class ActionButtonCommand {
9292
// The button is disabled
9393
if (!showActionButton.commit) { return undefined; }
9494

95+
const primaryCommand = this.getCommitActionButtonPrimaryCommand();
96+
9597
return {
96-
command: this.getCommitActionButtonPrimaryCommand(),
98+
command: primaryCommand,
9799
secondaryCommands: this.getCommitActionButtonSecondaryCommands(),
100+
description: primaryCommand.description ?? primaryCommand.title,
98101
enabled: (this.state.repositoryHasChangesToCommit || this.state.isRebaseInProgress) && !this.state.isCommitInProgress && !this.state.isMergeInProgress
99102
};
100103
}
101104

102-
private getCommitActionButtonPrimaryCommand(): Command {
105+
private getCommitActionButtonPrimaryCommand(): CommitCommand {
103106
// Rebase Continue
104107
if (this.state.isRebaseInProgress) {
105108
return {
@@ -111,87 +114,22 @@ export class ActionButtonCommand {
111114
}
112115

113116
// Commit
114-
const config = workspace.getConfiguration('git', Uri.file(this.repository.root));
115-
const postCommitCommand = config.get<string>('postCommitCommand');
116-
117-
// Branch protection
118-
const isBranchProtected = this.repository.isBranchProtected();
119-
const branchProtectionPrompt = config.get<'alwaysCommit' | 'alwaysCommitToNewBranch' | 'alwaysPrompt'>('branchProtectionPrompt')!;
120-
const alwaysPrompt = isBranchProtected && branchProtectionPrompt === 'alwaysPrompt';
121-
const alwaysCommitToNewBranch = isBranchProtected && branchProtectionPrompt === 'alwaysCommitToNewBranch';
122-
123-
// Icon
124-
const icon = alwaysPrompt ? '$(lock)' : alwaysCommitToNewBranch ? '$(git-branch)' : undefined;
125-
126-
let commandArg = '';
127-
let title = localize('scm button commit title', "{0} Commit", icon ?? '$(check)');
128-
let tooltip = this.state.isCommitInProgress ? localize('scm button committing tooltip', "Committing Changes...") : localize('scm button commit tooltip', "Commit Changes");
129-
130-
// Title, tooltip
131-
switch (postCommitCommand) {
132-
case 'push': {
133-
commandArg = 'git.push';
134-
title = localize('scm button commit and push title', "{0} Commit & Push", icon ?? '$(arrow-up)');
135-
if (alwaysCommitToNewBranch) {
136-
tooltip = this.state.isCommitInProgress ?
137-
localize('scm button committing to new branch and pushing tooltip', "Committing to New Branch & Pushing Changes...") :
138-
localize('scm button commit to new branch and push tooltip', "Commit to New Branch & Push Changes");
139-
} else {
140-
tooltip = this.state.isCommitInProgress ?
141-
localize('scm button committing and pushing tooltip', "Committing & Pushing Changes...") :
142-
localize('scm button commit and push tooltip', "Commit & Push Changes");
143-
}
144-
break;
145-
}
146-
case 'sync': {
147-
commandArg = 'git.sync';
148-
title = localize('scm button commit and sync title', "{0} Commit & Sync", icon ?? '$(sync)');
149-
if (alwaysCommitToNewBranch) {
150-
tooltip = this.state.isCommitInProgress ?
151-
localize('scm button committing to new branch and synching tooltip', "Committing to New Branch & Synching Changes...") :
152-
localize('scm button commit to new branch and sync tooltip', "Commit to New Branch & Sync Changes");
153-
} else {
154-
tooltip = this.state.isCommitInProgress ?
155-
localize('scm button committing and synching tooltip', "Committing & Synching Changes...") :
156-
localize('scm button commit and sync tooltip', "Commit & Sync Changes");
157-
}
158-
break;
159-
}
160-
default: {
161-
if (alwaysCommitToNewBranch) {
162-
tooltip = this.state.isCommitInProgress ?
163-
localize('scm button committing to new branch tooltip', "Committing Changes to New Branch...") :
164-
localize('scm button commit to new branch tooltip', "Commit Changes to New Branch");
165-
}
166-
break;
167-
}
168-
}
169-
170-
return { command: 'git.commit', title, tooltip, arguments: [this.repository.sourceControl, commandArg] };
117+
return this.postCommitCommandCenter.getPrimaryCommand();
171118
}
172119

173120
private getCommitActionButtonSecondaryCommands(): Command[][] {
174-
const commandGroups: Command[][] = [];
175-
176-
if (!this.state.isRebaseInProgress) {
177-
for (const provider of this.postCommitCommandsProviderRegistry.getPostCommitCommandsProviders()) {
178-
const commands = provider.getCommands(new ApiRepository(this.repository));
179-
commandGroups.push((commands ?? []).map(c => {
180-
return {
181-
command: 'git.commit',
182-
title: c.title,
183-
arguments: [this.repository.sourceControl, c.command]
184-
};
185-
}));
186-
}
121+
// Rebase Continue
122+
if (this.state.isRebaseInProgress) {
123+
return [];
124+
}
187125

188-
if (commandGroups.length > 0) {
189-
commandGroups[0].splice(0, 0, {
190-
command: 'git.commit',
191-
title: localize('scm secondary button commit', "Commit"),
192-
arguments: [this.repository.sourceControl, '']
193-
});
194-
}
126+
// Commit
127+
const commandGroups: Command[][] = [];
128+
for (const commands of this.postCommitCommandCenter.getSecondaryCommands()) {
129+
commandGroups.push(commands.map(c => {
130+
// Use the description as title if present
131+
return { command: 'git.commit', title: c.description ?? c.title, tooltip: c.tooltip, arguments: c.arguments };
132+
}));
195133
}
196134

197135
return commandGroups;

extensions/git/src/api/git.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,10 @@ export interface CredentialsProvider {
254254
getCredentials(host: Uri): ProviderResult<Credentials>;
255255
}
256256

257+
export type CommitCommand = Command & { description?: string };
258+
257259
export interface PostCommitCommandsProvider {
258-
getCommands(repository: Repository): Command[];
260+
getCommands(repository: Repository): CommitCommand[];
259261
}
260262

261263
export interface PushErrorHandler {

extensions/git/src/commands.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,20 +1635,6 @@ export class CommandCenter {
16351635

16361636
await repository.commit(message, opts);
16371637

1638-
// Execute post-commit command
1639-
let postCommitCommand = opts.postCommitCommand;
1640-
1641-
if (postCommitCommand === undefined) {
1642-
// Commit WAS NOT initiated using the action button (ex: keybinding, toolbar
1643-
// action, command palette) so we honour the `git.postCommitCommand` setting.
1644-
const postCommitCommandSetting = config.get<string>('postCommitCommand');
1645-
postCommitCommand = postCommitCommandSetting === 'push' || postCommitCommandSetting === 'sync' ? `git.${postCommitCommandSetting}` : '';
1646-
}
1647-
1648-
if (postCommitCommand.length) {
1649-
await commands.executeCommand(postCommitCommand, new ApiRepository(repository));
1650-
}
1651-
16521638
return true;
16531639
}
16541640

0 commit comments

Comments
 (0)