From dc5cd8ddf716fd3de480b9d2d2290d1f8a15ebf1 Mon Sep 17 00:00:00 2001 From: Ben Bachem <10088265+bezbac@users.noreply.github.com> Date: Wed, 27 Mar 2024 23:20:55 +0100 Subject: [PATCH 1/2] improve `magit-branch-spinoff` implementation --- src/commands/branchingCommands.ts | 46 +++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/commands/branchingCommands.ts b/src/commands/branchingCommands.ts index 0d05dda..772818c 100644 --- a/src/commands/branchingCommands.ts +++ b/src/commands/branchingCommands.ts @@ -207,13 +207,49 @@ async function createNewSpinoff({ repository }: MenuState) { prompt: 'Name for new branch', }); - if (newBranchName && newBranchName.length > 0) { - const args = ['checkout', '-B', newBranchName]; - return gitRun(repository.gitRepository, args); - } else { - window.setStatusBarMessage( + if (!newBranchName || newBranchName.length < 1) { + return window.setStatusBarMessage( 'No name given for new branch', Constants.StatusMessageDisplayTimeout ); } + + if (repository.branches.find(b => b.name === newBranchName)) { + return window.setStatusBarMessage( + `Cannot spin off ${newBranchName}. It already exists`, + Constants.StatusMessageDisplayTimeout + ); + } + + const base = repository.HEAD?.name; + + if (!base) { + return window.setStatusBarMessage( + 'No branch checked out', + Constants.StatusMessageDisplayTimeout + ); + } + + // Save current commit hash of base branch for later reference + const baseCommit = repository.HEAD?.commit; + + // Get upsteam branch commit hash of base branch + const upstreamBranchCommit = repository.HEAD.upstreamRemote?.commit?.hash; + + // Checkout new branch + await gitRun(repository.gitRepository, ['checkout', '-b', newBranchName]); + + if (upstreamBranchCommit && baseCommit !== upstreamBranchCommit) { + await gitRun(repository.gitRepository, ['branch', '-f', base, upstreamBranchCommit]); + + window.setStatusBarMessage( + `Branch ${base} was reset to upstream`, + Constants.StatusMessageDisplayTimeout + ); + } else { + window.setStatusBarMessage( + `Branch ${base} not changed`, + Constants.StatusMessageDisplayTimeout + ); + } } From e0faf63d850d765bca2bd84d5bc316a164152d21 Mon Sep 17 00:00:00 2001 From: Ben Bachem <10088265+bezbac@users.noreply.github.com> Date: Fri, 29 Mar 2024 15:04:23 +0100 Subject: [PATCH 2/2] address pr comments --- src/commands/branchingCommands.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/commands/branchingCommands.ts b/src/commands/branchingCommands.ts index 772818c..f76abeb 100644 --- a/src/commands/branchingCommands.ts +++ b/src/commands/branchingCommands.ts @@ -239,11 +239,21 @@ async function createNewSpinoff({ repository }: MenuState) { // Checkout new branch await gitRun(repository.gitRepository, ['checkout', '-b', newBranchName]); - if (upstreamBranchCommit && baseCommit !== upstreamBranchCommit) { - await gitRun(repository.gitRepository, ['branch', '-f', base, upstreamBranchCommit]); + if (baseCommit && upstreamBranchCommit && baseCommit !== upstreamBranchCommit) { + // Find common ancestor of base branch and upstream branch + const mergeBase = await repository.gitRepository.getMergeBase(baseCommit, upstreamBranchCommit); + + // Reset the original branch to the common ancestor + await gitRun(repository.gitRepository, [ + 'update-ref', + '-m', + `"reset: moving to ${mergeBase}"`, + `refs/heads/${base}`, + mergeBase + ]); window.setStatusBarMessage( - `Branch ${base} was reset to upstream`, + `Branch ${base} was reset to ${mergeBase}`, Constants.StatusMessageDisplayTimeout ); } else {