Skip to content

Commit 27090c9

Browse files
nzaytsevd13
authored andcommitted
Adds a way to force push from the Graph
- add sync button and action - await for pull before run push - add split button dropdown
1 parent 8969492 commit 27090c9

File tree

9 files changed

+298
-142
lines changed

9 files changed

+298
-142
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1111
- Adds [Cursor](https://cursor.so) support — closes [#3222](https://github.com/gitkraken/vscode-gitlens/issues/3222)
1212
- Adds monospace formatting in commit messages — closes [#2350](https://github.com/gitkraken/vscode-gitlens/issues/2350)
1313
- Adds a new `${authorFirst}` and `${authorLast}` commit formatting tokens that can be used in inline blame, commit hovers, etc — closes [#2980](https://github.com/gitkraken/vscode-gitlens/issues/2980)
14+
- Adds a way to force push from the Graph
1415

1516
### Changed
1617

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8825,6 +8825,13 @@
88258825
"icon": "$(gitlens-repo-pull)",
88268826
"enablement": "!operationInProgress"
88278827
},
8828+
{
8829+
"command": "gitlens.graph.sync",
8830+
"title": "Pull",
8831+
"category": "GitLens",
8832+
"icon": "$(gitlens-repo-sync)",
8833+
"enablement": "!operationInProgress"
8834+
},
88288835
{
88298836
"command": "gitlens.graph.fetch",
88308837
"title": "Fetch",
@@ -11995,6 +12002,10 @@
1199512002
"command": "gitlens.graph.pull",
1199612003
"when": "false"
1199712004
},
12005+
{
12006+
"command": "gitlens.graph.sync",
12007+
"when": "false"
12008+
},
1199812009
{
1199912010
"command": "gitlens.graph.fetch",
1200012011
"when": "false"
@@ -15577,6 +15588,11 @@
1557715588
"when": "gitlens:repos:withRemotes && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && webviewItem =~ /gitlens:branch\\b(?=.*?\\b\\+(behind|tracking)\\b)(?!.*?\\b\\+closed\\b)/",
1557815589
"group": "1_gitlens_actions@2"
1557915590
},
15591+
{
15592+
"command": "gitlens.graph.sync",
15593+
"when": "false",
15594+
"group": "1_gitlens_actions@2"
15595+
},
1558015596
{
1558115597
"command": "gitlens.graph.fetch",
1558215598
"when": "gitlens:repos:withRemotes && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && webviewItem =~ /gitlens:branch\\b(?=.*?\\b\\+(remote|tracking)\\b)(?!.*?\\b\\+closed\\b)/",
@@ -15832,6 +15848,11 @@
1583215848
"when": "webviewItem =~ /gitlens:upstreamStatus\\b/",
1583315849
"group": "1_gitlens_actions@2"
1583415850
},
15851+
{
15852+
"command": "gitlens.graph.sync",
15853+
"when": "sync",
15854+
"group": "1_gitlens_actions@2"
15855+
},
1583515856
{
1583615857
"command": "gitlens.graph.fetch",
1583715858
"when": "webviewItem =~ /gitlens:upstreamStatus\\b/",

src/commands/git/pull.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ export class PullGitCommand extends QuickCommand<State> {
133133
state.flags = result;
134134
}
135135

136+
await this.execute(state as PullStepState);
136137
endSteps(state);
137-
void this.execute(state as PullStepState);
138138
}
139139

140140
return state.counter < 0 ? StepResultBreak : undefined;

src/plus/webviews/graph/graphWebview.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
447447
this.host.registerWebviewCommand('gitlens.graph.push', this.push),
448448
this.host.registerWebviewCommand('gitlens.graph.pull', this.pull),
449449
this.host.registerWebviewCommand('gitlens.graph.fetch', this.fetch),
450+
this.host.registerWebviewCommand('gitlens.graph.sync', this.sync),
450451
this.host.registerWebviewCommand('gitlens.graph.publishBranch', this.publishBranch),
451452
this.host.registerWebviewCommand('gitlens.graph.switchToAnotherBranch', this.switchToAnother),
452453

@@ -2855,6 +2856,13 @@ export class GraphWebviewProvider implements WebviewProvider<State, State, Graph
28552856
void RepoActions.fetch(this.repository, ref);
28562857
}
28572858

2859+
@log()
2860+
private async sync(item?: GraphItemContext) {
2861+
const ref = item != null ? this.getGraphItemRef(item, 'branch') : undefined;
2862+
await RepoActions.pull(this.repository, ref);
2863+
void RepoActions.push(this.repository, undefined, ref);
2864+
}
2865+
28582866
@log()
28592867
private pull(item?: GraphItemContext) {
28602868
const ref = item != null ? this.getGraphItemRef(item, 'branch') : undefined;

src/webviews/apps/plus/graph/GraphWrapper.tsx

Lines changed: 7 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ import { GlSearchBox } from '../../shared/components/search/react';
8686
import type { SearchNavigationEventDetail } from '../../shared/components/search/search-box';
8787
import type { DateTimeFormat } from '../../shared/date';
8888
import { formatDate, fromNow } from '../../shared/date';
89+
import { GitActionsButtons } from './actions/gitActionsButtons';
8990
import { GlGraphHover } from './hover/graphHover.react';
9091
import type { GraphMinimapDaySelectedEventDetail } from './minimap/minimap';
9192
import { GlGraphMinimapContainer } from './minimap/minimap-container.react';
@@ -991,146 +992,6 @@ export function GraphWrapper({
991992
onChangeSelection?.(rows);
992993
};
993994

994-
const renderFetchAction = () => {
995-
let action: 'fetch' | 'pull' | 'push' = 'fetch';
996-
let icon = 'repo-fetch';
997-
let label = 'Fetch';
998-
let isBehind = false;
999-
let isAhead = false;
1000-
1001-
const remote = branchState?.upstream ? (
1002-
<>
1003-
<span className="md-code">{branchState?.upstream}</span>
1004-
</>
1005-
) : (
1006-
'remote'
1007-
);
1008-
1009-
let tooltip;
1010-
if (branchState) {
1011-
isAhead = branchState.ahead > 0;
1012-
isBehind = branchState.behind > 0;
1013-
1014-
const branchPrefix = (
1015-
<>
1016-
<span className="md-code">{branchName}</span> is
1017-
</>
1018-
);
1019-
1020-
if (isBehind) {
1021-
action = 'pull';
1022-
icon = 'repo-pull';
1023-
label = 'Pull';
1024-
tooltip = (
1025-
<>
1026-
Pull {pluralize('commit', branchState.behind)} from {remote}
1027-
{branchState.provider?.name ? ` on ${branchState.provider?.name}` : ''}
1028-
</>
1029-
);
1030-
if (isAhead) {
1031-
tooltip = (
1032-
<>
1033-
{tooltip}
1034-
<hr />
1035-
{branchPrefix} {pluralize('commit', branchState.behind)} behind and{' '}
1036-
{pluralize('commit', branchState.ahead)} ahead of {remote}
1037-
{branchState.provider?.name ? ` on ${branchState.provider?.name}` : ''}
1038-
</>
1039-
);
1040-
} else {
1041-
tooltip = (
1042-
<>
1043-
{tooltip}
1044-
<hr />
1045-
{branchPrefix} {pluralize('commit', branchState.behind)} behind {remote}
1046-
{branchState.provider?.name ? ` on ${branchState.provider?.name}` : ''}
1047-
</>
1048-
);
1049-
}
1050-
} else if (isAhead) {
1051-
action = 'push';
1052-
icon = 'repo-push';
1053-
label = 'Push';
1054-
tooltip = (
1055-
<>
1056-
Push {pluralize('commit', branchState.ahead)} to {remote}
1057-
{branchState.provider?.name ? ` on ${branchState.provider?.name}` : ''}
1058-
<hr />
1059-
{branchPrefix} {pluralize('commit', branchState.ahead)} ahead of {remote}
1060-
</>
1061-
);
1062-
}
1063-
}
1064-
1065-
const lastFetchedDate = lastFetched && new Date(lastFetched);
1066-
const fetchedText = lastFetchedDate && lastFetchedDate.getTime() !== 0 ? fromNow(lastFetchedDate) : undefined;
1067-
1068-
return (
1069-
<>
1070-
{(isBehind || isAhead) && (
1071-
<GlTooltip placement="bottom">
1072-
<a
1073-
href={createWebviewCommandLink(
1074-
`gitlens.graph.${action}`,
1075-
state.webviewId,
1076-
state.webviewInstanceId,
1077-
)}
1078-
className={`action-button${isBehind ? ' is-behind' : ''}${isAhead ? ' is-ahead' : ''}`}
1079-
>
1080-
<span className={`glicon glicon-${icon} action-button__icon`}></span>
1081-
{label}
1082-
{(isAhead || isBehind) && (
1083-
<span>
1084-
<span className="pill action-button__pill">
1085-
{isBehind && (
1086-
<span>
1087-
{branchState!.behind}
1088-
<span className="codicon codicon-arrow-down"></span>
1089-
</span>
1090-
)}
1091-
{isAhead && (
1092-
<span>
1093-
{isBehind && <>&nbsp;&nbsp;</>}
1094-
{branchState!.ahead}
1095-
<span className="codicon codicon-arrow-up"></span>
1096-
</span>
1097-
)}
1098-
</span>
1099-
</span>
1100-
)}
1101-
</a>
1102-
<div slot="content" style={{ whiteSpace: 'break-spaces' }}>
1103-
{tooltip}
1104-
{fetchedText && (
1105-
<>
1106-
<hr /> Last fetched {fetchedText}
1107-
</>
1108-
)}
1109-
</div>
1110-
</GlTooltip>
1111-
)}
1112-
<GlTooltip placement="bottom">
1113-
<a
1114-
href={createWebviewCommandLink('gitlens.graph.fetch', state.webviewId, state.webviewInstanceId)}
1115-
className="action-button"
1116-
>
1117-
<span className="glicon glicon-repo-fetch action-button__icon"></span>
1118-
Fetch {fetchedText && <span className="action-button__small">({fetchedText})</span>}
1119-
</a>
1120-
<span slot="content" style={{ whiteSpace: 'break-spaces' }}>
1121-
Fetch from {remote}
1122-
{branchState?.provider?.name ? ` on ${branchState.provider?.name}` : ''}
1123-
{fetchedText && (
1124-
<>
1125-
<hr /> Last fetched {fetchedText}
1126-
</>
1127-
)}
1128-
</span>
1129-
</GlTooltip>
1130-
</>
1131-
);
1132-
};
1133-
1134995
return (
1135996
<>
1136997
<header className="titlebar graph-app__header">
@@ -1274,7 +1135,12 @@ export function GraphWrapper({
12741135
<span>
12751136
<span className="codicon codicon-chevron-right"></span>
12761137
</span>
1277-
{renderFetchAction()}
1138+
<GitActionsButtons
1139+
branchName={branchName}
1140+
branchState={branchState}
1141+
lastFetched={lastFetched}
1142+
state={state}
1143+
/>
12781144
</>
12791145
)}
12801146
</div>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { ReactNode } from 'react';
2+
import React from 'react';
3+
import type { BranchState, State } from '../../../../../plus/webviews/graph/protocol';
4+
import { createWebviewCommandLink } from '../../../../../system/webview';
5+
import { GlTooltip } from '../../../shared/components/overlays/tooltip.react';
6+
7+
export const FetchButton = ({
8+
state,
9+
fetchedText,
10+
branchState,
11+
remote,
12+
}: {
13+
branchState: BranchState | undefined;
14+
state: State;
15+
fetchedText: string | undefined;
16+
remote: ReactNode;
17+
}) => {
18+
return (
19+
<GlTooltip placement="bottom">
20+
<a
21+
href={createWebviewCommandLink('gitlens.graph.fetch', state.webviewId, state.webviewInstanceId)}
22+
className="action-button"
23+
>
24+
<span className="glicon glicon-repo-fetch action-button__icon"></span>
25+
Fetch {fetchedText && <span className="action-button__small">({fetchedText})</span>}
26+
</a>
27+
<span slot="content" style={{ whiteSpace: 'break-spaces' }}>
28+
Fetch from {remote}
29+
{branchState?.provider?.name ? ` on ${branchState.provider?.name}` : ''}
30+
{fetchedText && (
31+
<>
32+
<hr /> Last fetched {fetchedText}
33+
</>
34+
)}
35+
</span>
36+
</GlTooltip>
37+
);
38+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import type { BranchState, State } from '../../../../../plus/webviews/graph/protocol';
3+
import { fromNow } from '../../../../../system/date';
4+
import { FetchButton } from './fetchButton';
5+
import { SyncButton } from './syncButton';
6+
7+
export const GitActionsButtons = ({
8+
branchState,
9+
branchName,
10+
lastFetched,
11+
state,
12+
}: {
13+
branchState: BranchState | undefined;
14+
branchName: string | undefined;
15+
lastFetched: Date | undefined;
16+
state: State;
17+
}) => {
18+
const remote = branchState?.upstream ? <span className="md-code">{branchState?.upstream}</span> : 'remote';
19+
20+
const lastFetchedDate = lastFetched && new Date(lastFetched);
21+
const fetchedText = lastFetchedDate && lastFetchedDate.getTime() !== 0 ? fromNow(lastFetchedDate) : undefined;
22+
23+
return (
24+
<>
25+
<SyncButton
26+
branchState={branchState}
27+
state={state}
28+
fetchedText={fetchedText}
29+
branchName={branchName}
30+
remote={remote}
31+
/>
32+
<FetchButton branchState={branchState} fetchedText={fetchedText} remote={remote} state={state} />
33+
</>
34+
);
35+
};

0 commit comments

Comments
 (0)