diff --git a/apps/desktop/src/lib/baseBranch/baseBranch.ts b/apps/desktop/src/lib/baseBranch/baseBranch.ts index cf54c6c7f..901b6ab6b 100644 --- a/apps/desktop/src/lib/baseBranch/baseBranch.ts +++ b/apps/desktop/src/lib/baseBranch/baseBranch.ts @@ -17,6 +17,10 @@ export class BaseBranch { @Type(() => Commit) recentCommits!: Commit[]; lastFetchedMs?: number; + conflicted!: boolean; + diverged!: boolean; + divergedAhead!: string[]; + divergedBehind!: string[]; actualPushRemoteName(): string { return this.pushRemoteName || this.remoteName; diff --git a/apps/desktop/src/lib/baseBranch/baseBranchService.ts b/apps/desktop/src/lib/baseBranch/baseBranchService.ts index 220fec1dd..cdd796a81 100644 --- a/apps/desktop/src/lib/baseBranch/baseBranchService.ts +++ b/apps/desktop/src/lib/baseBranch/baseBranchService.ts @@ -67,6 +67,27 @@ export class BaseBranchService { }); await this.fetchFromRemotes(); } + + async push(withForce?: boolean) { + this.loading.set(true); + try { + await invoke('push_base_branch', { + projectId: this.projectId, + withForce + }); + } catch (err: any) { + if (err.code === Code.DefaultTargetNotFound) { + // Swallow this error since user should be taken to project setup page + return; + } else if (err.code === Code.ProjectsGitAuth) { + showError('Failed to authenticate', err); + } else { + showError('Failed to push', err); + } + console.error(err); + } + await this.fetchFromRemotes(); + } } export async function getRemoteBranches( diff --git a/apps/desktop/src/lib/commit/CommitAction.svelte b/apps/desktop/src/lib/commit/CommitAction.svelte index 74a49ea73..fdc900b17 100644 --- a/apps/desktop/src/lib/commit/CommitAction.svelte +++ b/apps/desktop/src/lib/commit/CommitAction.svelte @@ -4,11 +4,12 @@ interface Props { bottomBorder?: boolean; + backgroundColor?: boolean; lines: Snippet; action: Snippet; } - const { bottomBorder = true, lines, action }: Props = $props(); + const { bottomBorder = true, backgroundColor = true, lines, action }: Props = $props(); let isNotInViewport = $state(false); @@ -18,6 +19,7 @@ class:not-in-viewport={!isNotInViewport} class:sticky-z-index={!isNotInViewport} class:bottom-border={bottomBorder} + class:background-color={backgroundColor} use:intersectionObserver={{ callback: (entry) => { if (entry?.isIntersecting) { @@ -46,12 +48,15 @@ position: relative; display: flex; - background-color: var(--clr-bg-2); overflow: hidden; transition: border-top var(--transition-fast); } + .background-color { + background-color: var(--clr-bg-2); + } + .action { display: flex; flex-direction: column; diff --git a/apps/desktop/src/lib/commit/CommitCard.svelte b/apps/desktop/src/lib/commit/CommitCard.svelte index bb1ac0969..87cb4e396 100644 --- a/apps/desktop/src/lib/commit/CommitCard.svelte +++ b/apps/desktop/src/lib/commit/CommitCard.svelte @@ -142,7 +142,7 @@ modeService!.enterEditMode(commit.id, branch!.refname); } - $: conflicted = commit instanceof DetailedCommit && commit.conflicted; + $: conflicted = commit.conflicted; diff --git a/apps/desktop/src/lib/commit/CommitList.svelte b/apps/desktop/src/lib/commit/CommitList.svelte index deccdd4b8..6db6deafd 100644 --- a/apps/desktop/src/lib/commit/CommitList.svelte +++ b/apps/desktop/src/lib/commit/CommitList.svelte @@ -18,7 +18,7 @@ import { Commit, DetailedCommit, VirtualBranch } from '$lib/vbranches/types'; import Button from '@gitbutler/ui/Button.svelte'; import LineGroup from '@gitbutler/ui/commitLines/LineGroup.svelte'; - import { LineManagerFactory } from '@gitbutler/ui/commitLines/lineManager'; + import { LineManagerFactory, LineSpacer } from '@gitbutler/ui/commitLines/lineManager'; import type { Snippet } from 'svelte'; import { goto } from '$app/navigation'; @@ -52,14 +52,6 @@ const reorderDropzoneManagerFactory = getContext(ReorderDropzoneManagerFactory); const gitHost = getGitHost(); - // TODO: Why does eslint-svelte-plugin complain about enum? - // eslint-disable-next-line svelte/valid-compile - enum LineSpacer { - Remote = 'remote-spacer', - Local = 'local-spacer', - LocalAndRemote = 'local-and-remote-spacer' - } - const mappedRemoteCommits = $derived( remoteCommits.length > 0 ? [...remoteCommits.map(transformAnyCommit), { id: LineSpacer.Remote }] diff --git a/apps/desktop/src/lib/components/BaseBranch.svelte b/apps/desktop/src/lib/components/BaseBranch.svelte index 1fe91d35d..936362165 100644 --- a/apps/desktop/src/lib/components/BaseBranch.svelte +++ b/apps/desktop/src/lib/components/BaseBranch.svelte @@ -1,78 +1,236 @@ -
-
- There {multiple ? 'are' : 'is'} - {base.upstreamCommits.length} unmerged upstream - {multiple ? 'commits' : 'commit'} +{#if base.diverged} +
+ {#if !onlyLocalAhead} + + + Your local target branch has diverged from upstream. +
+ Target branch is + + {`ahead by ${base.divergedAhead.length}`} + + commits and + + {`behind by ${base.divergedBehind.length}`} + + commits +
+
+ {:else} + + + Your local target branch is + + {`ahead by ${base.divergedAhead.length}`} + + commits + + + {/if}
+{/if} + +{#if !base.diverged && base.upstreamCommits.length > 0} +
+
+ There {multiple ? 'are' : 'is'} + {base.upstreamCommits.length} unmerged upstream + {multiple ? 'commits' : 'commit'} +
- {#if base.upstreamCommits?.length > 0} - +
+{/if} + +
+ + {#if base.upstreamCommits?.length > 0}
{#each base.upstreamCommits as commit, index} + > + {#snippet lines(topHeightPx)} + + {/snippet} + {/each}
- + + {#if base.diverged} + + {#snippet lines()} + + {/snippet} + {#snippet action()} + + {/snippet} + + {/if} {/if} + + {#if commitsAhead.length > 0} +
+ {#each commitsAhead as commit, index} + + {#snippet lines(topHeightPx)} + + {/snippet} + + {/each} +
+ + + {#snippet lines()} + + {/snippet} + {#snippet action()} +
+ + + {#if onlyLocalAhead} + + {/if} +
+ {/snippet} +
+ {/if} + +
- -

Local

-
- {#each base.recentCommits as commit, index} + {#each localAndRemoteCommits as commit, index} + > + {#snippet lines(topHeightPx)} + + {/snippet} + {/each}
@@ -146,17 +393,71 @@ {/snippet} +{#if resetBaseStrategy} + { + if (resetBaseStrategy) await resetBaseTo[resetBaseStrategy].action(); + close(); + }} + > + + + {#snippet controls(close)} + + + {/snippet} + +{/if} + + +