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: https://github.com/go-git/go-git/issues/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 <xiaolunwen@gmail.com> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
parent
07ba4d9f87
commit
d68a613ba8
@ -37,7 +37,7 @@ type CommitStatus struct {
|
|||||||
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
|
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
|
||||||
TargetURL string `xorm:"TEXT"`
|
TargetURL string `xorm:"TEXT"`
|
||||||
Description string `xorm:"TEXT"`
|
Description string `xorm:"TEXT"`
|
||||||
ContextHash string `xorm:"char(40) index"`
|
ContextHash string `xorm:"VARCHAR(64) index"`
|
||||||
Context string `xorm:"TEXT"`
|
Context string `xorm:"TEXT"`
|
||||||
Creator *user_model.User `xorm:"-"`
|
Creator *user_model.User `xorm:"-"`
|
||||||
CreatorID int64
|
CreatorID int64
|
||||||
|
@ -270,7 +270,7 @@ type Comment struct {
|
|||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||||
|
|
||||||
// Reference issue in commit message
|
// Reference issue in commit message
|
||||||
CommitSHA string `xorm:"VARCHAR(40)"`
|
CommitSHA string `xorm:"VARCHAR(64)"`
|
||||||
|
|
||||||
Attachments []*repo_model.Attachment `xorm:"-"`
|
Attachments []*repo_model.Attachment `xorm:"-"`
|
||||||
Reactions ReactionList `xorm:"-"`
|
Reactions ReactionList `xorm:"-"`
|
||||||
|
@ -171,11 +171,11 @@ type PullRequest struct {
|
|||||||
HeadBranch string
|
HeadBranch string
|
||||||
HeadCommitID string `xorm:"-"`
|
HeadCommitID string `xorm:"-"`
|
||||||
BaseBranch string
|
BaseBranch string
|
||||||
MergeBase string `xorm:"VARCHAR(40)"`
|
MergeBase string `xorm:"VARCHAR(64)"`
|
||||||
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
|
|
||||||
HasMerged bool `xorm:"INDEX"`
|
HasMerged bool `xorm:"INDEX"`
|
||||||
MergedCommitID string `xorm:"VARCHAR(40)"`
|
MergedCommitID string `xorm:"VARCHAR(64)"`
|
||||||
MergerID int64 `xorm:"INDEX"`
|
MergerID int64 `xorm:"INDEX"`
|
||||||
Merger *user_model.User `xorm:"-"`
|
Merger *user_model.User `xorm:"-"`
|
||||||
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
|
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
|
||||||
|
@ -116,7 +116,7 @@ type Review struct {
|
|||||||
Content string `xorm:"TEXT"`
|
Content string `xorm:"TEXT"`
|
||||||
// Official is a review made by an assigned approver (counts towards approval)
|
// Official is a review made by an assigned approver (counts towards approval)
|
||||||
Official bool `xorm:"NOT NULL DEFAULT false"`
|
Official bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
CommitID string `xorm:"VARCHAR(40)"`
|
CommitID string `xorm:"VARCHAR(64)"`
|
||||||
Stale bool `xorm:"NOT NULL DEFAULT false"`
|
Stale bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
|
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
# type Repository struct {
|
||||||
|
# ID int64 `xorm:"pk autoincr"`
|
||||||
|
# }
|
||||||
|
-
|
||||||
|
id: 1
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
-
|
||||||
|
id: 10
|
@ -556,6 +556,8 @@ var migrations = []Migration{
|
|||||||
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
|
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
|
||||||
// v285 -> v286
|
// v285 -> v286
|
||||||
NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
|
NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
|
||||||
|
// v286 -> v287
|
||||||
|
NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
104
models/migrations/v1_22/v286.go
Normal file
104
models/migrations/v1_22/v286.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
package v1_22 //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func expandHashReferencesToSha256(x *xorm.Engine) error {
|
||||||
|
alteredTables := [][2]string{
|
||||||
|
{"commit_status", "context_hash"},
|
||||||
|
{"comment", "commit_sha"},
|
||||||
|
{"pull_request", "merge_base"},
|
||||||
|
{"pull_request", "merged_commit_id"},
|
||||||
|
{"review", "commit_id"},
|
||||||
|
{"review_state", "commit_sha"},
|
||||||
|
{"repo_archiver", "commit_id"},
|
||||||
|
{"release", "sha1"},
|
||||||
|
{"repo_indexer_status", "commit_sha"},
|
||||||
|
}
|
||||||
|
|
||||||
|
db := x.NewSession()
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
if err := db.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !setting.Database.Type.IsSQLite3() {
|
||||||
|
if setting.Database.Type.IsMSSQL() {
|
||||||
|
// drop indexes that need to be re-created afterwards
|
||||||
|
droppedIndexes := []string{
|
||||||
|
"DROP INDEX commit_status.IDX_commit_status_context_hash",
|
||||||
|
"DROP INDEX review_state.UQE_review_state_pull_commit_user",
|
||||||
|
"DROP INDEX repo_archiver.UQE_repo_archiver_s",
|
||||||
|
}
|
||||||
|
for _, s := range droppedIndexes {
|
||||||
|
_, err := db.Exec(s)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(s + " " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, alts := range alteredTables {
|
||||||
|
var err error
|
||||||
|
if setting.Database.Type.IsMySQL() {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
} else if setting.Database.Type.IsMSSQL() {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
} else {
|
||||||
|
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` TYPE VARCHAR(64)", alts[0], alts[1]))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("alter column '%s' of table '%s' failed: %w", alts[1], alts[0], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if setting.Database.Type.IsMSSQL() {
|
||||||
|
recreateIndexes := []string{
|
||||||
|
"CREATE INDEX IDX_commit_status_context_hash ON commit_status(context_hash)",
|
||||||
|
"CREATE UNIQUE INDEX UQE_review_state_pull_commit_user ON review_state(user_id, pull_id, commit_sha)",
|
||||||
|
"CREATE UNIQUE INDEX UQE_repo_archiver_s ON repo_archiver(repo_id, type, commit_id)",
|
||||||
|
}
|
||||||
|
for _, s := range recreateIndexes {
|
||||||
|
_, err := db.Exec(s)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New(s + " " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Debug("Updated database tables to hold SHA256 git hash references")
|
||||||
|
|
||||||
|
return db.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func addObjectFormatNameToRepository(x *xorm.Engine) error {
|
||||||
|
type Repository struct {
|
||||||
|
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync(new(Repository)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here to catch weird edge-cases where column constraints above are
|
||||||
|
// not applied by the DB backend
|
||||||
|
_, err := x.Exec("UPDATE repository set object_format_name = 'sha1' WHERE object_format_name = '' or object_format_name IS NULL")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AdjustDBForSha256(x *xorm.Engine) error {
|
||||||
|
if err := expandHashReferencesToSha256(x); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return addObjectFormatNameToRepository(x)
|
||||||
|
}
|
62
models/migrations/v1_22/v286_test.go
Normal file
62
models/migrations/v1_22/v286_test.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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"
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
|
||||||
|
type Repository struct { // old struct
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare and load the testing database
|
||||||
|
return base.PrepareTestEnv(t, 0, new(Repository))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_RepositoryFormat(t *testing.T) {
|
||||||
|
x, deferable := PrepareOldRepository(t)
|
||||||
|
defer deferable()
|
||||||
|
|
||||||
|
type Repository struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
ObjectFormatName string `xorg:"not null default('sha1')"`
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := new(Repository)
|
||||||
|
|
||||||
|
// check we have some records to migrate
|
||||||
|
count, err := x.Count(new(Repository))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 4, count)
|
||||||
|
|
||||||
|
assert.NoError(t, AdjustDBForSha256(x))
|
||||||
|
|
||||||
|
repo.ID = 20
|
||||||
|
repo.ObjectFormatName = "sha256"
|
||||||
|
_, err = x.Insert(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
count, err = x.Count(new(Repository))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 5, count)
|
||||||
|
|
||||||
|
repo = new(Repository)
|
||||||
|
ok, err := x.ID(2).Get(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, true, ok)
|
||||||
|
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
|
||||||
|
|
||||||
|
repo = new(Repository)
|
||||||
|
ok, err = x.ID(20).Get(repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, true, ok)
|
||||||
|
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
|
||||||
|
}
|
@ -39,7 +39,7 @@ type ReviewState struct {
|
|||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
||||||
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
|
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
|
||||||
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
|
CommitSHA string `xorm:"NOT NULL VARCHAR(64) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
|
||||||
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
|
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
|
||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ type RepoArchiver struct { //revive:disable-line:exported
|
|||||||
RepoID int64 `xorm:"index unique(s)"`
|
RepoID int64 `xorm:"index unique(s)"`
|
||||||
Type git.ArchiveType `xorm:"unique(s)"`
|
Type git.ArchiveType `xorm:"unique(s)"`
|
||||||
Status ArchiverStatus
|
Status ArchiverStatus
|
||||||
CommitID string `xorm:"VARCHAR(40) unique(s)"`
|
CommitID string `xorm:"VARCHAR(64) unique(s)"`
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ type Release struct {
|
|||||||
Target string
|
Target string
|
||||||
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
||||||
Title string
|
Title string
|
||||||
Sha1 string `xorm:"VARCHAR(40)"`
|
Sha1 string `xorm:"VARCHAR(64)"`
|
||||||
NumCommits int64
|
NumCommits int64
|
||||||
NumCommitsBehind int64 `xorm:"-"`
|
NumCommitsBehind int64 `xorm:"-"`
|
||||||
Note string `xorm:"TEXT"`
|
Note string `xorm:"TEXT"`
|
||||||
|
@ -180,7 +180,7 @@ type Repository struct {
|
|||||||
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
|
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
|
||||||
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
|
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
|
||||||
Topics []string `xorm:"TEXT JSON"`
|
Topics []string `xorm:"TEXT JSON"`
|
||||||
ObjectFormatName string `xorm:"-"`
|
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
|
||||||
|
|
||||||
TrustModel TrustModelType
|
TrustModel TrustModelType
|
||||||
|
|
||||||
@ -276,10 +276,6 @@ func (repo *Repository) AfterLoad() {
|
|||||||
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
|
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
|
||||||
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
|
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
|
||||||
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
|
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
|
||||||
|
|
||||||
// this is a temporary behaviour to support old repos, next step is to store the object format in the database
|
|
||||||
// and read from database so this line could be removed. To not depend on git module, we use a constant variable here
|
|
||||||
repo.ObjectFormatName = "sha1"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadAttributes loads attributes of the repository.
|
// LoadAttributes loads attributes of the repository.
|
||||||
|
@ -27,7 +27,7 @@ const (
|
|||||||
type RepoIndexerStatus struct { //revive:disable-line:exported
|
type RepoIndexerStatus struct { //revive:disable-line:exported
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
RepoID int64 `xorm:"INDEX(s)"`
|
RepoID int64 `xorm:"INDEX(s)"`
|
||||||
CommitSha string `xorm:"VARCHAR(40)"`
|
CommitSha string `xorm:"VARCHAR(64)"`
|
||||||
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
144
modules/git/blame_sha256_test.go
Normal file
144
modules/git/blame_sha256_test.go
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReadingBlameOutputSha256(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
|
||||||
|
repo, err := OpenRepository(ctx, "./tests/repos/repo5_pulls_sha256")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
commit, err := repo.GetCommit("0b69b7bb649b5d46e14cabb6468685e5dd721290acc7ffe604d37cde57927345")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
parts := []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca",
|
||||||
|
Lines: []string{
|
||||||
|
"# test_repo",
|
||||||
|
"Test repository for testing migration from github to gitea",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "0b69b7bb649b5d46e14cabb6468685e5dd721290acc7ffe604d37cde57927345",
|
||||||
|
Lines: []string{"", "Do not make any changes to this repo it is used for unit testing"},
|
||||||
|
PreviousSha: "1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca",
|
||||||
|
PreviousPath: "README.md",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, bypass := range []bool{false, true} {
|
||||||
|
blameReader, err := CreateBlameReader(ctx, Sha256ObjectFormat, "./tests/repos/repo5_pulls_sha256", commit, "README.md", bypass)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, blameReader)
|
||||||
|
defer blameReader.Close()
|
||||||
|
|
||||||
|
assert.False(t, blameReader.UsesIgnoreRevs())
|
||||||
|
|
||||||
|
for _, part := range parts {
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, part, actualPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all parts have been read
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.Nil(t, actualPart)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
|
||||||
|
repo, err := OpenRepository(ctx, "./tests/repos/repo6_blame_sha256")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
full := []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
Lines: []string{"changed line"},
|
||||||
|
PreviousSha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
PreviousPath: "blame.txt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line", ""},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
CommitID string
|
||||||
|
UsesIgnoreRevs bool
|
||||||
|
Bypass bool
|
||||||
|
Parts []*BlamePart
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
CommitID: "e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3",
|
||||||
|
UsesIgnoreRevs: true,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: []*BlamePart{
|
||||||
|
{
|
||||||
|
Sha: "ab2b57a4fa476fb2edb74dafa577caf918561abbaa8fba0c8dc63c412e17a7cc",
|
||||||
|
Lines: []string{"line", "line", "changed line", "line", "line", ""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: true,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CommitID: "9347b0198cd1f25017579b79d0938fa89dba34ad2514f0dd92f6bc975ed1a2fe",
|
||||||
|
UsesIgnoreRevs: false,
|
||||||
|
Bypass: false,
|
||||||
|
Parts: full,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
commit, err := repo.GetCommit(c.CommitID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
blameReader, err := CreateBlameReader(ctx, repo.objectFormat, "./tests/repos/repo6_blame_sha256", commit, "blame.txt", c.Bypass)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, blameReader)
|
||||||
|
defer blameReader.Close()
|
||||||
|
|
||||||
|
assert.Equal(t, c.UsesIgnoreRevs, blameReader.UsesIgnoreRevs())
|
||||||
|
|
||||||
|
for _, part := range c.Parts {
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, part, actualPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all parts have been read
|
||||||
|
actualPart, err := blameReader.NextPart()
|
||||||
|
assert.Nil(t, actualPart)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -85,6 +85,8 @@ readLoop:
|
|||||||
commit.Committer.Decode(data)
|
commit.Committer.Decode(data)
|
||||||
_, _ = payloadSB.Write(line)
|
_, _ = payloadSB.Write(line)
|
||||||
case "gpgsig":
|
case "gpgsig":
|
||||||
|
fallthrough
|
||||||
|
case "gpgsig-sha256": // FIXME: no intertop, so only 1 exists at present.
|
||||||
_, _ = signatureSB.Write(data)
|
_, _ = signatureSB.Write(data)
|
||||||
_ = signatureSB.WriteByte('\n')
|
_ = signatureSB.WriteByte('\n')
|
||||||
pgpsig = true
|
pgpsig = true
|
||||||
|
195
modules/git/commit_sha256_test.go
Normal file
195
modules/git/commit_sha256_test.go
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
//go:build !gogit
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCommitsCountSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
commitsCount, err := CommitsCount(DefaultContext,
|
||||||
|
CommitsCountOptions{
|
||||||
|
RepoPath: bareRepo1Path,
|
||||||
|
Revision: []string{"f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc"},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(3), commitsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitsCountWithoutBaseSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
commitsCount, err := CommitsCount(DefaultContext,
|
||||||
|
CommitsCountOptions{
|
||||||
|
RepoPath: bareRepo1Path,
|
||||||
|
Not: "main",
|
||||||
|
Revision: []string{"branch1"},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(2), commitsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFullCommitIDSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "f004f4")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetFullCommitIDErrorSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "unknown")
|
||||||
|
assert.Empty(t, id)
|
||||||
|
if assert.Error(t, err) {
|
||||||
|
assert.EqualError(t, err, "object does not exist [id: unknown, rel_path: ]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitFromReaderSha256(t *testing.T) {
|
||||||
|
commitString := `9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 commit 1114
|
||||||
|
tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e
|
||||||
|
parent 26e9ccc29fad747e9c5d9f4c9ddeb7eff61cc45ef6a8dc258cbeb181afc055e8
|
||||||
|
author Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
committer Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
gpgsig-sha256 -----BEGIN PGP SIGNATURE-----
|
||||||
|
` + " " + `
|
||||||
|
iQIrBAABCgAtFiEES+fB08xlgTrzSdQvhkUIsBsmec8FAmU/wKoPHGFtYWplckBz
|
||||||
|
dXNlLmRlAAoJEIZFCLAbJnnP4s4PQIJATa++WPzR6/H4etT7bsOGoMyguEJYyWOd
|
||||||
|
aTybplzT7QAL7h2to0QszGabtzMJPIA39xSFZNYNN30voK5YyyYibXluPKgjemfK
|
||||||
|
WNXwF+gkwgZI38gSvKf+vlqI+EYyIFe19wOhiju0m8SIlB5NEPiWHa17q2mqmqqx
|
||||||
|
1FWa2JdqLPYjAtSLFXeSZegrY5V1FxdemyMUONkg8YO9OSIMZiE0GsnnOXQ3xcT4
|
||||||
|
JTCnmlUxIKw689UiEY80JopUIq+Wl7+qq9507IYYSUCyB6JazL42AKMzVCbD+qBP
|
||||||
|
oOzh/hafYgk9H9qCQXaLbmvs17zXRpicig1bAzqgAy1FDelvpERyRTydEajSLIG6
|
||||||
|
U1cRCkgXCZ0NfsYNPPmBa8b3+rnstypXYTbyMwTln7FfUAaGo6o9JYiPMkzxlmsy
|
||||||
|
zfp/tcaY8+LlBL9aOJjtv+a0p+HrpCGd6CCa4ARfphTLq8QRSSh8uzlB9N+6HnRI
|
||||||
|
VAEUo6ecdDxSpyt2naeg9pKus/BRi7P6g4B1hkk/zZstUX/QP4IQuAJbXjkvsC+X
|
||||||
|
HKRr3NlRM/DygzTyj0gN74uoa0goCIbyAQhiT42nm0cuhM7uN/W0ayrlZjGF1cbR
|
||||||
|
8NCJUL2Nwj0ywKIavC99Ipkb8AsFwpVT6U6effs6
|
||||||
|
=xybZ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
|
||||||
|
signed commit`
|
||||||
|
|
||||||
|
sha := &Sha256Hash{
|
||||||
|
0x94, 0x33, 0xb2, 0xa6, 0x2b, 0x96, 0x4c, 0x17, 0xa4, 0x48, 0x5a, 0xe1, 0x80, 0xf4, 0x5f, 0x59,
|
||||||
|
0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0,
|
||||||
|
}
|
||||||
|
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare_sha256"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, gitRepo)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if !assert.NotNil(t, commitFromReader) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.EqualValues(t, sha, commitFromReader.ID)
|
||||||
|
assert.EqualValues(t, `-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIrBAABCgAtFiEES+fB08xlgTrzSdQvhkUIsBsmec8FAmU/wKoPHGFtYWplckBz
|
||||||
|
dXNlLmRlAAoJEIZFCLAbJnnP4s4PQIJATa++WPzR6/H4etT7bsOGoMyguEJYyWOd
|
||||||
|
aTybplzT7QAL7h2to0QszGabtzMJPIA39xSFZNYNN30voK5YyyYibXluPKgjemfK
|
||||||
|
WNXwF+gkwgZI38gSvKf+vlqI+EYyIFe19wOhiju0m8SIlB5NEPiWHa17q2mqmqqx
|
||||||
|
1FWa2JdqLPYjAtSLFXeSZegrY5V1FxdemyMUONkg8YO9OSIMZiE0GsnnOXQ3xcT4
|
||||||
|
JTCnmlUxIKw689UiEY80JopUIq+Wl7+qq9507IYYSUCyB6JazL42AKMzVCbD+qBP
|
||||||
|
oOzh/hafYgk9H9qCQXaLbmvs17zXRpicig1bAzqgAy1FDelvpERyRTydEajSLIG6
|
||||||
|
U1cRCkgXCZ0NfsYNPPmBa8b3+rnstypXYTbyMwTln7FfUAaGo6o9JYiPMkzxlmsy
|
||||||
|
zfp/tcaY8+LlBL9aOJjtv+a0p+HrpCGd6CCa4ARfphTLq8QRSSh8uzlB9N+6HnRI
|
||||||
|
VAEUo6ecdDxSpyt2naeg9pKus/BRi7P6g4B1hkk/zZstUX/QP4IQuAJbXjkvsC+X
|
||||||
|
HKRr3NlRM/DygzTyj0gN74uoa0goCIbyAQhiT42nm0cuhM7uN/W0ayrlZjGF1cbR
|
||||||
|
8NCJUL2Nwj0ywKIavC99Ipkb8AsFwpVT6U6effs6
|
||||||
|
=xybZ
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
`, commitFromReader.Signature.Signature)
|
||||||
|
assert.EqualValues(t, `tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e
|
||||||
|
parent 26e9ccc29fad747e9c5d9f4c9ddeb7eff61cc45ef6a8dc258cbeb181afc055e8
|
||||||
|
author Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
committer Adam Majer <amajer@suse.de> 1698676906 +0100
|
||||||
|
|
||||||
|
signed commit`, commitFromReader.Signature.Payload)
|
||||||
|
assert.EqualValues(t, "Adam Majer <amajer@suse.de>", commitFromReader.Author.String())
|
||||||
|
|
||||||
|
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
commitFromReader.CommitMessage += "\n\n"
|
||||||
|
commitFromReader.Signature.Payload += "\n\n"
|
||||||
|
assert.EqualValues(t, commitFromReader, commitFromReader2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasPreviousCommitSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
|
||||||
|
|
||||||
|
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer repo.Close()
|
||||||
|
|
||||||
|
commit, err := repo.GetCommit("f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
parentSHA := MustIDFromString("b0ec7af4547047f12d5093e37ef8f1b3b5415ed8ee17894d43a34d7d34212e9c")
|
||||||
|
notParentSHA := MustIDFromString("42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236")
|
||||||
|
assert.Equal(t, repo.objectFormat, parentSHA.Type())
|
||||||
|
assert.Equal(t, repo.objectFormat.Name(), "sha256")
|
||||||
|
|
||||||
|
haz, err := commit.HasPreviousCommit(parentSHA)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, haz)
|
||||||
|
|
||||||
|
hazNot, err := commit.HasPreviousCommit(notParentSHA)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, hazNot)
|
||||||
|
|
||||||
|
selfNot, err := commit.HasPreviousCommit(commit.ID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, selfNot)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCommitFileStatusMergesSha256(t *testing.T) {
|
||||||
|
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge_sha256")
|
||||||
|
|
||||||
|
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expected := CommitFileStatus{
|
||||||
|
[]string{
|
||||||
|
"add_file.txt",
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
[]string{
|
||||||
|
"to_modify.txt",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expected.Added, commitFileStatus.Added)
|
||||||
|
assert.Equal(t, expected.Removed, commitFileStatus.Removed)
|
||||||
|
assert.Equal(t, expected.Modified, commitFileStatus.Modified)
|
||||||
|
|
||||||
|
expected = CommitFileStatus{
|
||||||
|
[]string{},
|
||||||
|
[]string{
|
||||||
|
"to_remove.txt",
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
commitFileStatus, err = GetCommitFileStatus(DefaultContext, bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, expected.Added, commitFileStatus.Added)
|
||||||
|
assert.Equal(t, expected.Removed, commitFileStatus.Removed)
|
||||||
|
assert.Equal(t, expected.Modified, commitFileStatus.Modified)
|
||||||
|
}
|
@ -185,7 +185,13 @@ func InitFull(ctx context.Context) (err error) {
|
|||||||
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
|
||||||
}
|
}
|
||||||
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
||||||
SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil
|
SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
|
||||||
|
if SupportHashSha256 {
|
||||||
|
SupportedObjectFormats = append(SupportedObjectFormats, Sha256ObjectFormat)
|
||||||
|
} else {
|
||||||
|
log.Warn("sha256 hash support is disabled - requires Git >= 2.42. Gogit is currently unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
if setting.LFS.StartServer {
|
if setting.LFS.StartServer {
|
||||||
if CheckGitVersionAtLeast("2.1.2") != nil {
|
if CheckGitVersionAtLeast("2.1.2") != nil {
|
||||||
return errors.New("LFS server support requires Git >= 2.1.2")
|
return errors.New("LFS server support requires Git >= 2.1.2")
|
||||||
|
@ -5,6 +5,7 @@ package git
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@ -12,6 +13,9 @@ import (
|
|||||||
// sha1Pattern can be used to determine if a string is an valid sha
|
// sha1Pattern can be used to determine if a string is an valid sha
|
||||||
var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
|
var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
|
||||||
|
|
||||||
|
// sha256Pattern can be used to determine if a string is an valid sha
|
||||||
|
var sha256Pattern = regexp.MustCompile(`^[0-9a-f]{4,64}$`)
|
||||||
|
|
||||||
type ObjectFormat interface {
|
type ObjectFormat interface {
|
||||||
// Name returns the name of the object format
|
// Name returns the name of the object format
|
||||||
Name() string
|
Name() string
|
||||||
@ -29,11 +33,12 @@ type ObjectFormat interface {
|
|||||||
ComputeHash(t ObjectType, content []byte) ObjectID
|
ComputeHash(t ObjectType, content []byte) ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA1 Type */
|
||||||
type Sha1ObjectFormatImpl struct{}
|
type Sha1ObjectFormatImpl struct{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
emptyObjectID = &Sha1Hash{}
|
emptySha1ObjectID = &Sha1Hash{}
|
||||||
emptyTree = &Sha1Hash{
|
emptySha1Tree = &Sha1Hash{
|
||||||
0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
|
0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
|
||||||
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
|
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
|
||||||
}
|
}
|
||||||
@ -41,11 +46,11 @@ var (
|
|||||||
|
|
||||||
func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
|
func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
|
||||||
func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID {
|
func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID {
|
||||||
return emptyObjectID
|
return emptySha1ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Sha1ObjectFormatImpl) EmptyTree() ObjectID {
|
func (Sha1ObjectFormatImpl) EmptyTree() ObjectID {
|
||||||
return emptyTree
|
return emptySha1Tree
|
||||||
}
|
}
|
||||||
func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
|
func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
|
||||||
func (Sha1ObjectFormatImpl) IsValid(input string) bool {
|
func (Sha1ObjectFormatImpl) IsValid(input string) bool {
|
||||||
@ -72,11 +77,59 @@ func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID
|
|||||||
return &sha1
|
return &sha1
|
||||||
}
|
}
|
||||||
|
|
||||||
var Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
|
/* SHA256 Type */
|
||||||
|
type Sha256ObjectFormatImpl struct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptySha256ObjectID = &Sha256Hash{}
|
||||||
|
emptySha256Tree = &Sha256Hash{
|
||||||
|
0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
|
||||||
|
0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
|
||||||
|
0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
|
||||||
|
0x53, 0x21,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) Name() string { return "sha256" }
|
||||||
|
func (Sha256ObjectFormatImpl) EmptyObjectID() ObjectID {
|
||||||
|
return emptySha256ObjectID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) EmptyTree() ObjectID {
|
||||||
|
return emptySha256Tree
|
||||||
|
}
|
||||||
|
func (Sha256ObjectFormatImpl) FullLength() int { return 64 }
|
||||||
|
func (Sha256ObjectFormatImpl) IsValid(input string) bool {
|
||||||
|
return sha256Pattern.MatchString(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID {
|
||||||
|
var id Sha256Hash
|
||||||
|
copy(id[0:32], b)
|
||||||
|
return &id
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeHash compute the hash for a given ObjectType and content
|
||||||
|
func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
|
||||||
|
hasher := sha256.New()
|
||||||
|
_, _ = hasher.Write(t.Bytes())
|
||||||
|
_, _ = hasher.Write([]byte(" "))
|
||||||
|
_, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
|
||||||
|
_, _ = hasher.Write([]byte{0})
|
||||||
|
|
||||||
|
// HashSum generates a SHA256 for the provided hash
|
||||||
|
var sha256 Sha1Hash
|
||||||
|
copy(sha256[:], hasher.Sum(nil))
|
||||||
|
return &sha256
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
|
||||||
|
Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
|
||||||
|
)
|
||||||
|
|
||||||
var SupportedObjectFormats = []ObjectFormat{
|
var SupportedObjectFormats = []ObjectFormat{
|
||||||
Sha1ObjectFormat,
|
Sha1ObjectFormat,
|
||||||
// TODO: add sha256
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ObjectFormatFromName(name string) ObjectFormat {
|
func ObjectFormatFromName(name string) ObjectFormat {
|
||||||
|
@ -16,6 +16,7 @@ type ObjectID interface {
|
|||||||
Type() ObjectFormat
|
Type() ObjectFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA1 */
|
||||||
type Sha1Hash [20]byte
|
type Sha1Hash [20]byte
|
||||||
|
|
||||||
func (h *Sha1Hash) String() string {
|
func (h *Sha1Hash) String() string {
|
||||||
@ -39,6 +40,21 @@ func MustIDFromString(hexHash string) ObjectID {
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SHA256 */
|
||||||
|
type Sha256Hash [32]byte
|
||||||
|
|
||||||
|
func (h *Sha256Hash) String() string {
|
||||||
|
return hex.EncodeToString(h[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Sha256Hash) IsZero() bool {
|
||||||
|
empty := Sha256Hash{}
|
||||||
|
return bytes.Equal(empty[:], h[:])
|
||||||
|
}
|
||||||
|
func (h *Sha256Hash) RawValue() []byte { return h[:] }
|
||||||
|
func (*Sha256Hash) Type() ObjectFormat { return Sha256ObjectFormat }
|
||||||
|
|
||||||
|
/* utility */
|
||||||
func NewIDFromString(hexHash string) (ObjectID, error) {
|
func NewIDFromString(hexHash string) (ObjectID, error) {
|
||||||
var theObjectFormat ObjectFormat
|
var theObjectFormat ObjectFormat
|
||||||
for _, objectFormat := range SupportedObjectFormats {
|
for _, objectFormat := range SupportedObjectFormats {
|
||||||
|
@ -13,6 +13,8 @@ func ParseGogitHash(h plumbing.Hash) ObjectID {
|
|||||||
switch hash.Size {
|
switch hash.Size {
|
||||||
case 20:
|
case 20:
|
||||||
return Sha1ObjectFormat.MustID(h[:])
|
return Sha1ObjectFormat.MustID(h[:])
|
||||||
|
case 32:
|
||||||
|
return Sha256ObjectFormat.MustID(h[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -97,15 +97,12 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd := NewCommand(ctx, "init")
|
cmd := NewCommand(ctx, "init")
|
||||||
if SupportHashSha256 {
|
|
||||||
if objectFormatName == "" {
|
if !IsValidObjectFormat(objectFormatName) {
|
||||||
objectFormatName = Sha1ObjectFormat.Name()
|
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
||||||
}
|
|
||||||
if !IsValidObjectFormat(objectFormatName) {
|
|
||||||
return fmt.Errorf("invalid object format: %s", objectFormatName)
|
|
||||||
}
|
|
||||||
cmd.AddOptionValues("--object-format", objectFormatName)
|
|
||||||
}
|
}
|
||||||
|
cmd.AddOptionValues("--object-format", objectFormatName)
|
||||||
|
|
||||||
if bare {
|
if bare {
|
||||||
cmd.AddArguments("--bare")
|
cmd.AddArguments("--bare")
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var isGogit bool
|
||||||
|
|
||||||
// contextKey is a value for use with context.WithValue.
|
// contextKey is a value for use with context.WithValue.
|
||||||
type contextKey struct {
|
type contextKey struct {
|
||||||
name string
|
name string
|
||||||
|
@ -21,6 +21,10 @@ import (
|
|||||||
"github.com/go-git/go-git/v5/storage/filesystem"
|
"github.com/go-git/go-git/v5/storage/filesystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
isGogit = true
|
||||||
|
}
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
Path string
|
Path string
|
||||||
|
@ -15,6 +15,10 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
isGogit = false
|
||||||
|
}
|
||||||
|
|
||||||
// Repository represents a Git repository.
|
// Repository represents a Git repository.
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
Path string
|
Path string
|
||||||
|
1
modules/git/tests/repos/repo1_bare_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo1_bare_sha256/HEAD
Normal file
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo1_bare_sha256/config
Normal file
6
modules/git/tests/repos/repo1_bare_sha256/config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo1_bare_sha256/description
Normal file
1
modules/git/tests/repos/repo1_bare_sha256/description
Normal file
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
6
modules/git/tests/repos/repo1_bare_sha256/info/exclude
Normal file
6
modules/git/tests/repos/repo1_bare_sha256/info/exclude
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
7
modules/git/tests/repos/repo1_bare_sha256/info/refs
Normal file
7
modules/git/tests/repos/repo1_bare_sha256/info/refs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236 refs/heads/branch1
|
||||||
|
5bc2249e32e0ba40a08879fba2bd4e97a13cb345831549f4bc5649525da8f6cc refs/heads/branch2
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/heads/main
|
||||||
|
29a82d4fc02e19190fb489cc90d5730ed91970b49f4e39acda2798b3dd4f814e refs/tags/signed-tag
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/tags/signed-tag^{}
|
||||||
|
171822a62559f3aa28a00aa3785dbe915d6a8eb02712682740db44fc8bd2187a refs/tags/test
|
||||||
|
6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1 refs/tags/test^{}
|
Binary file not shown.
@ -0,0 +1,2 @@
|
|||||||
|
P pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack
|
||||||
|
|
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.bitmap
Normal file
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.bitmap
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.idx
Normal file
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.idx
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack
Normal file
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.rev
Normal file
BIN
modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.rev
Normal file
Binary file not shown.
8
modules/git/tests/repos/repo1_bare_sha256/packed-refs
Normal file
8
modules/git/tests/repos/repo1_bare_sha256/packed-refs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# pack-refs with: peeled fully-peeled sorted
|
||||||
|
42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236 refs/heads/branch1
|
||||||
|
5bc2249e32e0ba40a08879fba2bd4e97a13cb345831549f4bc5649525da8f6cc refs/heads/branch2
|
||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0 refs/heads/main
|
||||||
|
29a82d4fc02e19190fb489cc90d5730ed91970b49f4e39acda2798b3dd4f814e refs/tags/signed-tag
|
||||||
|
^9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0
|
||||||
|
171822a62559f3aa28a00aa3785dbe915d6a8eb02712682740db44fc8bd2187a refs/tags/test
|
||||||
|
^6aae864a3d1d0d6a5be0cc64028c1e7021e2632b031fd8eb82afc5a283d1c3d1
|
@ -0,0 +1 @@
|
|||||||
|
9433b2a62b964c17a4485ae180f45f595d3e69d31b786087775e28c6b6399df0
|
1
modules/git/tests/repos/repo5_pulls_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo5_pulls_sha256/HEAD
Normal file
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo5_pulls_sha256/config
Normal file
6
modules/git/tests/repos/repo5_pulls_sha256/config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo5_pulls_sha256/description
Normal file
1
modules/git/tests/repos/repo5_pulls_sha256/description
Normal file
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
4
modules/git/tests/repos/repo5_pulls_sha256/info/refs
Normal file
4
modules/git/tests/repos/repo5_pulls_sha256/info/refs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main
|
||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main-clone
|
||||||
|
7f50a4906503378b0bbb7d61bd2ca8d8d8ff4f7a2474980f99402d742ccc9665 refs/heads/test-patch-1
|
||||||
|
1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca refs/tags/v0.9.99
|
Binary file not shown.
@ -0,0 +1,2 @@
|
|||||||
|
P pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack
|
||||||
|
|
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.bitmap
Normal file
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.bitmap
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.idx
Normal file
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.idx
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack
Normal file
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.rev
Normal file
BIN
modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.rev
Normal file
Binary file not shown.
5
modules/git/tests/repos/repo5_pulls_sha256/packed-refs
Normal file
5
modules/git/tests/repos/repo5_pulls_sha256/packed-refs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# pack-refs with: peeled fully-peeled sorted
|
||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main
|
||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b refs/heads/main-clone
|
||||||
|
7f50a4906503378b0bbb7d61bd2ca8d8d8ff4f7a2474980f99402d742ccc9665 refs/heads/test-patch-1
|
||||||
|
1e35a51dc00fd7de730344c07061acfe80e8117e075ac979b6a29a3a045190ca refs/tags/v0.9.99
|
@ -0,0 +1 @@
|
|||||||
|
35ecd0f946c8baeb76fa5a3876f46bf35218655e2304d8505026fa4bfb496a4b
|
1
modules/git/tests/repos/repo6_blame_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo6_blame_sha256/HEAD
Normal file
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo6_blame_sha256/config
Normal file
6
modules/git/tests/repos/repo6_blame_sha256/config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo6_blame_sha256/description
Normal file
1
modules/git/tests/repos/repo6_blame_sha256/description
Normal file
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
6
modules/git/tests/repos/repo6_blame_sha256/info/exclude
Normal file
6
modules/git/tests/repos/repo6_blame_sha256/info/exclude
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
1
modules/git/tests/repos/repo6_blame_sha256/info/refs
Normal file
1
modules/git/tests/repos/repo6_blame_sha256/info/refs
Normal file
@ -0,0 +1 @@
|
|||||||
|
e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3 refs/heads/main
|
Binary file not shown.
@ -0,0 +1,2 @@
|
|||||||
|
P pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack
|
||||||
|
|
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap
Normal file
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx
Normal file
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack
Normal file
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev
Normal file
BIN
modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev
Normal file
Binary file not shown.
2
modules/git/tests/repos/repo6_blame_sha256/packed-refs
Normal file
2
modules/git/tests/repos/repo6_blame_sha256/packed-refs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# pack-refs with: peeled fully-peeled sorted
|
||||||
|
e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3 refs/heads/main
|
@ -0,0 +1 @@
|
|||||||
|
e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3
|
1
modules/git/tests/repos/repo6_merge_sha256/HEAD
Normal file
1
modules/git/tests/repos/repo6_merge_sha256/HEAD
Normal file
@ -0,0 +1 @@
|
|||||||
|
ref: refs/heads/main
|
6
modules/git/tests/repos/repo6_merge_sha256/config
Normal file
6
modules/git/tests/repos/repo6_merge_sha256/config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[core]
|
||||||
|
repositoryformatversion = 1
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
[extensions]
|
||||||
|
objectformat = sha256
|
1
modules/git/tests/repos/repo6_merge_sha256/description
Normal file
1
modules/git/tests/repos/repo6_merge_sha256/description
Normal file
@ -0,0 +1 @@
|
|||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
6
modules/git/tests/repos/repo6_merge_sha256/info/exclude
Normal file
6
modules/git/tests/repos/repo6_merge_sha256/info/exclude
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
4
modules/git/tests/repos/repo6_merge_sha256/info/refs
Normal file
4
modules/git/tests/repos/repo6_merge_sha256/info/refs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1 refs/heads/main
|
||||||
|
b45258e9823233edea2d40d183742f29630e1e69300479fb4a55eabfe9b1d8bf refs/heads/merge/add_file
|
||||||
|
ff2b996e2fa366146300e4c9e51ccb6818147b360e46fa1437334f4a690955ce refs/heads/merge/modify_file
|
||||||
|
da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172 refs/heads/merge/remove_file
|
Binary file not shown.
@ -0,0 +1,3 @@
|
|||||||
|
P pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack
|
||||||
|
P pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack
|
||||||
|
|
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.bitmap
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.bitmap
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.idx
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.idx
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.rev
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.rev
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack
Normal file
Binary file not shown.
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev
Normal file
BIN
modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev
Normal file
Binary file not shown.
5
modules/git/tests/repos/repo6_merge_sha256/packed-refs
Normal file
5
modules/git/tests/repos/repo6_merge_sha256/packed-refs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# pack-refs with: peeled fully-peeled sorted
|
||||||
|
d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1 refs/heads/main
|
||||||
|
b45258e9823233edea2d40d183742f29630e1e69300479fb4a55eabfe9b1d8bf refs/heads/merge/add_file
|
||||||
|
ff2b996e2fa366146300e4c9e51ccb6818147b360e46fa1437334f4a690955ce refs/heads/merge/modify_file
|
||||||
|
da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172 refs/heads/merge/remove_file
|
@ -0,0 +1 @@
|
|||||||
|
d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1
|
@ -45,19 +45,19 @@ var (
|
|||||||
|
|
||||||
// valid chars in encoded path and parameter: [-+~_%.a-zA-Z0-9/]
|
// valid chars in encoded path and parameter: [-+~_%.a-zA-Z0-9/]
|
||||||
|
|
||||||
// sha1CurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
|
// hashCurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
|
||||||
// Although SHA1 hashes are 40 chars long, the regex matches the hash from 7 to 40 chars in length
|
// Although SHA1 hashes are 40 chars long, SHA256 are 64, the regex matches the hash from 7 to 64 chars in length
|
||||||
// so that abbreviated hash links can be used as well. This matches git and GitHub usability.
|
// so that abbreviated hash links can be used as well. This matches git and GitHub usability.
|
||||||
sha1CurrentPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-f]{7,40})(?:\s|$|\)|\]|[.,](\s|$))`)
|
hashCurrentPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-f]{7,64})(?:\s|$|\)|\]|[.,](\s|$))`)
|
||||||
|
|
||||||
// shortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
|
// shortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
|
||||||
shortLinkPattern = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`)
|
shortLinkPattern = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`)
|
||||||
|
|
||||||
// anySHA1Pattern splits url containing SHA into parts
|
// anySHA1Pattern splits url containing SHA into parts
|
||||||
anySHA1Pattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40})(/[-+~_%.a-zA-Z0-9/]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
|
anyHashPattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40,64})(/[-+~_%.a-zA-Z0-9/]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
|
||||||
|
|
||||||
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
|
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
|
||||||
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,40})(\.\.\.?)([0-9a-f]{7,40})?(#[-+~_%.a-zA-Z0-9]+)?`)
|
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,64})(\.\.\.?)([0-9a-f]{7,64})?(#[-+~_%.a-zA-Z0-9]+)?`)
|
||||||
|
|
||||||
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
|
validLinksPattern = regexp.MustCompile(`^[a-z][\w-]+://`)
|
||||||
|
|
||||||
@ -171,13 +171,13 @@ type processor func(ctx *RenderContext, node *html.Node)
|
|||||||
var defaultProcessors = []processor{
|
var defaultProcessors = []processor{
|
||||||
fullIssuePatternProcessor,
|
fullIssuePatternProcessor,
|
||||||
comparePatternProcessor,
|
comparePatternProcessor,
|
||||||
fullSha1PatternProcessor,
|
fullHashPatternProcessor,
|
||||||
shortLinkProcessor,
|
shortLinkProcessor,
|
||||||
linkProcessor,
|
linkProcessor,
|
||||||
mentionProcessor,
|
mentionProcessor,
|
||||||
issueIndexPatternProcessor,
|
issueIndexPatternProcessor,
|
||||||
commitCrossReferencePatternProcessor,
|
commitCrossReferencePatternProcessor,
|
||||||
sha1CurrentPatternProcessor,
|
hashCurrentPatternProcessor,
|
||||||
emailAddressProcessor,
|
emailAddressProcessor,
|
||||||
emojiProcessor,
|
emojiProcessor,
|
||||||
emojiShortCodeProcessor,
|
emojiShortCodeProcessor,
|
||||||
@ -199,12 +199,12 @@ func PostProcess(
|
|||||||
var commitMessageProcessors = []processor{
|
var commitMessageProcessors = []processor{
|
||||||
fullIssuePatternProcessor,
|
fullIssuePatternProcessor,
|
||||||
comparePatternProcessor,
|
comparePatternProcessor,
|
||||||
fullSha1PatternProcessor,
|
fullHashPatternProcessor,
|
||||||
linkProcessor,
|
linkProcessor,
|
||||||
mentionProcessor,
|
mentionProcessor,
|
||||||
issueIndexPatternProcessor,
|
issueIndexPatternProcessor,
|
||||||
commitCrossReferencePatternProcessor,
|
commitCrossReferencePatternProcessor,
|
||||||
sha1CurrentPatternProcessor,
|
hashCurrentPatternProcessor,
|
||||||
emailAddressProcessor,
|
emailAddressProcessor,
|
||||||
emojiProcessor,
|
emojiProcessor,
|
||||||
emojiShortCodeProcessor,
|
emojiShortCodeProcessor,
|
||||||
@ -231,12 +231,12 @@ func RenderCommitMessage(
|
|||||||
var commitMessageSubjectProcessors = []processor{
|
var commitMessageSubjectProcessors = []processor{
|
||||||
fullIssuePatternProcessor,
|
fullIssuePatternProcessor,
|
||||||
comparePatternProcessor,
|
comparePatternProcessor,
|
||||||
fullSha1PatternProcessor,
|
fullHashPatternProcessor,
|
||||||
linkProcessor,
|
linkProcessor,
|
||||||
mentionProcessor,
|
mentionProcessor,
|
||||||
issueIndexPatternProcessor,
|
issueIndexPatternProcessor,
|
||||||
commitCrossReferencePatternProcessor,
|
commitCrossReferencePatternProcessor,
|
||||||
sha1CurrentPatternProcessor,
|
hashCurrentPatternProcessor,
|
||||||
emojiShortCodeProcessor,
|
emojiShortCodeProcessor,
|
||||||
emojiProcessor,
|
emojiProcessor,
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ func RenderIssueTitle(
|
|||||||
return renderProcessString(ctx, []processor{
|
return renderProcessString(ctx, []processor{
|
||||||
issueIndexPatternProcessor,
|
issueIndexPatternProcessor,
|
||||||
commitCrossReferencePatternProcessor,
|
commitCrossReferencePatternProcessor,
|
||||||
sha1CurrentPatternProcessor,
|
hashCurrentPatternProcessor,
|
||||||
emojiShortCodeProcessor,
|
emojiShortCodeProcessor,
|
||||||
emojiProcessor,
|
emojiProcessor,
|
||||||
}, title)
|
}, title)
|
||||||
@ -946,15 +946,15 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fullSha1PatternProcessor renders SHA containing URLs
|
// fullHashPatternProcessor renders SHA containing URLs
|
||||||
func fullSha1PatternProcessor(ctx *RenderContext, node *html.Node) {
|
func fullHashPatternProcessor(ctx *RenderContext, node *html.Node) {
|
||||||
if ctx.Metas == nil {
|
if ctx.Metas == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
next := node.NextSibling
|
next := node.NextSibling
|
||||||
for node != nil && node != next {
|
for node != nil && node != next {
|
||||||
m := anySHA1Pattern.FindStringSubmatchIndex(node.Data)
|
m := anyHashPattern.FindStringSubmatchIndex(node.Data)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1111,9 +1111,9 @@ func emojiProcessor(ctx *RenderContext, node *html.Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sha1CurrentPatternProcessor renders SHA1 strings to corresponding links that
|
// hashCurrentPatternProcessor renders SHA1 strings to corresponding links that
|
||||||
// are assumed to be in the same repository.
|
// are assumed to be in the same repository.
|
||||||
func sha1CurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
|
func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
|
||||||
if ctx.Metas == nil || ctx.Metas["user"] == "" || ctx.Metas["repo"] == "" || ctx.Metas["repoPath"] == "" {
|
if ctx.Metas == nil || ctx.Metas["user"] == "" || ctx.Metas["repo"] == "" || ctx.Metas["repoPath"] == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1124,7 +1124,7 @@ func sha1CurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
|
|||||||
ctx.ShaExistCache = make(map[string]bool)
|
ctx.ShaExistCache = make(map[string]bool)
|
||||||
}
|
}
|
||||||
for node != nil && node != next && start < len(node.Data) {
|
for node != nil && node != next && start < len(node.Data) {
|
||||||
m := sha1CurrentPattern.FindStringSubmatchIndex(node.Data[start:])
|
m := hashCurrentPattern.FindStringSubmatchIndex(node.Data[start:])
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -390,10 +390,10 @@ func TestRegExp_sha1CurrentPattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range trueTestCases {
|
for _, testCase := range trueTestCases {
|
||||||
assert.True(t, sha1CurrentPattern.MatchString(testCase))
|
assert.True(t, hashCurrentPattern.MatchString(testCase))
|
||||||
}
|
}
|
||||||
for _, testCase := range falseTestCases {
|
for _, testCase := range falseTestCases {
|
||||||
assert.False(t, sha1CurrentPattern.MatchString(testCase))
|
assert.False(t, hashCurrentPattern.MatchString(testCase))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ func TestRegExp_anySHA1Pattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range testCases {
|
for k, v := range testCases {
|
||||||
assert.Equal(t, anySHA1Pattern.FindStringSubmatch(k)[1:], v)
|
assert.Equal(t, anyHashPattern.FindStringSubmatch(k)[1:], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ var (
|
|||||||
crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+[#!][0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
crossReferenceIssueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+[#!][0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
||||||
// crossReferenceCommitPattern matches a string that references a commit in a different repository
|
// crossReferenceCommitPattern matches a string that references a commit in a different repository
|
||||||
// e.g. go-gitea/gitea@d8a994ef, go-gitea/gitea@d8a994ef243349f321568f9e36d5c3f444b99cae (7-40 characters)
|
// e.g. go-gitea/gitea@d8a994ef, go-gitea/gitea@d8a994ef243349f321568f9e36d5c3f444b99cae (7-40 characters)
|
||||||
crossReferenceCommitPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+)@([0-9a-f]{7,40})(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
crossReferenceCommitPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+)@([0-9a-f]{7,64})(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`)
|
||||||
// spaceTrimmedPattern let's find the trailing space
|
// spaceTrimmedPattern let's find the trailing space
|
||||||
spaceTrimmedPattern = regexp.MustCompile(`(?:.*[0-9a-zA-Z-_])\s`)
|
spaceTrimmedPattern = regexp.MustCompile(`(?:.*[0-9a-zA-Z-_])\s`)
|
||||||
// timeLogPattern matches string for time tracking
|
// timeLogPattern matches string for time tracking
|
||||||
|
@ -343,7 +343,7 @@ func TestFindRenderizableCommitCrossReference(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Input: "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd12340", // longer than 40 characters
|
Input: "go-gitea/gitea@abcd1234abcd1234abcd1234abcd1234abcd12341234512345123451234512345", // longer than 64 characters
|
||||||
Expected: nil,
|
Expected: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,9 @@ type Repository struct {
|
|||||||
AvatarURL string `json:"avatar_url"`
|
AvatarURL string `json:"avatar_url"`
|
||||||
Internal bool `json:"internal"`
|
Internal bool `json:"internal"`
|
||||||
MirrorInterval string `json:"mirror_interval"`
|
MirrorInterval string `json:"mirror_interval"`
|
||||||
|
// ObjectFormatName of the underlying git repository
|
||||||
|
// enum: sha1,sha256
|
||||||
|
ObjectFormatName string `json:"object_format_name"`
|
||||||
// swagger:strfmt date-time
|
// swagger:strfmt date-time
|
||||||
MirrorUpdated time.Time `json:"mirror_updated,omitempty"`
|
MirrorUpdated time.Time `json:"mirror_updated,omitempty"`
|
||||||
RepoTransfer *RepoTransfer `json:"repo_transfer"`
|
RepoTransfer *RepoTransfer `json:"repo_transfer"`
|
||||||
@ -139,6 +142,9 @@ type CreateRepoOption struct {
|
|||||||
// TrustModel of the repository
|
// TrustModel of the repository
|
||||||
// enum: default,collaborator,committer,collaboratorcommitter
|
// enum: default,collaborator,committer,collaboratorcommitter
|
||||||
TrustModel string `json:"trust_model"`
|
TrustModel string `json:"trust_model"`
|
||||||
|
// ObjectFormatName of the underlying git repository
|
||||||
|
// enum: sha1,sha256
|
||||||
|
ObjectFormatName string `json:"object_format_name" binding:"MaxSize(6)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditRepoOption options when editing a repository's properties
|
// EditRepoOption options when editing a repository's properties
|
||||||
|
@ -41,3 +41,7 @@ func (su *StringUtils) Cut(s, sep string) []any {
|
|||||||
func (su *StringUtils) EllipsisString(s string, max int) string {
|
func (su *StringUtils) EllipsisString(s string, max int) string {
|
||||||
return base.EllipsisString(s, max)
|
return base.EllipsisString(s, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (su *StringUtils) ToUpper(s string) string {
|
||||||
|
return strings.ToUpper(s)
|
||||||
|
}
|
||||||
|
@ -970,6 +970,8 @@ issue_labels_helper = Select an issue label set.
|
|||||||
license = License
|
license = License
|
||||||
license_helper = Select a license file.
|
license_helper = Select a license file.
|
||||||
license_helper_desc = A license governs what others can and can't do with your code. Not sure which one is right for your project? See <a target="_blank" rel="noopener noreferrer" href="%s">Choose a license.</a>
|
license_helper_desc = A license governs what others can and can't do with your code. Not sure which one is right for your project? See <a target="_blank" rel="noopener noreferrer" href="%s">Choose a license.</a>
|
||||||
|
object_format = Object Format
|
||||||
|
object_format_helper = Object format of the repository. Cannot be changed later. SHA1 is most compatible.
|
||||||
readme = README
|
readme = README
|
||||||
readme_helper = Select a README file template.
|
readme_helper = Select a README file template.
|
||||||
readme_helper_desc = This is the place where you can write a complete description for your project.
|
readme_helper_desc = This is the place where you can write a complete description for your project.
|
||||||
@ -1038,6 +1040,7 @@ desc.public = Public
|
|||||||
desc.template = Template
|
desc.template = Template
|
||||||
desc.internal = Internal
|
desc.internal = Internal
|
||||||
desc.archived = Archived
|
desc.archived = Archived
|
||||||
|
desc.sha256 = SHA256
|
||||||
|
|
||||||
template.items = Template Items
|
template.items = Template Items
|
||||||
template.git_content = Git Content (Default Branch)
|
template.git_content = Git Content (Default Branch)
|
||||||
|
@ -253,7 +253,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
|
|||||||
DefaultBranch: opt.DefaultBranch,
|
DefaultBranch: opt.DefaultBranch,
|
||||||
TrustModel: repo_model.ToTrustModel(opt.TrustModel),
|
TrustModel: repo_model.ToTrustModel(opt.TrustModel),
|
||||||
IsTemplate: opt.Template,
|
IsTemplate: opt.Template,
|
||||||
ObjectFormatName: git.Sha1ObjectFormat.Name(),
|
ObjectFormatName: opt.ObjectFormatName,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if repo_model.IsErrRepoAlreadyExist(err) {
|
if repo_model.IsErrRepoAlreadyExist(err) {
|
||||||
|
@ -36,8 +36,8 @@ func gitHTTPRouters(m *web.Route) {
|
|||||||
m.Methods("GET,OPTIONS", "/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
|
m.Methods("GET,OPTIONS", "/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
|
||||||
m.Methods("GET,OPTIONS", "/objects/info/packs", repo.GetInfoPacks)
|
m.Methods("GET,OPTIONS", "/objects/info/packs", repo.GetInfoPacks)
|
||||||
m.Methods("GET,OPTIONS", "/objects/info/{file:[^/]*}", repo.GetTextFile(""))
|
m.Methods("GET,OPTIONS", "/objects/info/{file:[^/]*}", repo.GetTextFile(""))
|
||||||
m.Methods("GET,OPTIONS", "/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
|
m.Methods("GET,OPTIONS", "/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38,62}}", repo.GetLooseObject)
|
||||||
m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
|
m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40,64}}.pack", repo.GetPackFile)
|
||||||
m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
|
m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40,64}}.idx", repo.GetIdxFile)
|
||||||
}, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb())
|
}, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb())
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,6 @@ func Create(ctx *context.Context) {
|
|||||||
ctx.Data["private"] = getRepoPrivate(ctx)
|
ctx.Data["private"] = getRepoPrivate(ctx)
|
||||||
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
||||||
ctx.Data["default_branch"] = setting.Repository.DefaultBranch
|
ctx.Data["default_branch"] = setting.Repository.DefaultBranch
|
||||||
ctx.Data["hash_type"] = "sha1"
|
|
||||||
|
|
||||||
ctxUser := checkContextUser(ctx, ctx.FormInt64("org"))
|
ctxUser := checkContextUser(ctx, ctx.FormInt64("org"))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
@ -179,6 +178,8 @@ func Create(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
|
||||||
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
|
||||||
|
ctx.Data["SupportedObjectFormats"] = git.SupportedObjectFormats
|
||||||
|
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplCreate)
|
ctx.HTML(http.StatusOK, tplCreate)
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1235,7 @@ func registerRoutes(m *web.Route) {
|
|||||||
Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
|
Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
|
||||||
m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch).
|
m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch).
|
||||||
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
|
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
|
||||||
m.Combo("/_cherrypick/{sha:([a-f0-9]{7,40})}/*").Get(repo.CherryPick).
|
m.Combo("/_cherrypick/{sha:([a-f0-9]{7,64})}/*").Get(repo.CherryPick).
|
||||||
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
|
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
|
||||||
}, repo.MustBeEditable)
|
}, repo.MustBeEditable)
|
||||||
m.Group("", func() {
|
m.Group("", func() {
|
||||||
@ -1377,8 +1377,8 @@ func registerRoutes(m *web.Route) {
|
|||||||
m.Combo("/*").
|
m.Combo("/*").
|
||||||
Get(repo.Wiki).
|
Get(repo.Wiki).
|
||||||
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
|
||||||
m.Get("/commit/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
m.Get("/commit/{sha:[a-f0-9]{7,64}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||||
m.Get("/commit/{sha:[a-f0-9]{7,40}}.{ext:patch|diff}", repo.RawDiff)
|
m.Get("/commit/{sha:[a-f0-9]{7,64}}.{ext:patch|diff}", repo.RawDiff)
|
||||||
}, repo.MustEnableWiki, func(ctx *context.Context) {
|
}, repo.MustEnableWiki, func(ctx *context.Context) {
|
||||||
ctx.Data["PageIsWiki"] = true
|
ctx.Data["PageIsWiki"] = true
|
||||||
ctx.Data["CloneButtonOriginLink"] = ctx.Repo.Repository.WikiCloneLink()
|
ctx.Data["CloneButtonOriginLink"] = ctx.Repo.Repository.WikiCloneLink()
|
||||||
@ -1498,9 +1498,9 @@ func registerRoutes(m *web.Route) {
|
|||||||
|
|
||||||
m.Group("", func() {
|
m.Group("", func() {
|
||||||
m.Get("/graph", repo.Graph)
|
m.Get("/graph", repo.Graph)
|
||||||
m.Get("/commit/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
m.Get("/commit/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
|
||||||
m.Get("/commit/{sha:([a-f0-9]{7,40})$}/load-branches-and-tags", repo.LoadBranchesAndTags)
|
m.Get("/commit/{sha:([a-f0-9]{7,64})$}/load-branches-and-tags", repo.LoadBranchesAndTags)
|
||||||
m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
|
m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
|
||||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||||
|
|
||||||
m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
|
m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed)
|
||||||
@ -1517,7 +1517,7 @@ func registerRoutes(m *web.Route) {
|
|||||||
m.Group("", func() {
|
m.Group("", func() {
|
||||||
m.Get("/forks", repo.Forks)
|
m.Get("/forks", repo.Forks)
|
||||||
}, context.RepoRef(), reqRepoCodeReader)
|
}, context.RepoRef(), reqRepoCodeReader)
|
||||||
m.Get("/commit/{sha:([a-f0-9]{7,40})}.{ext:patch|diff}", repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff)
|
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff)
|
||||||
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
|
||||||
|
|
||||||
m.Post("/{username}/{reponame}/lastcommit/*", ignSignInAndCsrf, context.RepoAssignment, context.UnitTypes(), context.RepoRefByType(context.RepoRefCommit), reqRepoCodeReader, repo.LastCommit)
|
m.Post("/{username}/{reponame}/lastcommit/*", ignSignInAndCsrf, context.RepoAssignment, context.UnitTypes(), context.RepoRefByType(context.RepoRefCommit), reqRepoCodeReader, repo.LastCommit)
|
||||||
|
@ -217,6 +217,10 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.ObjectFormatName == "" {
|
||||||
|
opts.ObjectFormatName = git.Sha1ObjectFormat.Name()
|
||||||
|
}
|
||||||
|
|
||||||
repo := &repo_model.Repository{
|
repo := &repo_model.Repository{
|
||||||
OwnerID: u.ID,
|
OwnerID: u.ID,
|
||||||
Owner: u,
|
Owner: u,
|
||||||
|
@ -76,17 +76,18 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
|
|||||||
defaultBranch = opts.SingleBranch
|
defaultBranch = opts.SingleBranch
|
||||||
}
|
}
|
||||||
repo := &repo_model.Repository{
|
repo := &repo_model.Repository{
|
||||||
OwnerID: owner.ID,
|
OwnerID: owner.ID,
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
OwnerName: owner.Name,
|
OwnerName: owner.Name,
|
||||||
Name: opts.Name,
|
Name: opts.Name,
|
||||||
LowerName: strings.ToLower(opts.Name),
|
LowerName: strings.ToLower(opts.Name),
|
||||||
Description: opts.Description,
|
Description: opts.Description,
|
||||||
DefaultBranch: defaultBranch,
|
DefaultBranch: defaultBranch,
|
||||||
IsPrivate: opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate,
|
IsPrivate: opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate,
|
||||||
IsEmpty: opts.BaseRepo.IsEmpty,
|
IsEmpty: opts.BaseRepo.IsEmpty,
|
||||||
IsFork: true,
|
IsFork: true,
|
||||||
ForkID: opts.BaseRepo.ID,
|
ForkID: opts.BaseRepo.ID,
|
||||||
|
ObjectFormatName: opts.BaseRepo.ObjectFormatName,
|
||||||
}
|
}
|
||||||
|
|
||||||
oldRepoPath := opts.BaseRepo.RepoPath()
|
oldRepoPath := opts.BaseRepo.RepoPath()
|
||||||
|
@ -67,6 +67,9 @@
|
|||||||
{{if .IsTemplate}}
|
{{if .IsTemplate}}
|
||||||
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if eq .ObjectFormatName "sha256"}}
|
||||||
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.sha256"}}</span>
|
||||||
|
{{end}}
|
||||||
{{if .IsMirror}}
|
{{if .IsMirror}}
|
||||||
{{svg "octicon-mirror"}}
|
{{svg "octicon-mirror"}}
|
||||||
{{else if .IsFork}}
|
{{else if .IsFork}}
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
{{if .IsTemplate}}
|
{{if .IsTemplate}}
|
||||||
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if eq .ObjectFormatName "sha256"}}
|
||||||
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.sha256"}}</span>
|
||||||
|
{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-item-trailing">
|
<div class="flex-item-trailing">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="three wide">{{ctx.Locale.Tr "repo.commits.author"}}</th>
|
<th class="three wide">{{ctx.Locale.Tr "repo.commits.author"}}</th>
|
||||||
<th class="two wide sha">SHA1</th>
|
<th class="two wide sha">{{StringUtils.ToUpper $.Repository.ObjectFormatName}}</th>
|
||||||
<th class="eight wide message">{{ctx.Locale.Tr "repo.commits.message"}}</th>
|
<th class="eight wide message">{{ctx.Locale.Tr "repo.commits.message"}}</th>
|
||||||
<th class="two wide right aligned">{{ctx.Locale.Tr "repo.commits.date"}}</th>
|
<th class="two wide right aligned">{{ctx.Locale.Tr "repo.commits.date"}}</th>
|
||||||
<th class="one wide"></th>
|
<th class="one wide"></th>
|
||||||
|
@ -185,6 +185,19 @@
|
|||||||
<input id="default_branch" name="default_branch" value="{{.default_branch}}" placeholder="{{.default_branch}}">
|
<input id="default_branch" name="default_branch" value="{{.default_branch}}" placeholder="{{.default_branch}}">
|
||||||
<span class="help">{{ctx.Locale.Tr "repo.default_branch_helper"}}</span>
|
<span class="help">{{ctx.Locale.Tr "repo.default_branch_helper"}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{ctx.Locale.Tr "repo.object_format"}}</label>
|
||||||
|
<div class="ui selection owner dropdown">
|
||||||
|
<input type="hidden" id="object_format_name" name="object_format_name" value="{{.DefaultObjectFormat.Name}}" required>
|
||||||
|
<div class="default text">{{.DefaultObjectFormat.Name}}</div>
|
||||||
|
<div class="menu">
|
||||||
|
{{range .SupportedObjectFormats}}
|
||||||
|
<div class="item" data-value="{{.Name}}">{{.Name}}</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="help">{{ctx.Locale.Tr "repo.object_format_helper"}}</span>
|
||||||
|
</div>
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{ctx.Locale.Tr "repo.template"}}</label>
|
<label>{{ctx.Locale.Tr "repo.template"}}</label>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
||||||
<div class="repo-icon" data-tooltip-content="{{ctx.Locale.Tr "repo.desc.template"}}">{{svg "octicon-repo-template" 18}}</div>
|
<div class="repo-icon" data-tooltip-content="{{ctx.Locale.Tr "repo.desc.template"}}">{{svg "octicon-repo-template" 18}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if eq .ObjectFormatName "sha256"}}
|
||||||
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.sha256"}}</span>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{if not (or .IsBeingCreated .IsBroken)}}
|
{{if not (or .IsBeingCreated .IsBroken)}}
|
||||||
|
18
templates/swagger/v1_json.tmpl
generated
18
templates/swagger/v1_json.tmpl
generated
@ -18370,6 +18370,15 @@
|
|||||||
"uniqueItems": true,
|
"uniqueItems": true,
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
},
|
},
|
||||||
|
"object_format_name": {
|
||||||
|
"description": "ObjectFormatName of the underlying git repository",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"sha1",
|
||||||
|
"sha256"
|
||||||
|
],
|
||||||
|
"x-go-name": "ObjectFormatName"
|
||||||
|
},
|
||||||
"private": {
|
"private": {
|
||||||
"description": "Whether the repository is private",
|
"description": "Whether the repository is private",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -22185,6 +22194,15 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Name"
|
"x-go-name": "Name"
|
||||||
},
|
},
|
||||||
|
"object_format_name": {
|
||||||
|
"description": "ObjectFormatName of the underlying git repository",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"sha1",
|
||||||
|
"sha256"
|
||||||
|
],
|
||||||
|
"x-go-name": "ObjectFormatName"
|
||||||
|
},
|
||||||
"open_issues_count": {
|
"open_issues_count": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64",
|
"format": "int64",
|
||||||
|
Loading…
Reference in New Issue
Block a user