Browse Source

Replaces terminal push to commit cmd w/ real cmd

main
Eric Amodio 4 years ago
parent
commit
cfd7e25dc2
7 changed files with 131 additions and 628 deletions
  1. +16
    -16
      package.json
  2. +52
    -30
      src/commands/git/push.ts
  3. +5
    -552
      src/commands/gitCommands.actions.ts
  4. +19
    -2
      src/git/gitService.ts
  5. +9
    -6
      src/git/models/models.ts
  6. +21
    -6
      src/git/models/repository.ts
  7. +9
    -16
      src/views/viewCommands.ts

+ 16
- 16
package.json View File

@ -3041,6 +3041,11 @@
"category": "GitLens"
},
{
"command": "gitlens.views.pushToCommit",
"title": "Push to Commit...",
"category": "GitLens"
},
{
"command": "gitlens.views.rebaseOntoBranch",
"title": "Rebase Current onto Branch...",
"category": "GitLens"
@ -3066,11 +3071,6 @@
"category": "GitLens"
},
{
"command": "gitlens.views.terminalPushCommit",
"title": "Push to Commit (via Terminal)",
"category": "GitLens"
},
{
"command": "gitlens.views.terminalRemoveRemote",
"title": "Remove Remote (via Terminal)",
"category": "GitLens"
@ -3994,6 +3994,10 @@
"when": "false"
},
{
"command": "gitlens.views.pushToCommit",
"when": "false"
},
{
"command": "gitlens.views.rebaseOntoBranch",
"when": "false"
},
@ -4014,10 +4018,6 @@
"when": "false"
},
{
"command": "gitlens.views.terminalPushCommit",
"when": "false"
},
{
"command": "gitlens.views.terminalRemoveRemote",
"when": "false"
},
@ -5090,8 +5090,8 @@
"group": "1_gitlens_actions@3"
},
{
"command": "gitlens.views.switchToCommit",
"when": "!gitlens:readonly && viewItem =~ /gitlens:commit\\b/",
"command": "gitlens.views.pushToCommit",
"when": "!gitlens:readonly && viewItem =~ /gitlens:commit\\b(?=.*?\\b\\+current\\b)/",
"group": "1_gitlens_actions@4"
},
{
@ -5100,6 +5100,11 @@
"group": "1_gitlens_actions@5"
},
{
"command": "gitlens.views.switchToCommit",
"when": "!gitlens:readonly && viewItem =~ /gitlens:commit\\b/",
"group": "1_gitlens_actions@6"
},
{
"command": "gitlens.views.createBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:commit\\b/",
"group": "1_gitlens_actions_1@1"
@ -5146,11 +5151,6 @@
"group": "3_gitlens_explore@2"
},
{
"command": "gitlens.views.terminalPushCommit",
"when": "!gitlens:readonly && viewItem =~ /gitlens:commit\\b(?=.*?\\b\\+current\\b)/",
"group": "6_gitlens_terminal@1"
},
{
"command": "gitlens.copyShaToClipboard",
"when": "viewItem =~ /gitlens:(commit|file\\b(?=.*?\\b\\+committed\\b))\\b/",
"group": "7_gitlens_cutcopypaste@1"

+ 52
- 30
src/commands/git/push.ts View File

@ -1,11 +1,12 @@
'use strict';
import { configuration } from '../../configuration';
import { Container } from '../../container';
import { Repository } from '../../git/git';
import { GitReference, Repository } from '../../git/git';
import {
appendReposToTitle,
PartialStepState,
pickRepositoriesStep,
pickRepositoryStep,
QuickCommand,
QuickCommandButtons,
QuickPickStep,
@ -28,6 +29,7 @@ type Flags = '--force';
interface State<Repos = string | string[] | Repository | Repository[]> {
repos: Repos;
reference?: GitReference;
flags: Flags[];
}
@ -58,7 +60,10 @@ export class PushGitCommand extends QuickCommand {
}
execute(state: State<Repository[]>) {
return Container.git.pushAll(state.repos, { force: state.flags.includes('--force') });
return Container.git.pushAll(state.repos, {
force: state.flags.includes('--force'),
reference: state.reference,
});
}
protected async *steps(state: PartialStepState<State>): StepGenerator {
@ -89,6 +94,15 @@ export class PushGitCommand extends QuickCommand {
state.counter++;
}
state.repos = [context.repos[0]];
} else if (state.reference != null) {
const result = yield* pickRepositoryStep(
{ ...state, repos: undefined, reference: undefined },
context,
);
// Always break on the first step (so we will go back)
if (result === StepResult.Break) break;
state.repos = [result];
} else {
const result = yield* pickRepositoriesStep(
state as ExcludeSome<typeof state, 'repos', string | Repository>,
@ -163,39 +177,47 @@ export class PushGitCommand extends QuickCommand {
).fromNow()}`;
}
if (status?.state.behind) {
step = this.createConfirmStep(
appendReposToTitle(`Confirm ${context.title}`, state, context, lastFetchedOn),
[],
DirectiveQuickPickItem.create(Directive.Cancel, true, {
label: `Cancel ${this.title}`,
detail: `Cannot push; $(repo) ${repo.formattedName} is behind by ${Strings.pluralize(
'commit',
status.state.behind,
)}`,
}),
);
let pushDetails;
if (state.reference != null) {
pushDetails = status?.state.ahead
? ` commits up to ${GitReference.toString(state.reference, { label: false })} to $(repo) ${
repo.formattedName
}`
: ` to ${repo.formattedName}`;
} else {
const pushDetails = status?.state.ahead
pushDetails = status?.state.ahead
? ` ${Strings.pluralize('commit', status.state.ahead)} to $(repo) ${repo.formattedName}`
: ` to ${repo.formattedName}`;
step = this.createConfirmStep(
appendReposToTitle(`Confirm ${context.title}`, state, context, lastFetchedOn),
[
FlagsQuickPickItem.create<Flags>(state.flags, [], {
label: this.title,
detail: `Will push${pushDetails}`,
}),
FlagsQuickPickItem.create<Flags>(state.flags, ['--force'], {
label: `Force ${this.title}${useForceWithLease ? ' (with lease)' : ''}`,
description: `--force${useForceWithLease ? '-with-lease' : ''}`,
detail: `Will force push${useForceWithLease ? ' (with lease)' : ''} ${pushDetails}`,
}),
],
);
}
step = this.createConfirmStep(
appendReposToTitle(`Confirm ${context.title}`, state, context, lastFetchedOn),
[
...(status?.state.behind
? []
: [
FlagsQuickPickItem.create<Flags>(state.flags, [], {
label: this.title,
detail: `Will push${pushDetails}`,
}),
]),
FlagsQuickPickItem.create<Flags>(state.flags, ['--force'], {
label: `Force ${this.title}${useForceWithLease ? ' (with lease)' : ''}`,
description: `--force${useForceWithLease ? '-with-lease' : ''}`,
detail: `Will force push${useForceWithLease ? ' (with lease)' : ''} ${pushDetails}`,
}),
],
status?.state.behind
? DirectiveQuickPickItem.create(Directive.Cancel, true, {
label: `Cancel ${this.title}`,
detail: `Cannot push; $(repo) ${repo.formattedName} is behind by ${Strings.pluralize(
'commit',
status.state.behind,
)}`,
})
: undefined,
);
step.additionalButtons = [QuickCommandButtons.Fetch];
step.onDidClickButton = async (quickpick, button) => {
if (button !== QuickCommandButtons.Fetch || quickpick.busy) return false;

+ 5
- 552
src/commands/gitCommands.actions.ts View File

@ -62,8 +62,11 @@ export namespace GitActions {
return executeGitCommand({ command: 'pull', state: { repos: repos } });
}
export function push(repos?: string | string[] | Repository | Repository[], force?: boolean) {
return executeGitCommand({ command: 'push', state: { repos: repos, flags: force ? ['--force'] : [] } });
export function push(repos?: string | string[] | Repository | Repository[], force?: boolean, ref?: GitReference) {
return executeGitCommand({
command: 'push',
state: { repos: repos, flags: force ? ['--force'] : [], reference: ref },
});
}
export async function rebase(repo?: string | Repository, ref?: GitReference, interactive: boolean = true) {
@ -94,556 +97,6 @@ export namespace GitActions {
});
}
// @debug()
// private async highlightChanges(node: CommitFileNode | ResultsFileNode | StashFileNode) {
// if (
// !(node instanceof CommitFileNode) &&
// !(node instanceof StashFileNode) &&
// !(node instanceof ResultsFileNode)
// ) {
// return;
// }
// void (await this.openFile(node));
// void (await Container.fileAnnotations.toggle(
// window.activeTextEditor,
// FileAnnotationType.RecentChanges,
// node.ref,
// true,
// ));
// }
// @debug()
// private async highlightRevisionChanges(node: CommitFileNode | ResultsFileNode | StashFileNode) {
// if (
// !(node instanceof CommitFileNode) &&
// !(node instanceof StashFileNode) &&
// !(node instanceof ResultsFileNode)
// ) {
// return;
// }
// void (await this.openFileRevision(node, { showOptions: { preserveFocus: true, preview: true } }));
// void (await Container.fileAnnotations.toggle(
// window.activeTextEditor,
// FileAnnotationType.RecentChanges,
// node.ref,
// true,
// ));
// }
// @debug()
// private openInTerminal(node: RepositoryNode) {
// if (!(node instanceof RepositoryNode)) return undefined;
// return commands.executeCommand(BuiltInCommands.OpenInTerminal, Uri.file(node.repo.path));
// }
// @debug()
// private async rebaseToRemote(node: BranchNode | BranchTrackingStatusNode) {
// if (!(node instanceof BranchNode) && !(node instanceof BranchTrackingStatusNode)) return undefined;
// const upstream = node instanceof BranchNode ? node.branch.tracking : node.status.upstream;
// if (upstream == null) return undefined;
// const repo = await Container.git.getRepository(node.repoPath);
// const args: GitCommandsCommandArgs = {
// command: 'rebase',
// state: {
// repo: repo!,
// reference: GitReference.create(upstream, repo!.path, {
// refType: 'branch',
// name: upstream,
// remote: true,
// }),
// },
// };
// return commands.executeCommand(Commands.GitCommands, args);
// }
// @debug()
// private setAsDefault(node: RemoteNode) {
// if (node instanceof RemoteNode) return node.setAsDefault();
// return undefined;
// }
// @debug()
// private setComparisonNotation(node: ViewNode, comparisonNotation: '...' | '..') {
// if (!(node instanceof CompareResultsNode) && !(node instanceof CompareBranchNode)) return undefined;
// return node.setComparisonNotation(comparisonNotation);
// }
// @debug()
// private async stageFile(node: CommitFileNode | StatusFileNode) {
// if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return;
// void (await Container.git.stageFile(node.repoPath, node.file.fileName));
// void node.triggerChange();
// }
// @debug()
// private async stageDirectory(node: FolderNode) {
// if (!(node instanceof FolderNode) || !node.relativePath) return;
// void (await Container.git.stageDirectory(node.repoPath, node.relativePath));
// void node.triggerChange();
// }
// @debug()
// private star(node: BranchNode | RepositoryNode) {
// if (node instanceof BranchNode || node instanceof RepositoryNode) return node.star();
// return undefined;
// }
// @debug()
// private unsetAsDefault(node: RemoteNode) {
// if (node instanceof RemoteNode) return node.setAsDefault(false);
// return undefined;
// }
// @debug()
// private async unstageFile(node: CommitFileNode | StatusFileNode) {
// if (!(node instanceof CommitFileNode) && !(node instanceof StatusFileNode)) return;
// void (await Container.git.unStageFile(node.repoPath, node.file.fileName));
// void node.triggerChange();
// }
// @debug()
// private async unstageDirectory(node: FolderNode) {
// if (!(node instanceof FolderNode) || !node.relativePath) return;
// void (await Container.git.unStageDirectory(node.repoPath, node.relativePath));
// void node.triggerChange();
// }
// @debug()
// private unstar(node: BranchNode | RepositoryNode) {
// if (node instanceof BranchNode || node instanceof RepositoryNode) return node.unstar();
// return undefined;
// }
// @debug()
// private compareWithHead(node: ViewRefNode) {
// if (!(node instanceof ViewRefNode)) return undefined;
// return Container.compareView.compare(node.repoPath, node.ref, 'HEAD');
// }
// @debug()
// private compareWithRemote(node: BranchNode) {
// if (!(node instanceof BranchNode)) return undefined;
// if (!node.branch.tracking) return undefined;
// return Container.compareView.compare(node.repoPath, node.branch.tracking, node.ref);
// }
// @debug()
// private compareWithWorking(node: ViewRefNode) {
// if (!(node instanceof ViewRefNode)) return undefined;
// return Container.compareView.compare(node.repoPath, node.ref, '');
// }
// @debug()
// private async compareAncestryWithWorking(node: BranchNode) {
// if (!(node instanceof BranchNode)) return undefined;
// const branch = await Container.git.getBranch(node.repoPath);
// if (branch == null) return undefined;
// const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.ref, node.ref);
// if (commonAncestor == null) return undefined;
// return Container.compareView.compare(
// node.repoPath,
// { ref: commonAncestor, label: `ancestry with ${node.ref} (${GitRevision.shorten(commonAncestor)})` },
// '',
// );
// }
// @debug()
// private compareWithSelected(node: ViewRefNode) {
// if (!(node instanceof ViewRefNode)) return;
// Container.compareView.compareWithSelected(node.repoPath, node.ref);
// }
// @debug()
// private selectForCompare(node: ViewRefNode) {
// if (!(node instanceof ViewRefNode)) return;
// Container.compareView.selectForCompare(node.repoPath, node.ref);
// }
// @debug()
// private compareFileWithSelected(node: ViewRefFileNode) {
// if (this._selectedFile == null || !(node instanceof ViewRefFileNode) || node.ref == null) {
// return undefined;
// }
// if (this._selectedFile.repoPath !== node.repoPath) {
// this.selectFileForCompare(node);
// return undefined;
// }
// const selected = this._selectedFile;
// this._selectedFile = undefined;
// setCommandContext(CommandContext.ViewsCanCompareFile, false);
// const diffArgs: DiffWithCommandArgs = {
// repoPath: selected.repoPath,
// lhs: {
// sha: selected.ref,
// uri: selected.uri!,
// },
// rhs: {
// sha: node.ref,
// uri: node.uri,
// },
// };
// return commands.executeCommand(Commands.DiffWith, diffArgs);
// }
// private _selectedFile: CompareSelectedInfo | undefined;
// @debug()
// private selectFileForCompare(node: ViewRefFileNode) {
// if (!(node instanceof ViewRefFileNode) || node.ref == null) return;
// this._selectedFile = {
// ref: node.ref,
// repoPath: node.repoPath,
// uri: node.uri,
// };
// setCommandContext(CommandContext.ViewsCanCompareFile, true);
// }
// @debug()
// private openChanges(node: ViewRefFileNode | StatusFileNode) {
// if (!(node instanceof ViewRefFileNode) && !(node instanceof StatusFileNode)) return undefined;
// const command = node.getCommand();
// if (command == null || command.arguments == null) return undefined;
// const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs];
// args.showOptions!.preview = false;
// return commands.executeCommand(command.command, uri, args);
// }
// @debug()
// private openChangesWithWorking(node: ViewRefFileNode | StatusFileNode) {
// if (!(node instanceof ViewRefFileNode) && !(node instanceof StatusFileNode)) return undefined;
// const args: DiffWithWorkingCommandArgs = {
// showOptions: {
// preserveFocus: true,
// preview: false,
// },
// };
// return commands.executeCommand(Commands.DiffWithWorking, node.uri, args);
// }
// @debug()
// private openFile(node: ViewRefFileNode | StatusFileNode | FileHistoryNode | LineHistoryNode) {
// if (
// !(node instanceof ViewRefFileNode) &&
// !(node instanceof StatusFileNode) &&
// !(node instanceof FileHistoryNode) &&
// !(node instanceof LineHistoryNode)
// ) {
// return undefined;
// }
// const args: OpenWorkingFileCommandArgs = {
// uri: node.uri,
// showOptions: {
// preserveFocus: true,
// preview: false,
// },
// };
// return commands.executeCommand(Commands.OpenWorkingFile, undefined, args);
// }
// @debug()
// private openFileRevision(
// node: CommitFileNode | ResultsFileNode | StashFileNode | StatusFileNode,
// options?: OpenFileRevisionCommandArgs,
// ) {
// if (
// !(node instanceof CommitFileNode) &&
// !(node instanceof StashFileNode) &&
// !(node instanceof ResultsFileNode) &&
// !(node instanceof StatusFileNode)
// ) {
// return undefined;
// }
// options = { showOptions: { preserveFocus: true, preview: false }, ...options };
// let uri = options.uri;
// if (uri == null) {
// if (node instanceof ResultsFileNode) {
// uri = GitUri.toRevisionUri(node.uri);
// } else {
// uri =
// node.commit.status === 'D'
// ? GitUri.toRevisionUri(
// node.commit.previousSha!,
// node.commit.previousUri.fsPath,
// node.commit.repoPath,
// )
// : GitUri.toRevisionUri(node.uri);
// }
// }
// return findOrOpenEditor(uri, options.showOptions || { preserveFocus: true, preview: false });
// }
// @debug()
// private openFileRevisionInRemote(node: CommitFileNode) {
// if (!(node instanceof CommitFileNode) || node instanceof StashFileNode) return undefined;
// const args: OpenFileInRemoteCommandArgs = {
// range: false,
// };
// return commands.executeCommand(
// Commands.OpenFileInRemote,
// node.commit.toGitUri(node.commit.status === 'D'),
// args,
// );
// }
// @debug()
// private async openChangedFiles(
// node: CommitNode | StashNode | ResultsFilesNode,
// options?: TextDocumentShowOptions,
// ) {
// if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
// return;
// }
// options = { preserveFocus: false, preview: false, ...options };
// let repoPath: string;
// let files;
// let ref: string;
// if (node instanceof ResultsFilesNode) {
// const { diff } = await node.getFilesQueryResults();
// if (diff == null || diff.length === 0) return;
// repoPath = node.repoPath;
// files = diff;
// ref = node.ref1 || node.ref2;
// } else {
// repoPath = node.commit.repoPath;
// files = node.commit.files;
// ref = node.commit.sha;
// }
// if (files.length > 20) {
// const result = await window.showWarningMessage(
// `Are your sure you want to open all ${files.length} files?`,
// { title: 'Yes' },
// { title: 'No', isCloseAffordance: true },
// );
// if (result == null || result.title === 'No') return;
// }
// for (const file of files) {
// const uri = GitUri.fromFile(file, repoPath, ref);
// const args: OpenWorkingFileCommandArgs = {
// uri: uri,
// showOptions: options,
// };
// await commands.executeCommand(Commands.OpenWorkingFile, undefined, args);
// }
// }
// @debug()
// private async openChangedFileDiffs(
// node: CommitNode | StashNode | ResultsFilesNode,
// options?: TextDocumentShowOptions,
// ) {
// if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
// return;
// }
// options = { preserveFocus: false, preview: false, ...options };
// let repoPath: string;
// let files;
// let ref1: string;
// let ref2: string;
// if (node instanceof ResultsFilesNode) {
// const { diff } = await node.getFilesQueryResults();
// if (diff == null || diff.length === 0) return;
// repoPath = node.repoPath;
// files = diff;
// ref1 = node.ref1;
// ref2 = node.ref2;
// } else {
// repoPath = node.commit.repoPath;
// files = node.commit.files;
// ref1 = node.commit.previousSha != null ? node.commit.previousSha : GitRevision.deletedOrMissing;
// ref2 = node.commit.sha;
// }
// if (files.length > 20) {
// const result = await window.showWarningMessage(
// `Are your sure you want to open all ${files.length} files?`,
// { title: 'Yes' },
// { title: 'No', isCloseAffordance: true },
// );
// if (result == null || result.title === 'No') return;
// }
// let diffArgs: DiffWithCommandArgs;
// for (const file of files) {
// if (file.status === 'A') continue;
// const uri1 = GitUri.fromFile(file, repoPath);
// const uri2 =
// file.status === 'R' || file.status === 'C' ? GitUri.fromFile(file, repoPath, ref2, true) : uri1;
// diffArgs = {
// repoPath: repoPath,
// lhs: { uri: uri1, sha: ref1 },
// rhs: { uri: uri2, sha: ref2 },
// showOptions: options,
// };
// void (await commands.executeCommand(Commands.DiffWith, diffArgs));
// }
// }
// @debug()
// private async openChangedFileDiffsWithWorking(
// node: CommitNode | StashNode | ResultsFilesNode,
// options?: TextDocumentShowOptions,
// ) {
// if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
// return;
// }
// options = { preserveFocus: false, preview: false, ...options };
// let repoPath: string;
// let files;
// let ref: string;
// if (node instanceof ResultsFilesNode) {
// const { diff } = await node.getFilesQueryResults();
// if (diff == null || diff.length === 0) return;
// repoPath = node.repoPath;
// files = diff;
// ref = node.ref1 || node.ref2;
// } else {
// repoPath = node.commit.repoPath;
// files = node.commit.files;
// ref = node.commit.sha;
// }
// if (files.length > 20) {
// const result = await window.showWarningMessage(
// `Are your sure you want to open all ${files.length} files?`,
// { title: 'Yes' },
// { title: 'No', isCloseAffordance: true },
// );
// if (result == null || result.title === 'No') return;
// }
// for (const file of files) {
// if (file.status === 'A' || file.status === 'D') continue;
// const args: DiffWithWorkingCommandArgs = {
// showOptions: options,
// };
// const uri = GitUri.fromFile(file, repoPath, ref);
// await commands.executeCommand(Commands.DiffWithWorking, uri, args);
// }
// }
// @debug()
// private async openChangedFileRevisions(
// node: CommitNode | StashNode | ResultsFilesNode,
// options?: TextDocumentShowOptions,
// ) {
// if (!(node instanceof CommitNode) && !(node instanceof StashNode) && !(node instanceof ResultsFilesNode)) {
// return;
// }
// options = { preserveFocus: false, preview: false, ...options };
// let repoPath: string;
// let files;
// let ref1: string;
// let ref2: string;
// if (node instanceof ResultsFilesNode) {
// const { diff } = await node.getFilesQueryResults();
// if (diff == null || diff.length === 0) return;
// repoPath = node.repoPath;
// files = diff;
// ref1 = node.ref1;
// ref2 = node.ref2;
// } else {
// repoPath = node.commit.repoPath;
// files = node.commit.files;
// ref1 = node.commit.sha;
// ref2 = node.commit.previousFileSha;
// }
// if (files.length > 20) {
// const result = await window.showWarningMessage(
// `Are your sure you want to open all ${files.length} files?`,
// { title: 'Yes' },
// { title: 'No', isCloseAffordance: true },
// );
// if (result == null || result.title === 'No') return;
// }
// for (const file of files) {
// const uri = GitUri.toRevisionUri(file.status === 'D' ? ref2 : ref1, file, repoPath);
// await findOrOpenEditor(uri, options);
// }
// }
// terminalCheckoutCommit(node: CommitNode) {
// if (!(node instanceof CommitNode)) return;
// runGitCommandInTerminal('checkout', `${node.ref}`, node.repoPath);
// }
// async terminalPushCommit(node: CommitNode) {
// if (!(node instanceof CommitNode)) return;
// const branch = node.branch || (await Container.git.getBranch(node.repoPath));
// if (branch == null) return;
// runGitCommandInTerminal(
// 'push',
// `${branch.getRemoteName()} ${node.ref}:${branch.getNameWithoutRemote()}`,
// node.repoPath,
// );
// }
// terminalRemoveRemote(node: RemoteNode) {
// if (!(node instanceof RemoteNode)) return;
// runGitCommandInTerminal('remote', `remove ${node.remote.name}`, node.remote.repoPath);
// }
export namespace Branch {
export function create(repo?: string | Repository, ref?: GitReference, name?: string) {
return executeGitCommand({

+ 19
- 2
src/git/gitService.ts View File

@ -18,7 +18,7 @@ import {
WorkspaceFolder,
WorkspaceFoldersChangeEvent,
} from 'vscode';
import { API as BuiltInGitApi, GitExtension } from '../@types/git';
import { API as BuiltInGitApi, Repository as BuiltInGitRepository, GitExtension } from '../@types/git';
import { configuration } from '../configuration';
import { CommandContext, DocumentSchemes, setCommandContext } from '../constants';
import { Container } from '../container';
@ -62,6 +62,7 @@ import {
GitLog,
GitLogCommit,
GitLogParser,
GitReference,
GitReflog,
GitRemote,
GitRemoteParser,
@ -620,7 +621,7 @@ export class GitService implements Disposable {
0: (repos?: Repository[]) => (repos == null ? false : repos.map(r => r.name).join(', ')),
},
})
async pushAll(repositories?: Repository[], options: { force?: boolean } = {}) {
async pushAll(repositories?: Repository[], options: { force?: boolean; reference?: GitReference } = {}) {
if (repositories == null) {
repositories = await this.getOrderedRepositories();
}
@ -3270,6 +3271,22 @@ export class GitService implements Disposable {
return undefined;
}
@log()
static async getBuiltInGitRepository(repoPath: string): Promise<BuiltInGitRepository | undefined> {
const gitApi = await GitService.getBuiltInGitApi();
if (gitApi == null) return undefined;
const normalizedPath = Strings.normalizePath(repoPath, { stripTrailingSlash: true }).toLowerCase();
const repo = gitApi.repositories.find(r => {
const normalized = Strings.normalizePath(r.rootUri.fsPath, {
stripTrailingSlash: true,
}).toLowerCase();
return normalized === normalizedPath;
});
return repo;
}
static getEncoding(repoPath: string, fileName: string): string;
static getEncoding(uri: Uri): string;
static getEncoding(repoPathOrUri: string | Uri, fileName?: string): string {

+ 9
- 6
src/git/models/models.ts View File

@ -219,23 +219,26 @@ export namespace GitReference {
export function toString(
refs: GitReference | GitReference[] | undefined,
options?: { capitalize?: boolean; expand?: boolean; icon?: boolean } | false,
options?: { capitalize?: boolean; expand?: boolean; icon?: boolean; label?: boolean } | false,
) {
if (refs == null) return '';
options = options === false ? {} : { expand: true, icon: true, ...options };
options =
options === false
? {}
: { expand: true, icon: true, label: options?.label ?? options?.expand ?? true, ...options };
let result;
if (!Array.isArray(refs) || refs.length === 1) {
const ref = Array.isArray(refs) ? refs[0] : refs;
switch (ref.refType) {
case 'branch':
result = `${options.expand ? `${ref.remote ? 'remote ' : ''}branch ` : ''}${
result = `${options.label ? `${ref.remote ? 'remote ' : ''}branch ` : ''}${
options.icon ? `$(git-branch) ${ref.name}${GlyphChars.Space}` : ref.name
}`;
break;
case 'tag':
result = `${options.expand ? 'tag ' : ''}${
result = `${options.label ? 'tag ' : ''}${
options.icon ? `$(tag) ${ref.name}${GlyphChars.Space}` : ref.name
}`;
break;
@ -250,7 +253,7 @@ export namespace GitReference {
}`;
}
result = `${options.expand ? 'stash ' : ''}${
result = `${options.label ? 'stash ' : ''}${
options.icon
? `$(archive) ${message ?? ref.name}${GlyphChars.Space}`
: `${message ?? ref.number ?? ref.name}`
@ -266,7 +269,7 @@ export namespace GitReference {
: ` (${ref.message})`;
}
result = `${options.expand ? 'commit ' : ''}${
result = `${options.label ? 'commit ' : ''}${
options.icon
? `$(git-commit) ${ref.name}${message ?? ''}${GlyphChars.Space}`
: `${ref.name}${message ?? ''}`

+ 21
- 6
src/git/models/repository.ts View File

@ -18,6 +18,7 @@ import { StarredRepositories, WorkspaceState } from '../../constants';
import { Container } from '../../container';
import { Functions, gate, Iterables, log, logName } from '../../system';
import { GitBranch, GitContributor, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git';
import { GitService } from '../gitService';
import { GitUri } from '../gitUri';
import { RemoteProviderFactory, RemoteProviders, RemoteProviderWithApi } from '../remotes/factory';
import { Messages } from '../../messages';
@ -444,22 +445,36 @@ export class Repository implements Disposable {
@gate()
@log()
async push(options: { force?: boolean; progress?: boolean } = {}) {
const { force, progress } = { progress: true, ...options };
if (!progress) return this.pushCore(force);
async push(options: { force?: boolean; progress?: boolean; reference?: GitReference } = {}) {
const { force, progress, reference } = { progress: true, ...options };
if (!progress) return this.pushCore(force, reference);
return void (await window.withProgress(
{
location: ProgressLocation.Notification,
title: `Pushing ${this.formattedName}...`,
},
() => this.pushCore(force),
() => this.pushCore(force, reference),
));
}
private async pushCore(force: boolean = false) {
private async pushCore(force: boolean = false, reference?: GitReference) {
try {
void (await commands.executeCommand(force ? 'git.pushForce' : 'git.push', this.path));
if (reference != null) {
const branch = await this.getBranch();
if (branch === undefined) return;
const repo = await GitService.getBuiltInGitRepository(this.path);
if (repo == null) return;
await repo?.push(
branch.getRemoteName(),
`${reference.ref}:${branch.getNameWithoutRemote()}`,
undefined,
);
} else {
void (await commands.executeCommand(force ? 'git.pushForce' : 'git.push', this.path));
}
this.fireChange(RepositoryChange.Repository);
} catch (ex) {

+ 9
- 16
src/views/viewCommands.ts View File

@ -166,6 +166,7 @@ export class ViewCommands {
commands.registerCommand('gitlens.views.deleteTag', this.deleteTag, this);
commands.registerCommand('gitlens.views.mergeBranchInto', this.merge, this);
commands.registerCommand('gitlens.views.pushToCommit', this.pushToCommit, this);
commands.registerCommand('gitlens.views.rebaseOntoBranch', this.rebase, this);
commands.registerCommand('gitlens.views.rebaseOntoUpstream', this.rebaseToRemote, this);
@ -174,8 +175,6 @@ export class ViewCommands {
commands.registerCommand('gitlens.views.reset', this.reset, this);
commands.registerCommand('gitlens.views.revert', this.revert, this);
commands.registerCommand('gitlens.views.terminalPushCommit', this.terminalPushCommit, this);
commands.registerCommand('gitlens.views.terminalRemoveRemote', this.terminalRemoveRemote, this);
}
@ -324,13 +323,20 @@ export class ViewCommands {
}
@debug()
private async merge(node: BranchNode | TagNode) {
private merge(node: BranchNode | TagNode) {
if (!(node instanceof BranchNode) && !(node instanceof TagNode)) return undefined;
return GitActions.merge(node.repoPath, node instanceof BranchNode ? node.branch : node.tag);
}
@debug()
private pushToCommit(node: CommitNode) {
if (!(node instanceof CommitNode)) return undefined;
return GitActions.push(node.repoPath, false, node.commit);
}
@debug()
private openInTerminal(node: RepositoryNode) {
if (!(node instanceof RepositoryNode)) return undefined;
@ -832,19 +838,6 @@ export class ViewCommands {
);
}
async terminalPushCommit(node: CommitNode) {
if (!(node instanceof CommitNode)) return;
const branch = node.branch ?? (await Container.git.getBranch(node.repoPath));
if (branch === undefined) return;
runGitCommandInTerminal(
'push',
`${branch.getRemoteName()} ${node.ref}:${branch.getNameWithoutRemote()}`,
node.repoPath,
);
}
terminalRemoveRemote(node: RemoteNode) {
if (!(node instanceof RemoteNode)) return;

Loading…
Cancel
Save