Fix first push for new worktrees
This commit is contained in:
@@ -166,6 +166,25 @@ describe("git-actions-policy", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps push available for a no-upstream Paseo worktree with local commits", () => {
|
||||||
|
const actions = buildGitActions(
|
||||||
|
createInput({
|
||||||
|
hasRemote: true,
|
||||||
|
isPaseoOwnedWorktree: true,
|
||||||
|
isOnBaseBranch: false,
|
||||||
|
aheadCount: 1,
|
||||||
|
aheadOfOrigin: null,
|
||||||
|
behindOfOrigin: null,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const pushAction = actions.secondary.find((action) => action.id === "push");
|
||||||
|
|
||||||
|
expect(pushAction).toMatchObject({
|
||||||
|
disabled: false,
|
||||||
|
unavailableMessage: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("shows update-from-base only on feature branches that are behind the base branch", () => {
|
it("shows update-from-base only on feature branches that are behind the base branch", () => {
|
||||||
const actions = buildGitActions(
|
const actions = buildGitActions(
|
||||||
createInput({
|
createInput({
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ export interface BuildGitActionsInput {
|
|||||||
baseRefLabel: string;
|
baseRefLabel: string;
|
||||||
aheadCount: number;
|
aheadCount: number;
|
||||||
behindBaseCount: number;
|
behindBaseCount: number;
|
||||||
aheadOfOrigin: number;
|
aheadOfOrigin: number | null;
|
||||||
behindOfOrigin: number;
|
behindOfOrigin: number | null;
|
||||||
shouldPromoteArchive: boolean;
|
shouldPromoteArchive: boolean;
|
||||||
shipDefault: "merge" | "pr";
|
shipDefault: "merge" | "pr";
|
||||||
runtime: Record<GitActionId, GitActionRuntimeState>;
|
runtime: Record<GitActionId, GitActionRuntimeState>;
|
||||||
@@ -489,11 +489,20 @@ function buildDisablePullRequestAutoMergeAction(input: BuildGitActionsInput): Gi
|
|||||||
}
|
}
|
||||||
|
|
||||||
function canPull(input: BuildGitActionsInput): boolean {
|
function canPull(input: BuildGitActionsInput): boolean {
|
||||||
return input.hasRemote && !input.hasUncommittedChanges && input.behindOfOrigin > 0;
|
return input.hasRemote && !input.hasUncommittedChanges && (input.behindOfOrigin ?? 0) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canPush(input: BuildGitActionsInput): boolean {
|
function canPush(input: BuildGitActionsInput): boolean {
|
||||||
return input.hasRemote && input.aheadOfOrigin > 0 && input.behindOfOrigin === 0;
|
return input.hasRemote && hasPushableCommits(input) && (input.behindOfOrigin ?? 0) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasPushableCommits(input: BuildGitActionsInput): boolean {
|
||||||
|
if ((input.aheadOfOrigin ?? 0) > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// No-upstream Paseo worktrees are first-pushable: the daemon push sets upstream with `git push -u`.
|
||||||
|
// Do not fold this into aheadOfOrigin; null also covers deleted/pruned upstream branches.
|
||||||
|
return input.isPaseoOwnedWorktree && input.aheadOfOrigin === null && input.aheadCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canMergeFromBase(input: BuildGitActionsInput): boolean {
|
function canMergeFromBase(input: BuildGitActionsInput): boolean {
|
||||||
@@ -587,6 +596,9 @@ function getPullUnavailableMessage(input: BuildGitActionsInput): string | undefi
|
|||||||
if (input.hasUncommittedChanges) {
|
if (input.hasUncommittedChanges) {
|
||||||
return "Pull isn't available while you have local changes so commit or stash them first";
|
return "Pull isn't available while you have local changes so commit or stash them first";
|
||||||
}
|
}
|
||||||
|
if (input.behindOfOrigin === null) {
|
||||||
|
return "Pull isn't available here because this branch is not connected to a remote yet";
|
||||||
|
}
|
||||||
if (input.behindOfOrigin === 0) {
|
if (input.behindOfOrigin === 0) {
|
||||||
return "Pull isn't available because this branch is already up to date";
|
return "Pull isn't available because this branch is already up to date";
|
||||||
}
|
}
|
||||||
@@ -597,10 +609,10 @@ function getPushUnavailableMessage(input: BuildGitActionsInput): string | undefi
|
|||||||
if (!input.hasRemote) {
|
if (!input.hasRemote) {
|
||||||
return "Push isn't available here because this branch is not connected to a remote yet";
|
return "Push isn't available here because this branch is not connected to a remote yet";
|
||||||
}
|
}
|
||||||
if (input.behindOfOrigin > 0) {
|
if ((input.behindOfOrigin ?? 0) > 0) {
|
||||||
return "Push isn't available yet because there are newer changes to bring in first";
|
return "Push isn't available yet because there are newer changes to bring in first";
|
||||||
}
|
}
|
||||||
if (input.aheadOfOrigin === 0) {
|
if (!hasPushableCommits(input)) {
|
||||||
return "Push isn't available because there is nothing new to send";
|
return "Push isn't available because there is nothing new to send";
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -613,13 +625,16 @@ function getPullAndPushUnavailableMessage(input: BuildGitActionsInput): string |
|
|||||||
if (input.hasUncommittedChanges) {
|
if (input.hasUncommittedChanges) {
|
||||||
return "Pull and push isn't available while you have local changes so commit or stash them first";
|
return "Pull and push isn't available while you have local changes so commit or stash them first";
|
||||||
}
|
}
|
||||||
|
if (input.behindOfOrigin === null) {
|
||||||
|
return "Pull and push isn't available because there are no incoming changes to pull first";
|
||||||
|
}
|
||||||
if (input.behindOfOrigin === 0 && input.aheadOfOrigin === 0) {
|
if (input.behindOfOrigin === 0 && input.aheadOfOrigin === 0) {
|
||||||
return "Pull and push isn't available because this branch is already in sync";
|
return "Pull and push isn't available because this branch is already in sync";
|
||||||
}
|
}
|
||||||
if (input.behindOfOrigin === 0) {
|
if (input.behindOfOrigin === 0) {
|
||||||
return "Pull and push isn't available because there are no incoming changes to pull first";
|
return "Pull and push isn't available because there are no incoming changes to pull first";
|
||||||
}
|
}
|
||||||
if (input.aheadOfOrigin === 0) {
|
if ((input.aheadOfOrigin ?? 0) === 0) {
|
||||||
return "Pull and push isn't available because there is nothing new to send after pulling";
|
return "Pull and push isn't available because there is nothing new to send after pulling";
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ interface DerivedGitActionsState {
|
|||||||
actionsDisabled: boolean;
|
actionsDisabled: boolean;
|
||||||
aheadCount: number;
|
aheadCount: number;
|
||||||
behindBaseCount: number;
|
behindBaseCount: number;
|
||||||
aheadOfOrigin: number;
|
aheadOfOrigin: number | null;
|
||||||
behindOfOrigin: number;
|
behindOfOrigin: number | null;
|
||||||
hasPullRequest: boolean;
|
hasPullRequest: boolean;
|
||||||
hasRemote: boolean;
|
hasRemote: boolean;
|
||||||
isPaseoOwnedWorktree: boolean;
|
isPaseoOwnedWorktree: boolean;
|
||||||
@@ -71,16 +71,16 @@ interface DerivedGitActionsState {
|
|||||||
interface GitCommitCounts {
|
interface GitCommitCounts {
|
||||||
aheadCount: number;
|
aheadCount: number;
|
||||||
behindBaseCount: number;
|
behindBaseCount: number;
|
||||||
aheadOfOrigin: number;
|
aheadOfOrigin: number | null;
|
||||||
behindOfOrigin: number;
|
behindOfOrigin: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractGitCommitCounts(gitStatus: CheckoutStatusPayload | null): GitCommitCounts {
|
function extractGitCommitCounts(gitStatus: CheckoutStatusPayload | null): GitCommitCounts {
|
||||||
return {
|
return {
|
||||||
aheadCount: gitStatus?.aheadBehind?.ahead ?? 0,
|
aheadCount: gitStatus?.aheadBehind?.ahead ?? 0,
|
||||||
behindBaseCount: gitStatus?.aheadBehind?.behind ?? 0,
|
behindBaseCount: gitStatus?.aheadBehind?.behind ?? 0,
|
||||||
aheadOfOrigin: gitStatus?.aheadOfOrigin ?? 0,
|
aheadOfOrigin: gitStatus?.aheadOfOrigin ?? null,
|
||||||
behindOfOrigin: gitStatus?.behindOfOrigin ?? 0,
|
behindOfOrigin: gitStatus?.behindOfOrigin ?? null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user