Merge pull request #3939 from gitbutlerapp/show-infobox-if-workspace-update-stashed-branches

show infobox if workspace update stashed branches
This commit is contained in:
Kiril Videlov 2024-06-01 14:04:34 +02:00 committed by GitHub
commit 39e157fac6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 49 additions and 19 deletions

View File

@ -5,6 +5,7 @@
import CommitCard from '$lib/components/CommitCard.svelte'; import CommitCard from '$lib/components/CommitCard.svelte';
import Modal from '$lib/components/Modal.svelte'; import Modal from '$lib/components/Modal.svelte';
import { projectMergeUpstreamWarningDismissed } from '$lib/config/config'; import { projectMergeUpstreamWarningDismissed } from '$lib/config/config';
import { showInfo } from '$lib/notifications/toasts';
import { getContext } from '$lib/utils/context'; import { getContext } from '$lib/utils/context';
import { tooltip } from '$lib/utils/tooltip'; import { tooltip } from '$lib/utils/tooltip';
import { BranchController } from '$lib/vbranches/branchController'; import { BranchController } from '$lib/vbranches/branchController';
@ -22,6 +23,13 @@
let mergeUpstreamWarningDismissedCheckbox = false; let mergeUpstreamWarningDismissedCheckbox = false;
$: multiple = base ? base.upstreamCommits.length > 1 || base.upstreamCommits.length == 0 : false; $: multiple = base ? base.upstreamCommits.length > 1 || base.upstreamCommits.length == 0 : false;
async function updateBaseBranch() {
let infoText = await branchController.updateBaseBranch();
if (infoText) {
showInfo('Stashed conflicting branches', infoText);
}
}
</script> </script>
<div class="wrapper"> <div class="wrapper">
@ -38,7 +46,7 @@
help={`Merges the commits from ${base.branchName} into the base of all applied virtual branches`} help={`Merges the commits from ${base.branchName} into the base of all applied virtual branches`}
on:click={() => { on:click={() => {
if ($mergeUpstreamWarningDismissed) { if ($mergeUpstreamWarningDismissed) {
branchController.updateBaseBranch(); updateBaseBranch();
} else { } else {
updateTargetModal.show(); updateTargetModal.show();
} }
@ -111,7 +119,7 @@
style="pop" style="pop"
kind="solid" kind="solid"
on:click={() => { on:click={() => {
branchController.updateBaseBranch(); updateBaseBranch();
if (mergeUpstreamWarningDismissedCheckbox) { if (mergeUpstreamWarningDismissedCheckbox) {
mergeUpstreamWarningDismissed.set(true); mergeUpstreamWarningDismissed.set(true);
} }

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import Tag from './Tag.svelte'; import Tag from './Tag.svelte';
import { showError } from '$lib/notifications/toasts'; import { showInfo, showError } from '$lib/notifications/toasts';
import { getContext } from '$lib/utils/context'; import { getContext } from '$lib/utils/context';
import { BranchController } from '$lib/vbranches/branchController'; import { BranchController } from '$lib/vbranches/branchController';
@ -17,7 +17,10 @@
on:click={async () => { on:click={async () => {
loading = true; loading = true;
try { try {
await branchController.updateBaseBranch(); let infoText = await branchController.updateBaseBranch();
if (infoText) {
showInfo('Stashed conflicting branches', infoText);
}
} catch (err) { } catch (err) {
showError('Failed update workspace', err); showError('Failed update workspace', err);
} finally { } finally {

View File

@ -26,6 +26,10 @@ export function showError(title: string, err: any) {
showToast({ title, errorMessage: errorMessage, style: 'error' }); showToast({ title, errorMessage: errorMessage, style: 'error' });
} }
export function showInfo(title: string, body: string) {
showToast({ title, message: body, errorMessage: '', style: 'neutral' });
}
export function dismissToast(messageId: string | undefined) { export function dismissToast(messageId: string | undefined) {
if (!messageId) return; if (!messageId) return;
toastStore.update((items) => items.filter((m) => m.id != messageId)); toastStore.update((items) => items.filter((m) => m.id != messageId));

View File

@ -238,9 +238,18 @@ export class BranchController {
} }
} }
async updateBaseBranch() { async updateBaseBranch(): Promise<string | undefined> {
try { try {
await invoke<object>('update_base_branch', { projectId: this.projectId }); const stashedConflicting = await invoke<Branch[]>('update_base_branch', {
projectId: this.projectId
});
if (stashedConflicting.length > 0) {
return `The following branches were stashed due to a merge conflict during updating the workspace: \n\n \
${stashedConflicting.map((branch) => branch.name).join('\n')} \n\n \
You can find them in the 'Branches' sidebar in order to resolve conflicts.`;
} else {
return undefined;
}
} finally { } finally {
this.targetBranchService.reload(); this.targetBranchService.reload();
} }

View File

@ -336,7 +336,7 @@ fn _print_tree(repo: &git2::Repository, tree: &git2::Tree) -> Result<()> {
pub fn update_base_branch( pub fn update_base_branch(
project_repository: &project_repository::Repository, project_repository: &project_repository::Repository,
user: Option<&users::User>, user: Option<&users::User>,
) -> anyhow::Result<()> { ) -> anyhow::Result<Vec<branch::Branch>> {
if project_repository.is_resolving() { if project_repository.is_resolving() {
anyhow::bail!(errors::UpdateBaseBranchError::Conflict( anyhow::bail!(errors::UpdateBaseBranchError::Conflict(
errors::ProjectConflict { errors::ProjectConflict {
@ -356,8 +356,10 @@ pub fn update_base_branch(
.peel_to_commit() .peel_to_commit()
.context(format!("failed to peel branch {} to commit", target.branch))?; .context(format!("failed to peel branch {} to commit", target.branch))?;
let mut unapplied_branches: Vec<branch::Branch> = Vec::new();
if new_target_commit.id() == target.sha.into() { if new_target_commit.id() == target.sha.into() {
return Ok(()); return Ok(unapplied_branches);
} }
let new_target_tree = new_target_commit let new_target_tree = new_target_commit
@ -433,6 +435,7 @@ pub fn update_base_branch(
// branch tree conflicts with new target, unapply branch for now. we'll handle it later, when user applies it back. // branch tree conflicts with new target, unapply branch for now. we'll handle it later, when user applies it back.
branch.applied = false; branch.applied = false;
vb_state.set_branch(branch.clone())?; vb_state.set_branch(branch.clone())?;
unapplied_branches.push(branch.clone());
return Ok(Some(branch)); return Ok(Some(branch));
} }
@ -569,7 +572,7 @@ pub fn update_base_branch(
// Rewriting the integration commit is necessary after changing target sha. // Rewriting the integration commit is necessary after changing target sha.
super::integration::update_gitbutler_integration(&vb_state, project_repository)?; super::integration::update_gitbutler_integration(&vb_state, project_repository)?;
Ok(()) Ok(unapplied_branches)
} }
pub fn target_to_base_branch( pub fn target_to_base_branch(

View File

@ -9,8 +9,8 @@ use tokio::{sync::Semaphore, task::JoinHandle};
use super::{ use super::{
branch::{BranchId, BranchOwnershipClaims}, branch::{BranchId, BranchOwnershipClaims},
errors::{self}, errors, target, target_to_base_branch, BaseBranch, Branch, RemoteBranchFile,
target, target_to_base_branch, BaseBranch, RemoteBranchFile, VirtualBranchesHandle, VirtualBranchesHandle,
}; };
use crate::{ use crate::{
git, project_repository, git, project_repository,
@ -164,7 +164,7 @@ impl Controller {
.await .await
} }
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<(), Error> { pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<Branch>, Error> {
self.inner(project_id) self.inner(project_id)
.await .await
.update_base_branch(project_id) .update_base_branch(project_id)
@ -587,7 +587,7 @@ impl ControllerInner {
}) })
} }
pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<(), Error> { pub async fn update_base_branch(&self, project_id: ProjectId) -> Result<Vec<Branch>, Error> {
let _permit = self.semaphore.acquire().await; let _permit = self.semaphore.acquire().await;
self.with_verify_branch(project_id, |project_repository, user| { self.with_verify_branch(project_id, |project_repository, user| {

View File

@ -150,13 +150,16 @@ pub mod commands {
#[tauri::command(async)] #[tauri::command(async)]
#[instrument(skip(handle), err(Debug))] #[instrument(skip(handle), err(Debug))]
pub async fn update_base_branch(handle: AppHandle, project_id: ProjectId) -> Result<(), Error> { pub async fn update_base_branch(
handle handle: AppHandle,
project_id: ProjectId,
) -> Result<Vec<branch::Branch>, Error> {
let unapplied_branches = handle
.state::<Controller>() .state::<Controller>()
.update_base_branch(project_id) .update_base_branch(project_id)
.await?; .await?;
emit_vbranches(&handle, project_id).await; emit_vbranches(&handle, project_id).await;
Ok(()) Ok(unapplied_branches)
} }
#[tauri::command(async)] #[tauri::command(async)]

View File

@ -780,7 +780,7 @@ mod tests {
for (delay, events) in expected_events { for (delay, events) in expected_events {
MockClock::set_time(backup_time); MockClock::set_time(backup_time);
state.queues = backup_queues.clone(); state.queues.clone_from(&backup_queues);
match delay.as_str() { match delay.as_str() {
"none" => {} "none" => {}

View File

@ -192,7 +192,7 @@ mod utils {
fn add_path(&mut self, path: &Path) { fn add_path(&mut self, path: &Path) {
for (p, file_id) in &self.file_system { for (p, file_id) in &self.file_system {
if p.starts_with(path) { if p.starts_with(path) {
self.paths.insert(p.clone(), file_id.clone()); self.paths.insert(p.clone(), *file_id);
} }
} }
} }
@ -202,7 +202,7 @@ mod utils {
} }
fn rescan(&mut self) { fn rescan(&mut self) {
self.add_path(&Path::new("/")); self.add_path(Path::new("/"));
} }
} }
} }