mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-28 04:47:42 +03:00
Merge pull request #4663 from gitbutlerapp/create-delete-local-branch
create-delete-local-branch
This commit is contained in:
commit
ed7a8c4027
@ -8,6 +8,7 @@
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import Icon from '@gitbutler/ui/icon/Icon.svelte';
|
||||
import Button from '@gitbutler/ui/inputs/Button.svelte';
|
||||
import Modal from '@gitbutler/ui/modal/Modal.svelte';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import type { PullRequest } from '$lib/gitHost/interface/types';
|
||||
import type { Branch } from '$lib/vbranches/types';
|
||||
@ -26,6 +27,8 @@
|
||||
$: gitHostBranch = upstream ? $gitHost?.branch(upstream) : undefined;
|
||||
|
||||
let isApplying = false;
|
||||
let isDeleting = false;
|
||||
let deleteBranchModal: Modal;
|
||||
</script>
|
||||
|
||||
<div class="header__wrapper">
|
||||
@ -110,12 +113,56 @@
|
||||
>
|
||||
Apply
|
||||
</Button>
|
||||
<Button
|
||||
style="ghost"
|
||||
outline
|
||||
help="Deletes the local branch. If this branch is also present on a remote, it will not be deleted there."
|
||||
icon="bin-small"
|
||||
loading={isDeleting}
|
||||
disabled={!localBranch}
|
||||
onclick={async () => {
|
||||
if (localBranch) {
|
||||
console.log(JSON.stringify(localBranch));
|
||||
deleteBranchModal.show(branch);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Delete locally
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header__top-overlay" data-tauri-drag-region></div>
|
||||
</div>
|
||||
|
||||
<Modal width="small" title="Delete branch" bind:this={deleteBranchModal}>
|
||||
{#snippet children(branch)}
|
||||
Are you sure you want to delete <code class="code-string">{branch.name}</code>?
|
||||
{/snippet}
|
||||
{#snippet controls(close)}
|
||||
<Button style="ghost" outline onclick={close}>Cancel</Button>
|
||||
<Button
|
||||
style="error"
|
||||
kind="solid"
|
||||
onclick={async () => {
|
||||
try {
|
||||
await branchController.deleteLocalBranch(branch.name, branch.givenName);
|
||||
} catch (e) {
|
||||
const err = 'Failed to delete local branch';
|
||||
error(err);
|
||||
console.error(err, e);
|
||||
} finally {
|
||||
isDeleting = false;
|
||||
close();
|
||||
}
|
||||
goto(`/${project.id}/board`);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
{/snippet}
|
||||
</Modal>
|
||||
|
||||
<style lang="postcss">
|
||||
.header__wrapper {
|
||||
z-index: var(--z-lifted);
|
||||
|
@ -293,6 +293,25 @@ You can find them in the 'Branches' sidebar in order to resolve conflicts.`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a branch local reference and any associated virtual branch if applicable and updates the list of branches know to the UI.
|
||||
* @param branch The reference name of the branch to delete (including the `refs/heads/` prefix).
|
||||
*/
|
||||
async deleteLocalBranch(refname: string, givenName: string) {
|
||||
try {
|
||||
await invoke<void>('delete_local_branch', {
|
||||
projectId: this.projectId,
|
||||
refname,
|
||||
givenName
|
||||
});
|
||||
} catch (err) {
|
||||
showError('Failed to delete local branch', err);
|
||||
} finally {
|
||||
this.remoteBranchService.refresh();
|
||||
this.baseBranchService.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async markResolved(path: string) {
|
||||
try {
|
||||
await invoke<void>('mark_resolved', { projectId: this.projectId, path });
|
||||
|
@ -94,6 +94,43 @@ impl VirtualBranchActions {
|
||||
Ok(branch_id)
|
||||
}
|
||||
|
||||
/// Deletes a local branch reference and it's associated virtual branch.
|
||||
/// If there is a virtual branch and it is applied, this function will return an error.
|
||||
/// If there is no such local reference, this function will return an error.
|
||||
pub fn delete_local_branch(
|
||||
&self,
|
||||
project: &Project,
|
||||
refname: &Refname,
|
||||
given_name: String,
|
||||
) -> Result<()> {
|
||||
let ctx = open_with_verify(project)?;
|
||||
let repo = ctx.repository();
|
||||
let handle = ctx.project().virtual_branches();
|
||||
let vbranch = handle.list_all_branches()?.into_iter().find(|branch| {
|
||||
branch
|
||||
.source_refname
|
||||
.as_ref()
|
||||
.map_or(false, |source_refname| source_refname == refname)
|
||||
});
|
||||
|
||||
if let Some(vbranch) = vbranch {
|
||||
// Disallow deletion of branches that are applied in workspace
|
||||
if vbranch.in_workspace {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Cannot delete a branch that is applied in workspace"
|
||||
));
|
||||
}
|
||||
// Deletes the virtual branch entry from the application state
|
||||
handle.delete_branch_entry(&vbranch.id)?;
|
||||
}
|
||||
|
||||
// If a branch reference for this can be found, delete it
|
||||
if let Ok(mut branch) = repo.find_branch(&given_name, git2::BranchType::Local) {
|
||||
branch.delete()?;
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(project), err(Debug))]
|
||||
pub fn get_base_branch_data(project: &Project) -> Result<BaseBranch> {
|
||||
let ctx = CommandContext::open(project)?;
|
||||
|
@ -237,6 +237,13 @@ impl VirtualBranchesHandle {
|
||||
|
||||
Ok(order)
|
||||
}
|
||||
|
||||
pub fn delete_branch_entry(&self, branch_id: &BranchId) -> Result<()> {
|
||||
let mut virtual_branches = self.read_file()?;
|
||||
virtual_branches.branches.remove(branch_id);
|
||||
self.write_file(&virtual_branches)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn write<P: AsRef<Path>>(file_path: P, virtual_branches: &VirtualBranches) -> Result<()> {
|
||||
|
@ -149,6 +149,7 @@ fn main() {
|
||||
repo::commands::git_clone_repository,
|
||||
virtual_branches::commands::list_virtual_branches,
|
||||
virtual_branches::commands::create_virtual_branch,
|
||||
virtual_branches::commands::delete_local_branch,
|
||||
virtual_branches::commands::commit_virtual_branch,
|
||||
virtual_branches::commands::get_base_branch_data,
|
||||
virtual_branches::commands::set_base_branch,
|
||||
|
@ -78,6 +78,21 @@ pub mod commands {
|
||||
Ok(branch_id)
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(projects, windows), err(Debug))]
|
||||
pub fn delete_local_branch(
|
||||
windows: State<'_, WindowState>,
|
||||
projects: State<'_, projects::Controller>,
|
||||
project_id: ProjectId,
|
||||
refname: Refname,
|
||||
given_name: String,
|
||||
) -> Result<(), Error> {
|
||||
let project = projects.get(project_id)?;
|
||||
VirtualBranchActions.delete_local_branch(&project, &refname, given_name)?;
|
||||
emit_vbranches(&windows, project_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(projects, windows), err(Debug))]
|
||||
pub fn create_virtual_branch_from_branch(
|
||||
|
Loading…
Reference in New Issue
Block a user