Skip to content

Commit d68a613

Browse files
AdamMajerlunny6543
authored
Add support for sha256 repositories (#23894)
Currently only SHA1 repositories are supported by Gitea. This adds support for alternate SHA256 with the additional aim of easier support for additional hash types in the future. Fixes: #13794 Limited by: go-git/go-git#899 Depend on: #28138 <img width="776" alt="图片" src="https://github.com/go-gitea/gitea/assets/81045/5448c9a7-608e-4341-a149-5dd0069c9447"> --------- Co-authored-by: Lunny Xiao <[email protected]> Co-authored-by: 6543 <[email protected]>
1 parent 07ba4d9 commit d68a613

File tree

98 files changed

+834
-76
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+834
-76
lines changed

models/git/commit_status.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type CommitStatus struct {
3737
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
3838
TargetURL string `xorm:"TEXT"`
3939
Description string `xorm:"TEXT"`
40-
ContextHash string `xorm:"char(40) index"`
40+
ContextHash string `xorm:"VARCHAR(64) index"`
4141
Context string `xorm:"TEXT"`
4242
Creator *user_model.User `xorm:"-"`
4343
CreatorID int64

models/issues/comment.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ type Comment struct {
270270
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
271271

272272
// Reference issue in commit message
273-
CommitSHA string `xorm:"VARCHAR(40)"`
273+
CommitSHA string `xorm:"VARCHAR(64)"`
274274

275275
Attachments []*repo_model.Attachment `xorm:"-"`
276276
Reactions ReactionList `xorm:"-"`

models/issues/pull.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,11 @@ type PullRequest struct {
171171
HeadBranch string
172172
HeadCommitID string `xorm:"-"`
173173
BaseBranch string
174-
MergeBase string `xorm:"VARCHAR(40)"`
174+
MergeBase string `xorm:"VARCHAR(64)"`
175175
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
176176

177177
HasMerged bool `xorm:"INDEX"`
178-
MergedCommitID string `xorm:"VARCHAR(40)"`
178+
MergedCommitID string `xorm:"VARCHAR(64)"`
179179
MergerID int64 `xorm:"INDEX"`
180180
Merger *user_model.User `xorm:"-"`
181181
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`

models/issues/review.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type Review struct {
116116
Content string `xorm:"TEXT"`
117117
// Official is a review made by an assigned approver (counts towards approval)
118118
Official bool `xorm:"NOT NULL DEFAULT false"`
119-
CommitID string `xorm:"VARCHAR(40)"`
119+
CommitID string `xorm:"VARCHAR(64)"`
120120
Stale bool `xorm:"NOT NULL DEFAULT false"`
121121
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
122122

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# type Repository struct {
2+
# ID int64 `xorm:"pk autoincr"`
3+
# }
4+
-
5+
id: 1
6+
-
7+
id: 2
8+
-
9+
id: 3
10+
-
11+
id: 10

models/migrations/migrations.go

+2
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ var migrations = []Migration{
556556
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
557557
// v285 -> v286
558558
NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
559+
// v286 -> v287
560+
NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
559561
}
560562

561563
// GetCurrentDBVersion returns the current db version

models/migrations/v1_22/v286.go

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
package v1_22 //nolint
4+
5+
import (
6+
"errors"
7+
"fmt"
8+
9+
"code.gitea.io/gitea/modules/log"
10+
"code.gitea.io/gitea/modules/setting"
11+
12+
"xorm.io/xorm"
13+
)
14+
15+
func expandHashReferencesToSha256(x *xorm.Engine) error {
16+
alteredTables := [][2]string{
17+
{"commit_status", "context_hash"},
18+
{"comment", "commit_sha"},
19+
{"pull_request", "merge_base"},
20+
{"pull_request", "merged_commit_id"},
21+
{"review", "commit_id"},
22+
{"review_state", "commit_sha"},
23+
{"repo_archiver", "commit_id"},
24+
{"release", "sha1"},
25+
{"repo_indexer_status", "commit_sha"},
26+
}
27+
28+
db := x.NewSession()
29+
defer db.Close()
30+
31+
if err := db.Begin(); err != nil {
32+
return err
33+
}
34+
35+
if !setting.Database.Type.IsSQLite3() {
36+
if setting.Database.Type.IsMSSQL() {
37+
// drop indexes that need to be re-created afterwards
38+
droppedIndexes := []string{
39+
"DROP INDEX commit_status.IDX_commit_status_context_hash",
40+
"DROP INDEX review_state.UQE_review_state_pull_commit_user",
41+
"DROP INDEX repo_archiver.UQE_repo_archiver_s",
42+
}
43+
for _, s := range droppedIndexes {
44+
_, err := db.Exec(s)
45+
if err != nil {
46+
return errors.New(s + " " + err.Error())
47+
}
48+
}
49+
}
50+
51+
for _, alts := range alteredTables {
52+
var err error
53+
if setting.Database.Type.IsMySQL() {
54+
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
55+
} else if setting.Database.Type.IsMSSQL() {
56+
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
57+
} else {
58+
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` TYPE VARCHAR(64)", alts[0], alts[1]))
59+
}
60+
if err != nil {
61+
return fmt.Errorf("alter column '%s' of table '%s' failed: %w", alts[1], alts[0], err)
62+
}
63+
}
64+
65+
if setting.Database.Type.IsMSSQL() {
66+
recreateIndexes := []string{
67+
"CREATE INDEX IDX_commit_status_context_hash ON commit_status(context_hash)",
68+
"CREATE UNIQUE INDEX UQE_review_state_pull_commit_user ON review_state(user_id, pull_id, commit_sha)",
69+
"CREATE UNIQUE INDEX UQE_repo_archiver_s ON repo_archiver(repo_id, type, commit_id)",
70+
}
71+
for _, s := range recreateIndexes {
72+
_, err := db.Exec(s)
73+
if err != nil {
74+
return errors.New(s + " " + err.Error())
75+
}
76+
}
77+
}
78+
}
79+
log.Debug("Updated database tables to hold SHA256 git hash references")
80+
81+
return db.Commit()
82+
}
83+
84+
func addObjectFormatNameToRepository(x *xorm.Engine) error {
85+
type Repository struct {
86+
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
87+
}
88+
89+
if err := x.Sync(new(Repository)); err != nil {
90+
return err
91+
}
92+
93+
// Here to catch weird edge-cases where column constraints above are
94+
// not applied by the DB backend
95+
_, err := x.Exec("UPDATE repository set object_format_name = 'sha1' WHERE object_format_name = '' or object_format_name IS NULL")
96+
return err
97+
}
98+
99+
func AdjustDBForSha256(x *xorm.Engine) error {
100+
if err := expandHashReferencesToSha256(x); err != nil {
101+
return err
102+
}
103+
return addObjectFormatNameToRepository(x)
104+
}

