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)) }