diff --git a/src/plus/webviews/graph/graphWebview.ts b/src/plus/webviews/graph/graphWebview.ts index 4d400bd..b0c832a 100644 --- a/src/plus/webviews/graph/graphWebview.ts +++ b/src/plus/webviews/graph/graphWebview.ts @@ -1743,8 +1743,11 @@ export class GraphWebviewProvider implements WebviewProvider { const branch = await this.repository.getBranch(); let branchState; if (branch != null) { + const remote = await branch.getRemote(); branchState = { ...branch.state, + upstream: branch.upstream?.name, + provider: remote?.provider?.name, }; } diff --git a/src/plus/webviews/graph/protocol.ts b/src/plus/webviews/graph/protocol.ts index 6e2f1b8..bcf5c5e 100644 --- a/src/plus/webviews/graph/protocol.ts +++ b/src/plus/webviews/graph/protocol.ts @@ -89,7 +89,7 @@ export interface State { selectedRepository?: string; selectedRepositoryVisibility?: RepositoryVisibility; branchName?: string; - branchState?: GitTrackingState; + branchState?: BranchState; lastFetched?: Date; selectedRows?: GraphSelectedRows; subscription?: Subscription; @@ -122,6 +122,11 @@ export interface State { theming?: { cssVariables: CssVariables; themeOpacityFactor: number }; } +export interface BranchState extends GitTrackingState { + upstream?: string; + provider?: string; +} + export type GraphWorkingTreeStats = WorkDirStats; export interface GraphPaging { diff --git a/src/webviews/apps/plus/graph/GraphWrapper.tsx b/src/webviews/apps/plus/graph/GraphWrapper.tsx index 8026a34..2ec8d90 100644 --- a/src/webviews/apps/plus/graph/GraphWrapper.tsx +++ b/src/webviews/apps/plus/graph/GraphWrapper.tsx @@ -193,6 +193,7 @@ export function GraphWrapper({ const [repo, setRepo] = useState( repos.find(item => item.path === state.selectedRepository), ); + const [branchState, setBranchState] = useState(state.branchState); const [selectedRows, setSelectedRows] = useState(state.selectedRows); const [activeRow, setActiveRow] = useState(state.activeRow); const [activeDay, setActiveDay] = useState(state.activeDay); @@ -320,6 +321,7 @@ export function GraphWrapper({ setContext(state.context); setAvatars(state.avatars ?? {}); setDownstreams(state.downstreams ?? {}); + setBranchState(state.branchState); setRefsMetadata(state.refsMetadata); setPagingHasMore(state.paging?.hasMore ?? false); setRepos(state.repositories ?? []); @@ -1095,21 +1097,32 @@ export function GraphWrapper({ let icon = 'sync'; let label = 'Fetch'; let action = 'command:gitlens.graph.fetch'; - - const isBehind = state.branchState && state.branchState.behind > 0; - const isAhead = state.branchState && state.branchState.ahead > 0; - if (isBehind) { - action = 'command:gitlens.graph.pull'; - icon = 'arrow-down'; - label = 'Pull'; - } else if (isAhead) { - action = 'command:gitlens.graph.push'; - icon = 'arrow-up'; - label = 'Push'; + let tooltip; + let isBehind = false; + let isAhead = false; + + if (branchState) { + isBehind = branchState.behind > 0; + isAhead = branchState.ahead > 0; + tooltip = `Branch ${branchName} is`; + if (isBehind) { + action = 'command:gitlens.graph.pull'; + icon = 'arrow-down'; + label = 'Pull'; + tooltip += ` ${pluralize('commit', branchState.behind)} behind of`; + } else if (isAhead) { + action = 'command:gitlens.graph.push'; + icon = 'arrow-up'; + label = 'Push'; + tooltip += ` ${pluralize('commit', branchState.ahead)} ahead of`; + } else { + tooltip += ' up to date with'; + } + tooltip += ` ${branchState.upstream}${branchState.provider ? ` on ${branchState.provider}` : ''}`; } return ( - + {label} {fetchedText && (Last fetched {fetchedText})} @@ -1117,19 +1130,13 @@ export function GraphWrapper({ {isAhead && ( - - {state.branchState!.ahead} + + {branchState!.ahead} )} {isBehind && ( - - {state.branchState!.behind} + + {branchState!.behind} )}