Skip to content

Commit d0ebd57

Browse files
committed
fix
1 parent c706b3e commit d0ebd57

File tree

6 files changed

+93
-9
lines changed

6 files changed

+93
-9
lines changed

models/git/branch.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import (
1313
user_model "code.gitea.io/gitea/models/user"
1414
"code.gitea.io/gitea/modules/git"
1515
"code.gitea.io/gitea/modules/log"
16+
"code.gitea.io/gitea/modules/setting"
1617
"code.gitea.io/gitea/modules/timeutil"
1718
"code.gitea.io/gitea/modules/util"
1819

1920
"xorm.io/builder"
21+
"xorm.io/xorm/schemas"
2022
)
2123

2224
// ErrBranchNotExist represents an error that branch with such name does not exist.
@@ -103,7 +105,7 @@ func (err ErrBranchesEqual) Unwrap() error {
103105
type Branch struct {
104106
ID int64
105107
RepoID int64 `xorm:"UNIQUE(s)"`
106-
Name string `xorm:"UNIQUE(s) NOT NULL"` // git's ref-name is case-sensitive internally, however, in some databases (mssql, mysql, by default), it's case-insensitive at the moment
108+
Name string `xorm:"UNIQUE(s) NOT NULL"`
107109
CommitID string
108110
CommitMessage string `xorm:"TEXT"` // it only stores the message summary (the first line)
109111
PusherID int64
@@ -117,6 +119,20 @@ type Branch struct {
117119
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
118120
}
119121

122+
// TableCollations is to make the "name" column case-sensitve for MySQL/MSSQL
123+
func (b *Branch) TableCollations() []*schemas.Collation {
124+
if setting.Database.Type.IsMySQL() {
125+
return []*schemas.Collation{
126+
{Column: "name", Name: "utf8mb4_bin"},
127+
}
128+
} else if setting.Database.Type.IsMSSQL() {
129+
return []*schemas.Collation{
130+
{Column: "name", Name: "Latin1_General_CS_AS"},
131+
}
132+
}
133+
return nil
134+
}
135+
120136
func (b *Branch) LoadDeletedBy(ctx context.Context) (err error) {
121137
if b.DeletedBy == nil {
122138
b.DeletedBy, err = user_model.GetUserByID(ctx, b.DeletedByID)

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,8 @@ var migrations = []Migration{
552552
NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
553553
// v283 -> v284
554554
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
555+
// v284 -> v285
556+
NewMigration("Alter branch name collation to be case-sensitive", v1_22.AlterBranchNameCollation),
555557
}
556558

557559
// GetCurrentDBVersion returns the current db version

models/migrations/v1_22/v283_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ import (
77
"testing"
88

99
"code.gitea.io/gitea/models/migrations/base"
10+
11+
"github.com/stretchr/testify/assert"
1012
)
1113

1214
func Test_AddCombinedIndexToIssueUser(t *testing.T) {
1315
type IssueUser struct {
14-
UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID.
15-
IssueID int64 `xorm:"INDEX unique(uid_to_issue)"`
16+
ID int64 `xorm:"pk autoincr"`
17+
UID int64 `xorm:"INDEX"` // User ID.
18+
IssueID int64 `xorm:"INDEX"`
19+
IsRead bool
20+
IsMentioned bool
1621
}
1722

1823
// Prepare and load the testing database
1924
x, deferable := base.PrepareTestEnv(t, 0, new(IssueUser))
2025
defer deferable()
21-
if x == nil || t.Failed() {
22-
return
23-
}
2426

25-
if err := AddCombinedIndexToIssueUser(x); err != nil {
26-
t.Fatal(err)
27-
}
27+
assert.NoError(t, AddCombinedIndexToIssueUser(x))
2828
}

models/migrations/v1_22/v284.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package v1_22 //nolint
5+
6+
import (
7+
"code.gitea.io/gitea/modules/log"
8+
"code.gitea.io/gitea/modules/setting"
9+
10+
"xorm.io/xorm"
11+
)
12+
13+
func AlterBranchNameCollation(x *xorm.Engine) error {
14+
if setting.Database.Type.IsMySQL() {
15+
_, err := x.Exec("ALTER TABLE branch MODIFY COLUMN `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL")
16+
return err
17+
} else if setting.Database.Type.IsMSSQL() {
18+
if _, err := x.Exec("DROP INDEX UQE_branch_s ON branch"); err != nil {
19+
log.Error("Failed to drop index UQE_branch_s on branch: %v", err) // ignore this error, in case the index has been dropped in previous migration
20+
}
21+
if _, err := x.Exec("ALTER TABLE branch ALTER COLUMN [name] nvarchar(255) COLLATE Latin1_General_CS_AS NOT NULL"); err != nil {
22+
return err
23+
}
24+
if _, err := x.Exec("CREATE UNIQUE NONCLUSTERED INDEX UQE_branch_s ON branch (repo_id ASC, [name] ASC)"); err != nil {
25+
return err
26+
}
27+
}
28+
return nil
29+
}

models/migrations/v1_22/v284_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
)
13+
14+
func TestAlterBranchNameCollation(t *testing.T) {
15+
type Branch struct {
16+
ID int64
17+
RepoID int64 `xorm:"UNIQUE(s)"`
18+
Name string `xorm:"UNIQUE(s) NOT NULL"`
19+
}
20+
21+
x, deferable := base.PrepareTestEnv(t, 0, new(Branch))
22+
defer deferable()
23+
24+
assert.NoError(t, AlterBranchNameCollation(x))
25+
}

tests/integration/api_branch_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,18 @@ func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
142142
NewBranch: "branch_2",
143143
ExpectedHTTPStatus: http.StatusCreated,
144144
},
145+
// Trying to create a case-sensitive branch name
146+
{
147+
OldBranch: "new_branch_from_master_1",
148+
NewBranch: "Branch_2",
149+
ExpectedHTTPStatus: http.StatusCreated,
150+
},
151+
// Trying to create a branch with UTF8
152+
{
153+
OldBranch: "master",
154+
NewBranch: "test-👀",
155+
ExpectedHTTPStatus: http.StatusCreated,
156+
},
145157
// Trying to create from a branch which does not exist
146158
{
147159
OldBranch: "does_not_exist",

0 commit comments

Comments
 (0)