From 269b30e970ba51378ecc73e44d15704915cea991 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 26 Aug 2025 15:19:15 -0700 Subject: [PATCH 1/4] Deleting branch could delete broken branch which has database record but git branch is missing --- services/repository/branch.go | 44 +++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/services/repository/branch.go b/services/repository/branch.go index 6e0065b2776d5..b496e060ffa5c 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -532,9 +532,14 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // database branch record not exist or it's a deleted branch notExist := git_model.IsErrBranchNotExist(err) || rawBranch.IsDeleted - commit, err := gitRepo.GetBranchCommit(branchName) - if err != nil { - return err + branchExistInGit := gitRepo.IsBranchExist(branchName) + var commitID string + if branchExistInGit { + commit, err := gitRepo.GetBranchCommit(branchName) + if err != nil { + return err + } + commitID = commit.ID.String() } if err := db.WithTx(ctx, func(ctx context.Context) error { @@ -549,6 +554,9 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return fmt.Errorf("DeleteBranch: %v", err) } } + if !branchExistInGit { + return nil + } return gitRepo.DeleteBranch(branchName, git.DeleteBranchOptions{ Force: true, @@ -557,20 +565,22 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return err } - objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) - - // Don't return error below this - if err := PushUpdate( - &repo_module.PushUpdateOptions{ - RefFullName: git.RefNameFromBranch(branchName), - OldCommitID: commit.ID.String(), - NewCommitID: objectFormat.EmptyObjectID().String(), - PusherID: doer.ID, - PusherName: doer.Name, - RepoUserName: repo.OwnerName, - RepoName: repo.Name, - }); err != nil { - log.Error("Update: %v", err) + if branchExistInGit { + objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) + + // Don't return error below this + if err := PushUpdate( + &repo_module.PushUpdateOptions{ + RefFullName: git.RefNameFromBranch(branchName), + OldCommitID: commitID, + NewCommitID: objectFormat.EmptyObjectID().String(), + PusherID: doer.ID, + PusherName: doer.Name, + RepoUserName: repo.OwnerName, + RepoName: repo.Name, + }); err != nil { + log.Error("Update: %v", err) + } } return nil From f10adacdebb42e713db3c383403a2e63b7db2150 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 27 Aug 2025 12:22:10 -0700 Subject: [PATCH 2/4] improvements --- services/repository/branch.go | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/services/repository/branch.go b/services/repository/branch.go index b496e060ffa5c..e7fb5a28fec75 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -532,14 +532,9 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // database branch record not exist or it's a deleted branch notExist := git_model.IsErrBranchNotExist(err) || rawBranch.IsDeleted - branchExistInGit := gitRepo.IsBranchExist(branchName) - var commitID string - if branchExistInGit { - commit, err := gitRepo.GetBranchCommit(branchName) - if err != nil { - return err - } - commitID = commit.ID.String() + commit, err := gitRepo.GetBranchCommit(branchName) + if err != nil && !errors.Is(err, util.ErrNotExist) { + return err } if err := db.WithTx(ctx, func(ctx context.Context) error { @@ -554,7 +549,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return fmt.Errorf("DeleteBranch: %v", err) } } - if !branchExistInGit { + if commit == nil { return nil } @@ -565,14 +560,14 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return err } - if branchExistInGit { + if commit != nil { objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) // Don't return error below this if err := PushUpdate( &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(branchName), - OldCommitID: commitID, + OldCommitID: commit.ID.String(), NewCommitID: objectFormat.EmptyObjectID().String(), PusherID: doer.ID, PusherName: doer.Name, From f3bbcdf90bfafffd36f1dc10fedcc5346e3bace7 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 28 Aug 2025 11:32:54 +0800 Subject: [PATCH 3/4] Update branch.go --- services/repository/branch.go | 36 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/services/repository/branch.go b/services/repository/branch.go index e7fb5a28fec75..8cbd3f2b2a987 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -532,7 +532,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // database branch record not exist or it's a deleted branch notExist := git_model.IsErrBranchNotExist(err) || rawBranch.IsDeleted - commit, err := gitRepo.GetBranchCommit(branchName) + branchCommit, err := gitRepo.GetBranchCommit(branchName) if err != nil && !errors.Is(err, util.ErrNotExist) { return err } @@ -549,7 +549,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return fmt.Errorf("DeleteBranch: %v", err) } } - if commit == nil { + if branchCommit == nil { return nil } @@ -560,22 +560,24 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return err } - if commit != nil { - objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) + if branchCommit == nil { + return nil + } - // Don't return error below this - if err := PushUpdate( - &repo_module.PushUpdateOptions{ - RefFullName: git.RefNameFromBranch(branchName), - OldCommitID: commit.ID.String(), - NewCommitID: objectFormat.EmptyObjectID().String(), - PusherID: doer.ID, - PusherName: doer.Name, - RepoUserName: repo.OwnerName, - RepoName: repo.Name, - }); err != nil { - log.Error("Update: %v", err) - } + // Don't return error below this + + objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) + if err := PushUpdate( + &repo_module.PushUpdateOptions{ + RefFullName: git.RefNameFromBranch(branchName), + OldCommitID: commit.ID.String(), + NewCommitID: objectFormat.EmptyObjectID().String(), + PusherID: doer.ID, + PusherName: doer.Name, + RepoUserName: repo.OwnerName, + RepoName: repo.Name, + }); err != nil { + log.Error("PushUpdateOptions: %v", err) } return nil From f3873be6319f0523f3d2d124b4041f29b90f0792 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 28 Aug 2025 11:40:07 +0800 Subject: [PATCH 4/4] Update branch.go --- services/repository/branch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/repository/branch.go b/services/repository/branch.go index 8cbd3f2b2a987..df7202227aa70 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -570,7 +570,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R if err := PushUpdate( &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(branchName), - OldCommitID: commit.ID.String(), + OldCommitID: branchCommit.ID.String(), NewCommitID: objectFormat.EmptyObjectID().String(), PusherID: doer.ID, PusherName: doer.Name,