feat(remote): Enhance remote branch management and stability

Improved handling for deleting remote branches across the application, enhancing both user experience and backend reliability. This includes adding structured logging to all Git remote operations in Rust, refining UI components to handle remote-specific deletion flows, and providing clear status/error feedback in sync settings.

- Standardized styling for action toggles (Stash, Branch, Explorer) using consistent dimensions.
- Implemented detailed console logging for all Git remote operations on the backend.
- Refined dialogs and sync settings to provide explicit status and error messages during remote management.
This commit is contained in:
Christoph Brandau
2026-07-14 00:29:37 +02:00
parent 7800f0fb24
commit 95c8b01ed1
10 changed files with 219 additions and 57 deletions
+42 -11
View File
@@ -2276,7 +2276,27 @@
async function confirmDeleteBranch() {
const branch = deleteBranchTarget;
if (!activeRepoPath || !branch || branch.remote || branch.current || isBusy) return;
if (!activeRepoPath || !branch || branch.current || isBusy) return;
if (branch.remote) {
const slash = branch.name.indexOf("/");
if (slash < 1) { errorMessage = "Could not determine remote name."; return; }
const remote = branch.name.slice(0, slash);
const remoteBranch = branch.name.slice(slash + 1);
operation = `Deleting ${branch.name} from remote`;
errorMessage = "";
try {
applyStatus(await deleteRemoteBranch(activeRepoPath, remote, remoteBranch));
deleteBranchTarget = null;
await refreshRefsAndCommitGraph(activeRepoPath);
trackEvent("remote_branch_deleted");
} catch (error) {
errorMessage = errorToMessage(error);
} finally {
operation = "";
}
return;
}
operation = `${deleteBranchForce ? "Force deleting" : "Deleting"} ${branch.name}`;
errorMessage = "";
@@ -2809,11 +2829,10 @@
async function deleteTrackedRemoteBranch(branch: GitBranchInfo) {
if (!activeRepoPath || !branch.remote) return;
const slash = branch.name.indexOf("/");
if (slash < 1) { errorMessage = "Could not determine remote name."; return; }
const remote = branch.name.slice(0, slash); const remoteBranch = branch.name.slice(slash + 1);
if (!window.confirm(`Delete '${remoteBranch}' from remote '${remote}'?`)) return;
await runOperation("Deleting remote branch", async () => { applyStatus(await deleteRemoteBranch(activeRepoPath, remote, remoteBranch)); await refreshRefsAndCommitGraph(activeRepoPath); });
if (import.meta.env.DEV) console.info("[Gitty remote] remote branch delete requested", branch);
deleteBranchTarget = branch;
deleteBranchForce = false;
trackEvent("remote_branch_delete_dialog_opened");
}
async function initializeRepository() {
@@ -2873,10 +2892,21 @@
async function addSyncRemote(name: string, url: string) { if (!activeRepoPath) return; syncSettingsRemotes = await addRemote(activeRepoPath, name, url); await refreshBranchList(activeRepoPath); }
async function updateSyncRemote(name: string, url: string) { if (!activeRepoPath) return; syncSettingsRemotes = await updateRemote(activeRepoPath, name, url); }
async function removeSyncRemote(name: string) {
if (!activeRepoPath || !window.confirm(`Remove remote '${name}'? Local commits and branches are kept.`)) return;
syncSettingsRemotes = await removeRemote(activeRepoPath, name);
if (selectedRemote === name) selectedRemote = "";
await refreshBranchList(activeRepoPath);
if (!activeRepoPath) return;
operation = `Removing remote ${name}`;
try {
syncSettingsRemotes = await removeRemote(activeRepoPath, name);
if (syncSettingsRemotes.some((remote) => remote.name === name)) throw new Error(`Remote '${name}' still exists after removal.`);
if (selectedRemote === name) { selectedRemote = ""; localStorage.setItem("gitlite.selectedRemote", ""); }
applyStatus(await getStatus(activeRepoPath));
await refreshBranchList(activeRepoPath);
} catch (error) {
const message = errorToMessage(error);
if (import.meta.env.DEV) console.error("[Gitty remote] remove_remote failed", { name, path: activeRepoPath, error });
throw new Error(message);
} finally {
operation = "";
}
}
async function saveStash(message: string, includeUntracked: boolean) {
@@ -3667,6 +3697,7 @@
}
function handleWindowContextMenu(event: MouseEvent) {
if (import.meta.env.DEV) return;
event.preventDefault();
if (repoTabContextMenu) closeRepoTabContextMenu();
}
@@ -4404,7 +4435,7 @@
/>
{/if}
<!-- Delete a local branch from the branch context menu -->
<!-- Confirm deletion of a local or remote branch from the shared branch context menu -->
{#if deleteBranchTarget}
<BranchDeleteConfirmDialog
branch={deleteBranchTarget}