Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
wxiaoguang committed Dec 28, 2023
1 parent c706b3e commit f3a702b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
18 changes: 17 additions & 1 deletion models/git/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"xorm.io/builder"
"xorm.io/xorm/schemas"
)

// ErrBranchNotExist represents an error that branch with such name does not exist.
Expand Down Expand Up @@ -103,7 +105,7 @@ func (err ErrBranchesEqual) Unwrap() error {
type Branch struct {
ID int64
RepoID int64 `xorm:"UNIQUE(s)"`
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
Name string `xorm:"UNIQUE(s) NOT NULL"`
CommitID string
CommitMessage string `xorm:"TEXT"` // it only stores the message summary (the first line)
PusherID int64
Expand All @@ -117,6 +119,20 @@ type Branch struct {
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
}

// TableCollations is to make the "name" column case-sensitve for MySQL/MSSQL
func (b *Branch) TableCollations() []*schemas.Collation {
if setting.Database.Type.IsMySQL() {
return []*schemas.Collation{
{Column: "name", Name: "utf8mb4_bin"},
}
} else if setting.Database.Type.IsMSSQL() {
return []*schemas.Collation{
{Column: "name", Name: "Latin1_General_CS_AS"},
}
}
return nil
}

func (b *Branch) LoadDeletedBy(ctx context.Context) (err error) {
if b.DeletedBy == nil {
b.DeletedBy, err = user_model.GetUserByID(ctx, b.DeletedByID)
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,8 @@ var migrations = []Migration{
NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
// v283 -> v284
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
// v284 -> v285
NewMigration("Alter branch name collation to be case-sensitvie", v1_22.AlterBranchNameCollation),
}

// GetCurrentDBVersion returns the current db version
Expand Down
29 changes: 29 additions & 0 deletions models/migrations/v1_22/v284.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_22 //nolint

import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"

"xorm.io/xorm"
)

func AlterBranchNameCollation(x *xorm.Engine) error {
if setting.Database.Type.IsMySQL() {
_, err := x.Exec("ALTER TABLE branch MODIFY COLUMN `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL")
return err
} else if setting.Database.Type.IsMSSQL() {
if _, err := x.Exec("DROP INDEX UQE_branch_s ON branch"); err != nil {
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
}
if _, err := x.Exec("ALTER TABLE branch ALTER COLUMN [name] nvarchar(255) COLLATE Latin1_General_CS_AS NOT NULL"); err != nil {
return err
}
if _, err := x.Exec("CREATE UNIQUE NONCLUSTERED INDEX UQE_branch_s ON branch (repo_id ASC, [name] ASC)"); err != nil {
return err
}
}
return nil
}
25 changes: 25 additions & 0 deletions models/migrations/v1_22/v284_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_22 //nolint

import (
"testing"

"code.gitea.io/gitea/models/migrations/base"

"github.com/stretchr/testify/assert"
)

func TestAlterBranchNameCollation(t *testing.T) {
type Branch struct {
ID int64
RepoID int64 `xorm:"UNIQUE(s)"`
Name string `xorm:"UNIQUE(s) NOT NULL"`
}

x, deferable := base.PrepareTestEnv(t, 0, new(Branch))
defer deferable()

assert.NoError(t, AlterBranchNameCollation(x))
}
12 changes: 12 additions & 0 deletions tests/integration/api_branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
NewBranch: "branch_2",
ExpectedHTTPStatus: http.StatusCreated,
},
// Trying to create a case-sensive branch name
{
OldBranch: "new_branch_from_master_1",
NewBranch: "Branch_2",
ExpectedHTTPStatus: http.StatusCreated,
},
// Trying to create a branch with UTF8
{
OldBranch: "master",
NewBranch: "test-👀",
ExpectedHTTPStatus: http.StatusCreated,
},
// Trying to create from a branch which does not exist
{
OldBranch: "does_not_exist",
Expand Down

0 comments on commit f3a702b

Please sign in to comment.