44 *--------------------------------------------------------------------------------------------*/
55
66import * as vscode from 'vscode' ;
7- import { API as GitAPI , Repository } from './typings/git' ;
7+ import { API as GitAPI , RefType , Repository } from './typings/git' ;
88import { getRepositoryFromUrl } from './util' ;
99
1010export function isFileInRepo ( repository : Repository , file : vscode . Uri ) : boolean {
@@ -129,7 +129,7 @@ export function encodeURIComponentExceptSlashes(path: string) {
129129 return path . split ( '/' ) . map ( ( segment ) => encodeURIComponent ( segment ) ) . join ( '/' ) ;
130130}
131131
132- export function getLink ( gitAPI : GitAPI , useSelection : boolean , hostPrefix ?: string , linkType : 'permalink' | 'headlink' = 'permalink' , context ?: LinkContext , useRange ?: boolean ) : string | undefined {
132+ export async function getLink ( gitAPI : GitAPI , useSelection : boolean , hostPrefix ?: string , linkType : 'permalink' | 'headlink' = 'permalink' , context ?: LinkContext , useRange ?: boolean ) : Promise < string | undefined > {
133133 hostPrefix = hostPrefix ?? 'https://github.com' ;
134134 const fileAndPosition = getFileAndPosition ( context ) ;
135135 if ( ! fileAndPosition ) {
@@ -142,6 +142,9 @@ export function getLink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: stri
142142 if ( ! gitRepo ) {
143143 return ;
144144 }
145+
146+ await ensurePublished ( gitRepo , uri ) ;
147+
145148 let repo : { owner : string ; repo : string } | undefined ;
146149 gitRepo . state . remotes . find ( remote => {
147150 if ( remote . fetchUrl ) {
@@ -182,3 +185,54 @@ export function getBranchLink(url: string, branch: string, hostPrefix: string =
182185export function getVscodeDevHost ( ) : string {
183186 return `https://${ vscode . env . appName . toLowerCase ( ) . includes ( 'insiders' ) ? 'insiders.' : '' } vscode.dev/github` ;
184187}
188+
189+ export async function ensurePublished ( repository : Repository , file : vscode . Uri ) {
190+ if ( ( repository . state . HEAD ?. type === RefType . Head || repository . state . HEAD ?. type === RefType . Tag )
191+ // If HEAD is not published, make sure it is
192+ && ! repository ?. state . HEAD ?. upstream
193+ ) {
194+ const publishBranch = vscode . l10n . t ( 'Publish Branch' ) ;
195+ const selection = await vscode . window . showInformationMessage (
196+ vscode . l10n . t ( 'The current branch is not published to the remote. Would you like to publish your branch before copying a link?' ) ,
197+ { modal : true } ,
198+ publishBranch
199+ ) ;
200+ if ( selection !== publishBranch ) {
201+ throw new vscode . CancellationError ( ) ;
202+ }
203+
204+ await vscode . commands . executeCommand ( 'git.publish' ) ;
205+ }
206+
207+ const uncommittedChanges = [ ...repository . state . workingTreeChanges , ...repository . state . indexChanges ] ;
208+ if ( uncommittedChanges . find ( ( c ) => c . uri . toString ( ) === file . toString ( ) ) ) {
209+ const commitChanges = vscode . l10n . t ( 'Commit Changes' ) ;
210+ const copyAnyway = vscode . l10n . t ( 'Copy Anyway' ) ;
211+ const selection = await vscode . window . showWarningMessage (
212+ vscode . l10n . t ( 'The current file has uncommitted changes. Please commit your changes before copying a link.' ) ,
213+ { modal : true } ,
214+ commitChanges ,
215+ copyAnyway
216+ ) ;
217+
218+ if ( selection !== copyAnyway ) {
219+ // Focus the SCM view
220+ vscode . commands . executeCommand ( 'workbench.view.scm' ) ;
221+ throw new vscode . CancellationError ( ) ;
222+ }
223+ } else if ( repository . state . HEAD ?. ahead ) {
224+ const pushCommits = vscode . l10n . t ( 'Push Commits' ) ;
225+ const selection = await vscode . window . showInformationMessage (
226+ vscode . l10n . t ( 'The current branch has unpublished commits. Would you like to push your commits before copying a link?' ) ,
227+ { modal : true } ,
228+ pushCommits
229+ ) ;
230+ if ( selection !== pushCommits ) {
231+ throw new vscode . CancellationError ( ) ;
232+ }
233+
234+ await repository . push ( ) ;
235+ }
236+
237+ await repository . status ( ) ;
238+ }
0 commit comments