fix(repo): mark repository as non-empty before git push returns (#40102)

The post-receive hook syncs pushed branches to the database, but
`is_empty` and the default branch of an empty repository were only
updated later by the `push_update` queue. Until then the API treated the
repository as empty (branch list `null`, `GET /branches/{branch}` 500),
and the queue overwrote the default branch chosen by the hook or set via
the API.

`SyncBranchesToDB` now initializes an empty repository and repairs a
default branch missing in git in its locked transaction, so the state is
final when `git push` returns. The push queue and web file edits retry
it while the repository is still empty.

- The default branch is the configured one if it exists, else `main`,
else `master`, else the first branch by name, like GitLab. HEAD follows
it.
- A first push of several branches no longer depends on push order. The
push that initializes a repository still prints no pull request hints,
like GitHub.

---------

Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
Zettat123
2026-11-07 03:20:25 +00:00
committed by GitHub
parent b8b270bac9
commit c74f2f9216
6 changed files with 136 additions and 80 deletions

View File

@@ -103,7 +103,13 @@ func testGitPush(t *testing.T, u *url.URL) {
doGitCreateBranch(gitPath, branchName)(t)
}
pushed = append(pushed, "master")
doGitPushTestRepository(gitPath, "origin", "--all")(t)
_, stderr, err := gitcmd.NewCommand("push", "origin", "--all").WithDir(gitPath).RunStdString(t.Context())
require.NoError(t, err)
assert.NotContains(t, stderr, "Create a new pull request")
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 2, LowerName: "repo-to-push"})
assert.False(t, repo.IsEmpty)
assert.Equal(t, "master", repo.DefaultBranch)
return pushed, deleted
})
})
@@ -139,7 +145,9 @@ func testGitPush(t *testing.T, u *url.URL) {
pushed = append(pushed, "master")
// push all, so that master is not changed
doGitPushTestRepository(gitPath, "origin", "--all")(t)
_, stderr, err := gitcmd.NewCommand("push", "origin", "--all").WithDir(gitPath).RunStdString(t.Context())
require.NoError(t, err)
assert.Contains(t, stderr, "Create a new pull request for 'branch-2'")
return pushed, deleted
})