From 18e95af24f762cc1ad0ec23f619721422fe8e68a Mon Sep 17 00:00:00 2001 From: Jason Song Date: Wed, 20 Mar 2024 09:45:27 +0800 Subject: [PATCH] Restore deleted branches when syncing (#29898) Regression of #29493. If a branch has been deleted, repushing it won't restore it. Lunny may have noticed that, but I didn't delve into the comment then overlooked it: https://github.com/go-gitea/gitea/pull/29493#discussion_r1509046867 The additional comments added are to explain the issue I found during testing, which are unrelated to the fixes. (cherry picked from commit f371f84fa3456c2a71470632b6458d81e4892a54) --- routers/private/hook_post_receive.go | 4 ++++ tests/integration/git_push_test.go | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index f5527cb15..fff47caa8 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -75,6 +75,10 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { updates = append(updates, option) if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") { // put the master/main branch first + // FIXME: It doesn't always work, since the master/main branch may not be the first batch of updates. + // If the user pushes many branches at once, the Git hook will call the internal API in batches, rather than all at once. + // See https://github.com/go-gitea/gitea/blob/cb52b17f92e2d2293f7c003649743464492bca48/cmd/hook.go#L27 + // If the user executes `git push origin --all` and pushes more than 30 branches, the master/main may not be the default branch. copy(updates[1:], updates) updates[0] = option } diff --git a/tests/integration/git_push_test.go b/tests/integration/git_push_test.go index cb2910b17..0a3572480 100644 --- a/tests/integration/git_push_test.go +++ b/tests/integration/git_push_test.go @@ -69,6 +69,23 @@ func testGitPush(t *testing.T, u *url.URL) { return pushed, deleted }) }) + + t.Run("Push to deleted branch", func(t *testing.T) { + runTestGitPush(t, u, func(t *testing.T, gitPath string) (pushed, deleted []string) { + doGitPushTestRepository(gitPath, "origin", "master")(t) // make sure master is the default branch instead of a branch we are going to delete + pushed = append(pushed, "master") + + doGitCreateBranch(gitPath, "branch-1")(t) + doGitPushTestRepository(gitPath, "origin", "branch-1")(t) + pushed = append(pushed, "branch-1") + + // delete and restore + doGitPushTestRepository(gitPath, "origin", "--delete", "branch-1")(t) + doGitPushTestRepository(gitPath, "origin", "branch-1")(t) + + return pushed, deleted + }) + }) } func runTestGitPush(t *testing.T, u *url.URL, gitOperation func(t *testing.T, gitPath string) (pushed, deleted []string)) {