From c3ac916c32ded33c30082ea5de7693e28ca939a4 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Mon, 6 May 2024 15:30:38 +0200 Subject: [PATCH] link to cross-repo unified diff on github --- .../lib/components/ProjectSetupTarget.svelte | 4 +- app/src/lib/vbranches/types.ts | 51 ++++++++++++++++--- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/app/src/lib/components/ProjectSetupTarget.svelte b/app/src/lib/components/ProjectSetupTarget.svelte index b1a22b28f..7d8057d80 100644 --- a/app/src/lib/components/ProjectSetupTarget.svelte +++ b/app/src/lib/components/ProjectSetupTarget.svelte @@ -109,8 +109,8 @@

- You have branches from multiple remotes. If you want to specify a push target for creating - branches that is different from your production branch, change it here. + You have branches from multiple remotes. If you want to specify a remote for creating + branches that is different from the remote that your target branch is on, change it here.

{/if} diff --git a/app/src/lib/vbranches/types.ts b/app/src/lib/vbranches/types.ts index 146e1b2ec..c72fd40d1 100644 --- a/app/src/lib/vbranches/types.ts +++ b/app/src/lib/vbranches/types.ts @@ -347,23 +347,32 @@ export class BaseBranch { return this.lastFetchedMs ? new Date(this.lastFetchedMs) : undefined; } + get pushRepoBaseUrl(): string { + return this.cleanUrl(this.pushRemoteUrl); + } + get repoBaseUrl(): string { - if (this.pushRemoteUrl.startsWith('http')) { - return this.pushRemoteUrl.replace('.git', ''); + return this.cleanUrl(this.remoteUrl); + } + + // turn a git remote url into a web url (github, gitlab, bitbucket, etc) + private cleanUrl(url: string): string { + if (url.startsWith('http')) { + return url.replace('.git', '').trim(); } else { - return this.pushRemoteUrl.replace(':', '/').replace('git@', 'https://').replace('.git', ''); + return url.replace(':', '/').replace('git@', 'https://').replace('.git', '').trim(); } } commitUrl(commitId: string): string | undefined { // Different Git providers use different paths for the commit url: if (this.isBitBucket) { - return `${this.repoBaseUrl}/commits/${commitId}`; + return `${this.pushRepoBaseUrl}/commits/${commitId}`; } if (this.isGitlab) { - return `${this.repoBaseUrl}/-/commit/${commitId}`; + return `${this.pushRepoBaseUrl}/-/commit/${commitId}`; } - return `${this.repoBaseUrl}/commit/${commitId}`; + return `${this.pushRepoBaseUrl}/commit/${commitId}`; } get shortName() { @@ -374,11 +383,37 @@ export class BaseBranch { if (!upstreamBranchName) return undefined; const baseBranchName = this.branchName.split('/')[1]; const branchName = upstreamBranchName.split('/').slice(3).join('/'); + + if (this.pushRemoteName) { + if (this.isGitHub) { + // master...schacon:docs:Virtual-branch + const pushUsername = this.extractUsernameFromGitHubUrl(this.pushRemoteUrl); + const pushRepoName = this.extractRepoNameFromGitHubUrl(this.pushRemoteUrl); + return `${this.repoBaseUrl}/compare/${baseBranchName}...${pushUsername}:${pushRepoName}:${branchName}`; + } + } + if (this.isBitBucket) { - return `${this.repoBaseUrl.trim()}/branch/${branchName}?dest=${baseBranchName}`; + return `${this.repoBaseUrl}/branch/${branchName}?dest=${baseBranchName}`; } // The following branch path is good for at least Gitlab and Github: - return `${this.repoBaseUrl.trim()}/compare/${baseBranchName}...${branchName}`; + return `${this.repoBaseUrl}/compare/${baseBranchName}...${branchName}`; + } + + private extractUsernameFromGitHubUrl(url: string): string | null { + const regex = /github\.com[/:]([a-zA-Z0-9_-]+)\/.*/; + const match = url.match(regex); + return match ? match[1] : null; + } + + private extractRepoNameFromGitHubUrl(url: string): string | null { + const regex = /github\.com[/:]([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)/; + const match = url.match(regex); + return match ? match[2] : null; + } + + private get isGitHub(): boolean { + return this.repoBaseUrl.includes('github.com'); } private get isBitBucket(): boolean {