From 21325bef88d6763f1ff0db4ab2c3f969bb0b6569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20H=C3=BCbelbauer?= Date: Thu, 8 Mar 2018 22:02:29 +0100 Subject: [PATCH] Hide ahead push arrow if remote push URL is no_push Closes Microsoft/vscode#45271 --- extensions/git/src/commands.ts | 4 +-- extensions/git/src/git.ts | 43 +++++++++++++++++++++++++------- extensions/git/src/repository.ts | 18 +++++++++---- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 7cf5d096d7e..b10670b1c74 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1314,7 +1314,7 @@ export class CommandCenter { return; } - const remotePicks = remotes.map(r => ({ label: r.name, description: r.url })); + const remotePicks = remotes.filter(r => r.fetchUrl !== undefined).map(r => ({ label: r.name, description: r.fetchUrl! })); const placeHolder = localize('pick remote pull repo', "Pick a remote to pull the branch from"); const remotePick = await window.showQuickPick(remotePicks, { placeHolder }); @@ -1421,7 +1421,7 @@ export class CommandCenter { } const branchName = repository.HEAD.name; - const picks = remotes.map(r => ({ label: r.name, description: r.url })); + const picks = remotes.filter(r => r.pushUrl !== undefined).map(r => ({ label: r.name, description: r.pushUrl! })); const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); const pick = await window.showQuickPick(picks, { placeHolder }); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 094bf3fe577..03affd2dea7 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -13,7 +13,7 @@ import * as which from 'which'; import { EventEmitter } from 'events'; import iconv = require('iconv-lite'); import * as filetype from 'file-type'; -import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; +import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; import { CancellationToken } from 'vscode'; const readfile = denodeify(fs.readFile); @@ -32,7 +32,9 @@ export interface IFileStatus { export interface Remote { name: string; - url: string; + fetchUrl?: string; + pushUrl?: string; + canPush: boolean; } export interface Stash { @@ -1199,14 +1201,37 @@ export class Repository { async getRemotes(): Promise { const result = await this.run(['remote', '--verbose']); - const regex = /^([^\s]+)\s+([^\s]+)\s/; - const rawRemotes = result.stdout.trim().split('\n') - .filter(b => !!b) - .map(line => regex.exec(line) as RegExpExecArray) - .filter(g => !!g) - .map((groups: RegExpExecArray) => ({ name: groups[1], url: groups[2] })); + const remotes: Remote[] = []; + const lines = result.stdout.trim().split('\n').filter(l => !!l); + for (const line of lines) { + const parts = line.split(/\s/); + let remote = remotes.find(r => r.name === parts[0]); + if (!remote) { + remote = { name: parts[0], canPush: true }; + remotes.push(remote); + } - return uniqBy(rawRemotes, remote => remote.name); + switch (parts[2]) { + case '(fetch)': { + remote.fetchUrl = parts[1]; + break; + } + case '(push)': { + remote.pushUrl = parts[1]; + break; + } + default: { + remote.fetchUrl = parts[1]; + remote.pushUrl = parts[1]; + break; + } + } + + // https://github.com/Microsoft/vscode/issues/45271 + remote.canPush = remote.pushUrl !== undefined && remote.pushUrl !== 'no_push'; + } + + return remotes; } async getBranch(name: string): Promise { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 7586abee7eb..2b214d13a6b 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -789,23 +789,24 @@ export class Repository implements Disposable { } private async _sync(head: Branch, rebase: boolean): Promise { - let remote: string | undefined; + let remoteName: string | undefined; let pullBranch: string | undefined; let pushBranch: string | undefined; if (head.name && head.upstream) { - remote = head.upstream.remote; + remoteName = head.upstream.remote; pullBranch = `${head.upstream.name}`; pushBranch = `${head.name}:${head.upstream.name}`; } await this.run(Operation.Sync, async () => { - await this.repository.pull(rebase, remote, pullBranch); + await this.repository.pull(rebase, remoteName, pullBranch); - const shouldPush = this.HEAD && typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true; + const remote = this.remotes.find(r => r.name === remoteName); + const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true) && (!remote || remote.canPush); if (shouldPush) { - await this.repository.push(remote, pushBranch); + await this.repository.push(remoteName, pushBranch); } }); } @@ -1154,6 +1155,13 @@ export class Repository implements Disposable { return ''; } + const remoteName = this.HEAD && this.HEAD.remote || this.HEAD.upstream.remote; + const remote = this.remotes.find(r => r.name === remoteName); + + if (remote && !remote.canPush) { + return `${this.HEAD.behind}↓`; + } + return `${this.HEAD.behind}↓ ${this.HEAD.ahead}↑`; }