From 181dc5d75e0a8844a095198b095dc56e609351cf Mon Sep 17 00:00:00 2001 From: Unknwon Date: Thu, 16 Nov 2017 00:03:35 -0500 Subject: [PATCH] editor: remove out of sync branch before checkout again If a branch was deleted from server, sometimes it is not reflected on local copy. Therefore, we need to remove the branch with same name if it is out of sync and then checkout to correct version. --- models/errors/repo.go | 13 +++++++++++++ models/repo_editor.go | 19 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/models/errors/repo.go b/models/errors/repo.go index 15adb2b05..69c29be66 100644 --- a/models/errors/repo.go +++ b/models/errors/repo.go @@ -59,3 +59,16 @@ func IsMirrorNotExist(err error) bool { func (err MirrorNotExist) Error() string { return fmt.Sprintf("mirror does not exist [repo_id: %d]", err.RepoID) } + +type BranchAlreadyExists struct { + Name string +} + +func IsBranchAlreadyExists(err error) bool { + _, ok := err.(BranchAlreadyExists) + return ok +} + +func (err BranchAlreadyExists) Error() string { + return fmt.Sprintf("branch already exists [name: %s]", err.Name) +} diff --git a/models/repo_editor.go b/models/repo_editor.go index 955d018d9..ebf25ecd3 100644 --- a/models/repo_editor.go +++ b/models/repo_editor.go @@ -21,6 +21,7 @@ import ( git "github.com/gogits/git-module" + "github.com/gogits/gogs/models/errors" "github.com/gogits/gogs/pkg/process" "github.com/gogits/gogs/pkg/setting" ) @@ -92,13 +93,29 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) ( return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } + repoPath := repo.RepoPath() + localPath := repo.LocalCopyPath() + if opts.OldBranch != opts.NewBranch { + // Directly return error if new branch already exists in the server + if git.IsBranchExist(repoPath, opts.NewBranch) { + return errors.BranchAlreadyExists{opts.NewBranch} + } + + // Otherwise, delete branch from local copy in case out of sync + if git.IsBranchExist(localPath, opts.NewBranch) { + if err = git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{ + Force: true, + }); err != nil { + return fmt.Errorf("DeleteBranch [name: %s]: %v", opts.NewBranch, err) + } + } + if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } - localPath := repo.LocalCopyPath() oldFilePath := path.Join(localPath, opts.OldTreeName) filePath := path.Join(localPath, opts.NewTreeName) os.MkdirAll(path.Dir(filePath), os.ModePerm)