diff --git a/extensions/git/package.json b/extensions/git/package.json index 3db3f72875d..cb3a56a982d 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -192,6 +192,11 @@ "title": "%command.pullRebase%", "category": "Git" }, + { + "command": "git.pullFrom", + "title": "%command.pullFrom%", + "category": "Git" + }, { "command": "git.push", "title": "%command.push%", @@ -325,6 +330,10 @@ "command": "git.pullRebase", "when": "config.git.enabled && scmProvider == git && gitState == idle" }, + { + "command": "git.pullFrom", + "when": "config.git.enabled && scmProvider == git && gitState == idle" + }, { "command": "git.push", "when": "config.git.enabled && scmProvider == git && gitState == idle" @@ -377,6 +386,11 @@ "group": "1_sync", "when": "config.git.enabled && scmProvider == git && gitState == idle" }, + { + "command": "git.pullFrom", + "group": "1_sync", + "when": "config.git.enabled && scmProvider == git && gitState == idle" + }, { "command": "git.push", "group": "1_sync", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 52edd8318c0..199338a68e6 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -25,6 +25,7 @@ "command.merge": "Merge Branch...", "command.pull": "Pull", "command.pullRebase": "Pull (Rebase)", + "command.pullFrom": "Pull from...", "command.push": "Push", "command.pushTo": "Push to...", "command.sync": "Sync", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 3eaa99748b3..986cebb23ae 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -834,6 +834,31 @@ export class CommandCenter { await this.model.pullWithRebase(); } + @command('git.pullFrom') + async pullFrom(): Promise { + const remotes = this.model.remotes; + + if (remotes.length === 0) { + window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); + return; + } + + const picks = remotes.map(r => ({ label: r.name, description: r.url })); + const placeHolder = localize('pick remote pull', "Pick a remote to pull from"); + const pickRemote = await window.showQuickPick(picks, { placeHolder }); + + const pickBranch = await window.showInputBox({ + prompt: localize('pick pull branch', "Type a branch to pull"), + ignoreFocusOut: true + }); + + if (!pickRemote || !pickBranch) { + return; + } + + this.model.pullFrom(false, pickRemote.label, pickBranch); + } + @command('git.push') async push(): Promise { const remotes = this.model.remotes; @@ -1017,4 +1042,4 @@ export class CommandCenter { dispose(): void { this.disposables.forEach(d => d.dispose()); } -} \ No newline at end of file +} diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 28e918ef536..5a9641e77b6 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -290,6 +290,8 @@ function getGitErrorCode(stderr: string): string | undefined { return GitErrorCodes.CantAccessRemote; } else if (/branch '.+' is not fully merged/.test(stderr)) { return GitErrorCodes.BranchNotFullyMerged; + } else if (/Couldn\'t find remote ref/.test(stderr)) { + return GitErrorCodes.CantAccessRemote; } return void 0; @@ -748,13 +750,18 @@ export class Repository { } } - async pull(rebase?: boolean): Promise { + async pull(rebase?: boolean, remote?: string, branch?: string): Promise { const args = ['pull']; if (rebase) { args.push('-r'); } + if (remote && branch) { + args.push(remote); + args.push(branch); + } + try { await this.run(args); } catch (err) { diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index 073cb39fc8f..3670130c83e 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -501,6 +501,10 @@ export class Model implements Disposable { await this.run(Operation.Push, () => this.repository.push()); } + async pullFrom(rebase?: boolean, remote?: string, branch?: string): Promise { + await this.run(Operation.Pull, () => this.repository.pull(rebase, remote, branch)); + } + async pushTo(remote?: string, name?: string, setUpstream: boolean = false): Promise { await this.run(Operation.Push, () => this.repository.push(remote, name, setUpstream)); }