Implemented rebase onto

This commit is contained in:
tomerstav
2020-10-19 04:13:52 +00:00
parent 74ef0a92fe
commit 741925db11
5 changed files with 81 additions and 0 deletions

View File

@@ -99,6 +99,18 @@ class MergeItem implements QuickPickItem {
}
}
class RebaseOntoItem implements QuickPickItem {
get label(): string { return this.ref.name || ''; }
get description(): string { return this.ref.name || ''; }
constructor(protected ref: Ref) { }
async run(repository: Repository): Promise<void> {
await repository.rebaseOnto(repository.HEAD, this.ref);
}
}
class CreateBranchItem implements QuickPickItem {
constructor(private cc: CommandCenter) { }
@@ -1848,6 +1860,31 @@ export class CommandCenter {
await choice.run(repository);
}
@command('git.rebaseOnto', { repository: true })
async rebaseOnto(repository: Repository): Promise<void> {
const config = workspace.getConfiguration('git');
const checkoutType = config.get<string>('checkoutType') || 'all';
const includeRemotes = checkoutType === 'all' || checkoutType === 'remote';
const heads = repository.refs.filter(ref => ref.type === RefType.Head)
.filter(ref => ref.name || ref.commit)
.map(ref => new RebaseOntoItem(ref as Branch));
const remoteHeads = (includeRemotes ? repository.refs.filter(ref => ref.type === RefType.RemoteHead) : [])
.filter(ref => ref.name || ref.commit)
.map(ref => new RebaseOntoItem(ref as Branch));
const picks = [...heads, ...remoteHeads];
const placeHolder = localize('select a branch to rebase onto', 'Select a branch to rebase onto');
const choice = await window.showQuickPick<RebaseOntoItem>(picks, { placeHolder });
if (!choice) {
return;
}
await choice.run(repository);
}
@command('git.createTag', { repository: true })
async createTag(repository: Repository): Promise<void> {
const inputTagName = await window.showInputBox({

View File

@@ -1608,6 +1608,24 @@ export class Repository {
}
}
async rebase(branch: string, options: PullOptions = {}): Promise<void> {
const args = ['rebase'];
args.push(branch);
try {
await this.run(args, options);
} catch (err) {
if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) {
err.gitErrorCode = GitErrorCodes.Conflict;
} else if (/cannot rebase onto multiple branches/i.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.CantRebaseMultipleBranches;
}
throw err;
}
}
async push(remote?: string, name?: string, setUpstream: boolean = false, tags = false, forcePushMode?: ForcePushMode): Promise<void> {
const args = ['push'];

View File

@@ -300,6 +300,7 @@ export const enum Operation {
RenameBranch = 'RenameBranch',
DeleteRef = 'DeleteRef',
Merge = 'Merge',
Rebase = 'Rebase',
Ignore = 'Ignore',
Tag = 'Tag',
DeleteTag = 'DeleteTag',
@@ -1067,6 +1068,10 @@ export class Repository implements Disposable {
await this.run(Operation.Merge, () => this.repository.merge(ref));
}
async rebase(branch: string): Promise<void> {
await this.run(Operation.Rebase, () => this.repository.rebase(branch));
}
async tag(name: string, message?: string): Promise<void> {
await this.run(Operation.Tag, () => this.repository.tag(name, message));
}
@@ -1143,6 +1148,14 @@ export class Repository implements Disposable {
return this.pullFrom(true, remote, branch);
}
@throttle
async rebaseOnto(head: Branch | undefined, branch: Branch | undefined): Promise<void> {
if (head?.name && branch?.name) {
await this.checkout(branch.name);
await this.rebase(head.name);
}
}
@throttle
async pull(head?: Branch, unshallow?: boolean): Promise<void> {
let remote: string | undefined;