From aa02463ded9e8618375db4a3cb3c1b2593e96a8e Mon Sep 17 00:00:00 2001
From: John Olheiser <42128690+jolheiser@users.noreply.github.com>
Date: Mon, 8 Apr 2019 00:08:02 -0500
Subject: [PATCH] Delete local branch if it exists (#6497)

Signed-off-by: jolheiser <john.olheiser@gmail.com>
---
 models/repo_branch.go  | 32 ++++++++++++++++++++++++++++++++
 routers/repo/branch.go |  6 ++++++
 2 files changed, 38 insertions(+)

diff --git a/models/repo_branch.go b/models/repo_branch.go
index 9ea4ce45fb..1c62a3d67d 100644
--- a/models/repo_branch.go
+++ b/models/repo_branch.go
@@ -54,6 +54,38 @@ func (repo *Repository) CheckoutNewBranch(oldBranch, newBranch string) error {
 	return checkoutNewBranch(repo.RepoPath(), repo.LocalCopyPath(), oldBranch, newBranch)
 }
 
+// deleteLocalBranch deletes a branch from a local repo cache
+// First checks out default branch to avoid trying to delete the currently checked out branch
+func deleteLocalBranch(localPath, defaultBranch, deleteBranch string) error {
+	if !com.IsExist(localPath) {
+		return nil
+	}
+
+	if !git.IsBranchExist(localPath, deleteBranch) {
+		return nil
+	}
+
+	// Must NOT have branch currently checked out
+	// Checkout default branch first
+	if err := git.Checkout(localPath, git.CheckoutOptions{
+		Timeout: time.Duration(setting.Git.Timeout.Pull) * time.Second,
+		Branch:  defaultBranch,
+	}); err != nil {
+		return fmt.Errorf("git checkout %s: %v", defaultBranch, err)
+	}
+
+	cmd := git.NewCommand("branch")
+	cmd.AddArguments("-D")
+	cmd.AddArguments(deleteBranch)
+	_, err := cmd.RunInDir(localPath)
+	return err
+}
+
+// DeleteLocalBranch deletes a branch from the local repo
+func (repo *Repository) DeleteLocalBranch(branchName string) error {
+	return deleteLocalBranch(repo.LocalCopyPath(), repo.DefaultBranch, branchName)
+}
+
 // Branch holds the branch information
 type Branch struct {
 	Path string
diff --git a/routers/repo/branch.go b/routers/repo/branch.go
index a29519a43f..4d5b3996c9 100644
--- a/routers/repo/branch.go
+++ b/routers/repo/branch.go
@@ -71,6 +71,12 @@ func DeleteBranchPost(ctx *context.Context) {
 		return
 	}
 
+	// Delete branch in local copy if it exists
+	if err := ctx.Repo.Repository.DeleteLocalBranch(branchName); err != nil {
+		ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", branchName))
+		return
+	}
+
 	ctx.Flash.Success(ctx.Tr("repo.branch.deletion_success", branchName))
 }