feat(app): add pull-and-push git action (#627)

Combines `git pull` followed by `git push` behind a single action in the
git actions split-button. Push is skipped if pull fails, and errors are
surfaced through the same toast pathway as the existing pull and push
actions.
This commit is contained in:
Mohamed Boudra
2026-04-30 12:56:09 +08:00
committed by GitHub
parent 3f2c33ad46
commit f286a5beea
7 changed files with 235 additions and 2 deletions
@@ -6,6 +6,7 @@ export type GitActionId =
| "commit"
| "pull"
| "push"
| "pull-and-push"
| "pr"
| "merge-branch"
| "merge-from-base"
@@ -56,7 +57,7 @@ export interface BuildGitActionsInput {
runtime: Record<GitActionId, GitActionRuntimeState>;
}
const REMOTE_ACTION_IDS: GitActionId[] = ["pull", "push"];
const REMOTE_ACTION_IDS: GitActionId[] = ["pull", "push", "pull-and-push"];
const FEATURE_ACTION_IDS: GitActionId[] = ["merge-from-base", "merge-branch", "pr"];
export function buildGitActions(input: BuildGitActionsInput): GitActions {
@@ -101,6 +102,20 @@ export function buildGitActions(input: BuildGitActionsInput): GitActions {
handler: input.runtime.push.handler,
});
allActions.set("pull-and-push", {
id: "pull-and-push",
label: "Pull and push",
pendingLabel: "Pulling and pushing...",
successLabel: "Pulled and pushed",
disabled: input.runtime["pull-and-push"].disabled,
status: input.runtime["pull-and-push"].status,
unavailableMessage: input.runtime["pull-and-push"].disabled
? undefined
: getPullAndPushUnavailableMessage(input),
icon: input.runtime["pull-and-push"].icon,
handler: input.runtime["pull-and-push"].handler,
});
allActions.set("pr", buildPrAction(input));
allActions.set("merge-branch", {
@@ -265,6 +280,19 @@ function getPushUnavailableMessage(input: BuildGitActionsInput): string | undefi
return undefined;
}
function getPullAndPushUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.hasRemote) {
return "Pull and push isn't available here because this branch is not connected to a remote yet";
}
if (input.hasUncommittedChanges) {
return "Pull and push isn't available while you have local changes so commit or stash them first";
}
if (input.behindOfOrigin === 0 && input.aheadOfOrigin === 0) {
return "Pull and push isn't available because this branch is already in sync";
}
return undefined;
}
function getCreatePrUnavailableMessage(input: BuildGitActionsInput): string | undefined {
if (!input.githubFeaturesEnabled) {
return "Create PR isn't available right now because GitHub isn't connected";