models/migrations/v1_22/v286_test.go

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_22 //nolint
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/migrations/base"
10+
11+
"github.com/stretchr/testify/assert"
12+
"xorm.io/xorm"
13+
)
14+
15+
func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
16+
type Repository struct { // old struct
17+
ID int64 `xorm:"pk autoincr"`
18+
}
19+
20+
// Prepare and load the testing database
21+
return base.PrepareTestEnv(t, 0, new(Repository))
22+
}
23+
24+
func Test_RepositoryFormat(t *testing.T) {
25+
x, deferable := PrepareOldRepository(t)
26+
defer deferable()
27+
28+
type Repository struct {
29+
ID int64 `xorm:"pk autoincr"`
30+
ObjectFormatName string `xorg:"not null default('sha1')"`
31+
}
32+
33+
repo := new(Repository)
34+
35+
// check we have some records to migrate
36+
count, err := x.Count(new(Repository))
37+
assert.NoError(t, err)
38+
assert.EqualValues(t, 4, count)
39+
40+
assert.NoError(t, AdjustDBForSha256(x))
41+
42+
repo.ID = 20
43+
repo.ObjectFormatName = "sha256"
44+
_, err = x.Insert(repo)
45+
assert.NoError(t, err)
46+
47+
count, err = x.Count(new(Repository))
48+
assert.NoError(t, err)
49+
assert.EqualValues(t, 5, count)
50+
51+
repo = new(Repository)
52+
ok, err := x.ID(2).Get(repo)
53+
assert.NoError(t, err)
54+
assert.EqualValues(t, true, ok)
55+
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
56+
57+
repo = new(Repository)
58+
ok, err = x.ID(20).Get(repo)
59+
assert.NoError(t, err)
60+
assert.EqualValues(t, true, ok)
61+
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
62+
}

models/pull/review_state.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type ReviewState struct {
3939
ID int64 `xorm:"pk autoincr"`
4040
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
4141
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
42-
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
42+
CommitSHA string `xorm:"NOT NULL VARCHAR(64) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
4343
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
4444
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
4545
}

models/repo/archiver.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type RepoArchiver struct { //revive:disable-line:exported
3333
RepoID int64 `xorm:"index unique(s)"`
3434
Type git.ArchiveType `xorm:"unique(s)"`
3535
Status ArchiverStatus
36-
CommitID string `xorm:"VARCHAR(40) unique(s)"`
36+
CommitID string `xorm:"VARCHAR(64) unique(s)"`
3737
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
3838
}
3939

models/repo/release.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ type Release struct {
7575
Target string
7676
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
7777
Title string
78-
Sha1 string `xorm:"VARCHAR(40)"`
78+
Sha1 string `xorm:"VARCHAR(64)"`
7979
NumCommits int64
8080
NumCommitsBehind int64 `xorm:"-"`
8181
Note string `xorm:"TEXT"`

models/repo/repo.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ type Repository struct {
180180
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
181181
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
182182
Topics []string `xorm:"TEXT JSON"`
183-
ObjectFormatName string `xorm:"-"`
183+
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
184184

185185
TrustModel TrustModelType
186186

@@ -276,10 +276,6 @@ func (repo *Repository) AfterLoad() {
276276
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
277277
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
278278
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
279-
280-
// this is a temporary behaviour to support old repos, next step is to store the object format in the database
281-
// and read from database so this line could be removed. To not depend on git module, we use a constant variable here
282-
repo.ObjectFormatName = "sha1"
283279
}
284280

285281
// LoadAttributes loads attributes of the repository.

models/repo/repo_indexer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const (
2727
type RepoIndexerStatus struct { //revive:disable-line:exported
2828
ID int64 `xorm:"pk autoincr"`
2929
RepoID int64 `xorm:"INDEX(s)"`
30-
CommitSha string `xorm:"VARCHAR(40)"`
30+
CommitSha string `xorm:"VARCHAR(64)"`
3131
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
3232
}
3333

0 commit comments

Comments
 (0)