From 71a11872091634f1370374ef123d32798ec0447d Mon Sep 17 00:00:00 2001 From: GWDx Date: Fri, 9 May 2025 02:00:29 +0800 Subject: [PATCH] Fix incorrect divergence cache after switching default branch (#34370) Issue: After switching the default branch, other branches are still compared against the old default branch due to outdated divergence cache. Change: Clear the divergence cache in SetRepoDefaultBranch to ensure correct comparisons against the new default branch. Fixes #34369 --- services/repository/branch.go | 5 + templates/repo/branch/list.tmpl | 6 +- .../integration/change_default_branch_test.go | 97 +++++++++++++++++++ 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/services/repository/branch.go b/services/repository/branch.go index 94c47ffdc4..dd00ca7dcd 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -663,6 +663,11 @@ func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, newB } } + // clear divergence cache + if err := DelRepoDivergenceFromCache(ctx, repo.ID); err != nil { + log.Error("DelRepoDivergenceFromCache: %v", err) + } + notify_service.ChangeDefaultBranch(ctx, repo) return nil diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index 19797229bf..aa38413ad7 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -20,7 +20,7 @@
- {{.DefaultBranchBranch.DBBranch.Name}} + {{.DefaultBranchBranch.DBBranch.Name}} {{if .DefaultBranchBranch.IsProtected}} {{svg "octicon-shield-lock"}} {{end}} @@ -90,13 +90,13 @@ {{if .DBBranch.IsDeleted}}
- {{.DBBranch.Name}} + {{.DBBranch.Name}}

{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{DateUtils.TimeSince .DBBranch.DeletedUnix}}

{{else}}
- {{.DBBranch.Name}} + {{.DBBranch.Name}} {{if .IsProtected}} {{svg "octicon-shield-lock"}} {{end}} diff --git a/tests/integration/change_default_branch_test.go b/tests/integration/change_default_branch_test.go index 729eb1e4ce..9b61cff9fd 100644 --- a/tests/integration/change_default_branch_test.go +++ b/tests/integration/change_default_branch_test.go @@ -6,12 +6,16 @@ package integration import ( "fmt" "net/http" + "strconv" "testing" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" ) func TestChangeDefaultBranch(t *testing.T) { @@ -38,3 +42,96 @@ func TestChangeDefaultBranch(t *testing.T) { }) session.MakeRequest(t, req, http.StatusNotFound) } + +func checkDivergence(t *testing.T, session *TestSession, branchesURL, expectedDefaultBranch string, expectedBranchToDivergence map[string]git.DivergeObject) { + req := NewRequest(t, "GET", branchesURL) + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + + branchNodes := htmlDoc.doc.Find(".branch-name").Nodes + branchNames := []string{} + for _, node := range branchNodes { + branchNames = append(branchNames, node.FirstChild.Data) + } + + expectBranchCount := len(expectedBranchToDivergence) + + assert.Len(t, branchNames, expectBranchCount+1) + assert.Equal(t, expectedDefaultBranch, branchNames[0]) + + allCountBehindNodes := htmlDoc.doc.Find(".count-behind").Nodes + allCountAheadNodes := htmlDoc.doc.Find(".count-ahead").Nodes + + assert.Len(t, allCountAheadNodes, expectBranchCount) + assert.Len(t, allCountBehindNodes, expectBranchCount) + + for i := range expectBranchCount { + branchName := branchNames[i+1] + assert.Contains(t, expectedBranchToDivergence, branchName) + + expectedCountAhead := expectedBranchToDivergence[branchName].Ahead + expectedCountBehind := expectedBranchToDivergence[branchName].Behind + countAhead, err := strconv.Atoi(allCountAheadNodes[i].FirstChild.Data) + assert.NoError(t, err) + countBehind, err := strconv.Atoi(allCountBehindNodes[i].FirstChild.Data) + assert.NoError(t, err) + + assert.Equal(t, expectedCountAhead, countAhead) + assert.Equal(t, expectedCountBehind, countBehind) + } +} + +func TestChangeDefaultBranchDivergence(t *testing.T) { + defer tests.PrepareTestEnv(t)() + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + + session := loginUser(t, owner.Name) + branchesURL := fmt.Sprintf("/%s/%s/branches", owner.Name, repo.Name) + settingsBranchesURL := fmt.Sprintf("/%s/%s/settings/branches", owner.Name, repo.Name) + + // check branch divergence before switching default branch + expectedBranchToDivergenceBefore := map[string]git.DivergeObject{ + "not-signed": { + Ahead: 0, + Behind: 0, + }, + "good-sign-not-yet-validated": { + Ahead: 0, + Behind: 1, + }, + "good-sign": { + Ahead: 1, + Behind: 3, + }, + } + checkDivergence(t, session, branchesURL, "master", expectedBranchToDivergenceBefore) + + // switch default branch + newDefaultBranch := "good-sign-not-yet-validated" + csrf := GetUserCSRFToken(t, session) + req := NewRequestWithValues(t, "POST", settingsBranchesURL, map[string]string{ + "_csrf": csrf, + "action": "default_branch", + "branch": newDefaultBranch, + }) + session.MakeRequest(t, req, http.StatusSeeOther) + + // check branch divergence after switching default branch + expectedBranchToDivergenceAfter := map[string]git.DivergeObject{ + "master": { + Ahead: 1, + Behind: 0, + }, + "not-signed": { + Ahead: 1, + Behind: 0, + }, + "good-sign": { + Ahead: 1, + Behind: 2, + }, + } + checkDivergence(t, session, branchesURL, newDefaultBranch, expectedBranchToDivergenceAfter) +}