Skip to content

Commit f321cdc

Browse files
Xinyu Zhouclarfontheyzeripathwxiaoguanglunny
authored
Add HEAD fix to gitea doctor (#21352) (#21751)
Backport #21352 Due to a bug in presumably an older version of Gitea, multiple of my repositories still have their HEADs pointing to a `master` branch while the default branch on the UI is listed as `main`. This adds a `gitea doctor` command that will fix all of the HEAD references for repos when they're not synchronized with the default branch in the DB. This will help with cloning to ensure that git automatically checks out the right branch, instead of a nonexistent one. Note: I'm not sure if I actually need to do more other than add a file here. Will try testing this out on my server soon. Co-authored-by: Clar Fon <[email protected]> Co-authored-by: zeripath <[email protected]> Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
1 parent f241201 commit f321cdc

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

modules/doctor/heads.go

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package doctor
6+
7+
import (
8+
"context"
9+
10+
repo_model "code.gitea.io/gitea/models/repo"
11+
"code.gitea.io/gitea/modules/git"
12+
"code.gitea.io/gitea/modules/log"
13+
)
14+
15+
func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error {
16+
numRepos := 0
17+
numHeadsBroken := 0
18+
numDefaultBranchesBroken := 0
19+
numReposUpdated := 0
20+
err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
21+
numRepos++
22+
runOpts := &git.RunOpts{Dir: repo.RepoPath()}
23+
24+
_, _, defaultBranchErr := git.NewCommand(ctx, "rev-parse", "--", repo.DefaultBranch).RunStdString(runOpts)
25+
26+
head, _, headErr := git.NewCommand(ctx, "symbolic-ref", "--short", "HEAD").RunStdString(runOpts)
27+
28+
// what we expect: default branch is valid, and HEAD points to it
29+
if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
30+
return nil
31+
}
32+
33+
if headErr != nil {
34+
numHeadsBroken++
35+
}
36+
if defaultBranchErr != nil {
37+
numDefaultBranchesBroken++
38+
}
39+
40+
// if default branch is broken, let the user fix that in the UI
41+
if defaultBranchErr != nil {
42+
logger.Warn("Default branch for %s/%s doesn't point to a valid commit", repo.OwnerName, repo.Name)
43+
return nil
44+
}
45+
46+
// if we're not autofixing, that's all we can do
47+
if !autofix {
48+
return nil
49+
}
50+
51+
// otherwise, let's try fixing HEAD
52+
err := git.NewCommand(ctx, "symbolic-ref", "--", "HEAD", repo.DefaultBranch).Run(runOpts)
53+
if err != nil {
54+
logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
55+
return nil
56+
}
57+
numReposUpdated++
58+
return nil
59+
})
60+
if err != nil {
61+
logger.Critical("Error when fixing repo HEADs: %v", err)
62+
}
63+
64+
if autofix {
65+
logger.Info("Out of %d repos, HEADs for %d are now fixed and HEADS for %d are still broken", numRepos, numReposUpdated, numDefaultBranchesBroken+numHeadsBroken-numReposUpdated)
66+
} else {
67+
if numHeadsBroken == 0 && numDefaultBranchesBroken == 0 {
68+
logger.Info("All %d repos have their HEADs in the correct state")
69+
} else {
70+
if numHeadsBroken == 0 && numDefaultBranchesBroken != 0 {
71+
logger.Critical("Default branches are broken for %d/%d repos", numDefaultBranchesBroken, numRepos)
72+
} else if numHeadsBroken != 0 && numDefaultBranchesBroken == 0 {
73+
logger.Warn("HEADs are broken for %d/%d repos", numHeadsBroken, numRepos)
74+
} else {
75+
logger.Critical("Out of %d repos, HEADS are broken for %d and default branches are broken for %d", numRepos, numHeadsBroken, numDefaultBranchesBroken)
76+
}
77+
}
78+
}
79+
80+
return err
81+
}
82+
83+
func init() {
84+
Register(&Check{
85+
Title: "Synchronize repo HEADs",
86+
Name: "synchronize-repo-heads",
87+
IsDefault: true,
88+
Run: synchronizeRepoHeads,
89+
Priority: 7,
90+
})
91+
}

0 commit comments

Comments
 (0)