Browse Source

Adds squash to merge git command

Replaces terminal merge with merge git command
Replaces terminal rebase with rebase git command
main
Eric Amodio 5 years ago
parent
commit
b8cbc9534c
7 changed files with 171 additions and 106 deletions
  1. +24
    -52
      package.json
  2. +35
    -3
      src/commands/git/cherry-pick.ts
  3. +32
    -1
      src/commands/git/merge.ts
  4. +23
    -1
      src/commands/git/rebase.ts
  5. +9
    -6
      src/commands/gitCommands.ts
  6. +4
    -0
      src/views/nodes/branchTrackingStatusNode.ts
  7. +44
    -43
      src/views/viewCommands.ts

+ 24
- 52
package.json View File

@ -2751,11 +2751,6 @@
}
},
{
"command": "gitlens.views.terminalCheckoutBranch",
"title": "Checkout Branch (via Terminal)",
"category": "GitLens"
},
{
"command": "gitlens.views.terminalCreateBranch",
"title": "Create Branch (via Terminal)...",
"category": "GitLens"
@ -2766,23 +2761,18 @@
"category": "GitLens"
},
{
"command": "gitlens.views.terminalMergeBranch",
"title": "Merge Branch (via Terminal)",
"category": "GitLens"
},
{
"command": "gitlens.views.terminalRebaseBranch",
"title": "Rebase (Interactive) Branch (via Terminal)",
"command": "gitlens.views.mergeBranchInto",
"title": "Merge Branch into Current",
"category": "GitLens"
},
{
"command": "gitlens.views.terminalRebaseBranchToRemote",
"title": "Rebase (Interactive) Branch to Remote (via Terminal)",
"command": "gitlens.views.rebaseOntoBranch",
"title": "Rebase Current onto Branch",
"category": "GitLens"
},
{
"command": "gitlens.views.terminalSquashBranchIntoCommit",
"title": "Squash Branch into Commit (via Terminal)",
"command": "gitlens.views.rebaseOntoUpstream",
"title": "Rebase Current onto Upstream",
"category": "GitLens"
},
{
@ -3654,10 +3644,6 @@
"when": "false"
},
{
"command": "gitlens.views.terminalCheckoutBranch",
"when": "false"
},
{
"command": "gitlens.views.terminalCreateBranch",
"when": "false"
},
@ -3666,19 +3652,15 @@
"when": "false"
},
{
"command": "gitlens.views.terminalMergeBranch",
"when": "false"
},
{
"command": "gitlens.views.terminalRebaseBranch",
"command": "gitlens.views.mergeBranchInto",
"when": "false"
},
{
"command": "gitlens.views.terminalRebaseBranchToRemote",
"command": "gitlens.views.rebaseOntoBranch",
"when": "false"
},
{
"command": "gitlens.views.terminalSquashBranchIntoCommit",
"command": "gitlens.views.rebaseOntoUpstream",
"when": "false"
},
{
@ -4440,6 +4422,21 @@
"group": "1_gitlens@1"
},
{
"command": "gitlens.views.rebaseOntoUpstream",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?=.*?\\b\\+current\\b)(?=.*?\\b\\+tracking\\b)/",
"group": "1_gitlens_1@1"
},
{
"command": "gitlens.views.mergeBranchInto",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "1_gitlens_1@2"
},
{
"command": "gitlens.views.rebaseOntoBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "1_gitlens_1@3"
},
{
"command": "gitlens.openBranchInRemote",
"when": "viewItem =~ /gitlens:branch\\b(?=.*?\\b\\+(tracking|remote)\\b)/",
"group": "2_gitlens@1"
@ -4490,31 +4487,6 @@
"group": "7_gitlens_more@2"
},
{
"command": "gitlens.views.terminalCheckoutBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "8_gitlens@1"
},
{
"command": "gitlens.views.terminalRebaseBranchToRemote",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?=.*?\\b\\+current\\b)(?=.*?\\b\\+tracking\\b)/",
"group": "8_gitlens@1"
},
{
"command": "gitlens.views.terminalMergeBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "8_gitlens@2"
},
{
"command": "gitlens.views.terminalRebaseBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "8_gitlens@3"
},
{
"command": "gitlens.views.terminalSquashBranchIntoCommit",
"when": "!gitlens:readonly && viewItem =~ /gitlens:branch\\b(?!.*?\\b\\+current\\b)/",
"group": "8_gitlens@4"
},
{
"command": "gitlens.views.terminalCreateBranch",
"when": "!gitlens:readonly && viewItem =~ /gitlens:(branch|commit|tag)\\b/",
"group": "8_gitlens@5"

+ 35
- 3
src/commands/git/cherry-pick.ts View File

@ -19,13 +19,45 @@ import { Logger } from '../../logger';
interface State {
repo: Repository;
destination: GitBranch;
source: GitBranch | GitReference;
source?: GitBranch | GitReference;
commits?: GitLogCommit[];
}
export interface CherryPickGitCommandArgs {
readonly command: 'cherry-pick';
state?: Partial<State>;
}
export class CherryPickGitCommand extends QuickCommandBase<State> {
constructor() {
constructor(args?: CherryPickGitCommandArgs) {
super('cherry-pick', 'cherry-pick', 'Cherry Pick', false, { description: 'via Terminal' });
if (args === undefined || args.state === undefined) return;
let counter = 0;
if (args.state.repo !== undefined) {
counter++;
}
if (args.state.destination !== undefined) {
counter++;
}
if (args.state.source !== undefined) {
counter++;
if (!GitBranch.is(args.state.source)) {
counter++;
}
} else if (args.state.commits !== undefined) {
counter++;
}
this._initialState = {
counter: counter,
confirm: true,
...args.state
};
}
execute(state: State) {
@ -35,7 +67,7 @@ export class CherryPickGitCommand extends QuickCommandBase {
runGitCommandInTerminal('cherry-pick', state.commits.map(c => c.sha).join(' '), state.repo.path, true);
}
runGitCommandInTerminal('cherry-pick', state.source.ref, state.repo.path, true);
runGitCommandInTerminal('cherry-pick', state.source!.ref, state.repo.path, true);
}
protected async *steps(): StepAsyncGenerator {

+ 32
- 1
src/commands/git/merge.ts View File

@ -22,9 +22,31 @@ interface State {
flags: string[];
}
export interface MergeGitCommandArgs {
readonly command: 'merge';
state?: Partial<State>;
}
export class MergeGitCommand extends QuickCommandBase<State> {
constructor() {
constructor(args?: MergeGitCommandArgs) {
super('merge', 'merge', 'Merge', false, { description: 'via Terminal' });
if (args === undefined || args.state === undefined) return;
let counter = 0;
if (args.state.repo !== undefined) {
counter++;
}
if (args.state.source !== undefined) {
counter++;
}
this._initialState = {
counter: counter,
confirm: true,
...args.state
};
}
execute(state: State) {
@ -146,6 +168,15 @@ export class MergeGitCommand extends QuickCommandBase {
count
)} from ${state.source.name} into ${state.destination.name}`,
item: ['--no-ff']
},
{
label: `Squash ${this.title}`,
description: `--squash ${state.source.name} into ${state.destination.name}`,
detail: `Will squash all commits into a single commit when merging ${Strings.pluralize(
'commit',
count
)} from ${state.source.name} into ${state.destination.name}`,
item: ['--squash']
}
]
);

+ 23
- 1
src/commands/git/rebase.ts View File

@ -22,9 +22,31 @@ interface State {
flags: string[];
}
export interface RebaseGitCommandArgs {
readonly command: 'rebase';
state?: Partial<State>;
}
export class RebaseGitCommand extends QuickCommandBase<State> {
constructor() {
constructor(args?: RebaseGitCommandArgs) {
super('rebase', 'rebase', 'Rebase', false, { description: 'via Terminal' });
if (args === undefined || args.state === undefined) return;
let counter = 0;
if (args.state.repo !== undefined) {
counter++;
}
if (args.state.source !== undefined) {
counter++;
}
this._initialState = {
counter: counter,
confirm: true,
...args.state
};
}
execute(state: State) {

+ 9
- 6
src/commands/gitCommands.ts View File

@ -11,12 +11,12 @@ import {
StepSelection
} from './quickCommand';
import { Directive, DirectiveQuickPickItem } from '../quickpicks';
import { CherryPickGitCommand } from './git/cherry-pick';
import { CherryPickGitCommand, CherryPickGitCommandArgs } from './git/cherry-pick';
import { FetchGitCommand, FetchGitCommandArgs } from './git/fetch';
import { MergeGitCommand } from './git/merge';
import { MergeGitCommand, MergeGitCommandArgs } from './git/merge';
import { PullGitCommand, PullGitCommandArgs } from './git/pull';
import { PushGitCommand, PushGitCommandArgs } from './git/push';
import { RebaseGitCommand } from './git/rebase';
import { RebaseGitCommand, RebaseGitCommandArgs } from './git/rebase';
import { StashGitCommand, StashGitCommandArgs } from './git/stash';
import { SwitchGitCommand, SwitchGitCommandArgs } from './git/switch';
import { Container } from '../container';
@ -25,9 +25,12 @@ import { configuration } from '../configuration';
const sanitizeLabel = /\$\(.+?\)|\W/g;
export type GitCommandsCommandArgs =
| CherryPickGitCommandArgs
| FetchGitCommandArgs
| MergeGitCommandArgs
| PullGitCommandArgs
| PushGitCommandArgs
| RebaseGitCommandArgs
| StashGitCommandArgs
| SwitchGitCommandArgs;
@ -39,12 +42,12 @@ class PickCommandStep implements QuickPickStep {
constructor(args?: GitCommandsCommandArgs) {
this.items = [
new CherryPickGitCommand(),
new MergeGitCommand(),
new CherryPickGitCommand(args && args.command === 'cherry-pick' ? args : undefined),
new MergeGitCommand(args && args.command === 'merge' ? args : undefined),
new FetchGitCommand(args && args.command === 'fetch' ? args : undefined),
new PullGitCommand(args && args.command === 'pull' ? args : undefined),
new PushGitCommand(args && args.command === 'push' ? args : undefined),
new RebaseGitCommand(),
new RebaseGitCommand(args && args.command === 'rebase' ? args : undefined),
new StashGitCommand(args && args.command === 'stash' ? args : undefined),
new SwitchGitCommand(args && args.command === 'switch' ? args : undefined)
];

+ 4
- 0
src/views/nodes/branchTrackingStatusNode.ts View File

@ -39,6 +39,10 @@ export class BranchTrackingStatusNode extends ViewNode implements
}):status:upstream:(${this.status.upstream}):${this.direction}`;
}
get repoPath(): string {
return this.uri.repoPath!;
}
async getChildren(): Promise<ViewNode[]> {
const ahead = this.direction === 'ahead';
const range = ahead

+ 44
- 43
src/views/viewCommands.ts View File

@ -153,17 +153,12 @@ export class ViewCommands {
this
);
commands.registerCommand('gitlens.views.terminalCheckoutBranch', this.terminalCheckoutBranch, this);
commands.registerCommand('gitlens.views.mergeBranchInto', this.merge, this);
commands.registerCommand('gitlens.views.rebaseOntoBranch', this.rebase, this);
commands.registerCommand('gitlens.views.rebaseOntoUpstream', this.rebaseToRemote, this);
commands.registerCommand('gitlens.views.terminalCreateBranch', this.terminalCreateBranch, this);
commands.registerCommand('gitlens.views.terminalDeleteBranch', this.terminalDeleteBranch, this);
commands.registerCommand('gitlens.views.terminalMergeBranch', this.terminalMergeBranch, this);
commands.registerCommand('gitlens.views.terminalRebaseBranch', this.terminalRebaseBranch, this);
commands.registerCommand('gitlens.views.terminalRebaseBranchToRemote', this.terminalRebaseBranchToRemote, this);
commands.registerCommand(
'gitlens.views.terminalSquashBranchIntoCommit',
this.terminalSquashBranchIntoCommit,
this
);
commands.registerCommand('gitlens.views.terminalCheckoutCommit', this.terminalCheckoutCommit, this);
commands.registerCommand('gitlens.views.terminalCherryPickCommit', this.terminalCherryPickCommit, this);
commands.registerCommand('gitlens.views.terminalPushCommit', this.terminalPushCommit, this);
@ -257,6 +252,46 @@ export class ViewCommands {
}
}
private async merge(node: BranchNode | TagNode) {
if (!(node instanceof BranchNode) && !(node instanceof TagNode)) return undefined;
const repo = await Container.git.getRepository(node.repoPath);
const args: GitCommandsCommandArgs = {
command: 'merge',
state: { repo: repo!, source: node instanceof BranchNode ? node.branch : node.tag }
};
return commands.executeCommand(Commands.GitCommands, args);
}
private async rebase(node: BranchNode | TagNode) {
if (!(node instanceof BranchNode) && !(node instanceof TagNode)) return undefined;
const repo = await Container.git.getRepository(node.repoPath);
const args: GitCommandsCommandArgs = {
command: 'rebase',
state: { repo: repo!, source: node instanceof BranchNode ? node.branch : node.tag }
};
return commands.executeCommand(Commands.GitCommands, args);
}
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;
const repo = await Container.git.getRepository(node.repoPath);
const branches = await repo!.getBranches({ filter: b => b.remote && b.name === upstream });
if (branches.length === 0) return undefined;
const args: GitCommandsCommandArgs = {
command: 'rebase',
state: { repo: repo!, source: branches[0] }
};
return commands.executeCommand(Commands.GitCommands, args);
}
private async restore(node: ViewRefFileNode) {
if (!(node instanceof ViewRefFileNode)) return undefined;
@ -771,12 +806,6 @@ export class ViewCommands {
return node.setComparisonNotation(comparisonNotation);
}
terminalCheckoutBranch(node: BranchNode) {
if (!(node instanceof BranchNode)) return;
runGitCommandInTerminal('checkout', `${node.ref}`, node.repoPath);
}
async terminalCreateBranch(node: ViewRefNode) {
if (!(node instanceof ViewRefNode)) return;
@ -808,34 +837,6 @@ export class ViewCommands {
}
}
terminalMergeBranch(node: BranchNode) {
if (!(node instanceof BranchNode)) return;
runGitCommandInTerminal('merge', `${node.ref}`, node.repoPath);
}
terminalRebaseBranch(node: BranchNode) {
if (!(node instanceof BranchNode)) return;
runGitCommandInTerminal('rebase', `-i ${node.ref}`, node.repoPath);
}
terminalRebaseBranchToRemote(node: BranchNode | BranchTrackingStatusNode) {
if (node instanceof BranchNode) {
if (!node.branch.current || !node.branch.tracking) return;
runGitCommandInTerminal('rebase', `-i ${node.branch.tracking}`, node.repoPath);
} else if (node instanceof BranchTrackingStatusNode) {
runGitCommandInTerminal('rebase', `-i ${node.status.upstream}`, node.status.repoPath);
}
}
terminalSquashBranchIntoCommit(node: BranchNode) {
if (!(node instanceof BranchNode)) return;
runGitCommandInTerminal('merge', `--squash ${node.ref}`, node.repoPath);
}
terminalCheckoutCommit(node: CommitNode) {
if (!(node instanceof CommitNode)) return;

Loading…
Cancel
Save