From d68a613ba8fd860863a3465b5b5945b191b87b25 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Fri, 19 Jan 2024 16:05:02 +0000 Subject: [PATCH] Add support for sha256 repositories (#23894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 图片 --------- Co-authored-by: Lunny Xiao Co-authored-by: 6543 <6543@obermui.de> --- models/git/commit_status.go | 2 +- models/issues/comment.go | 2 +- models/issues/pull.go | 4 +- models/issues/review.go | 2 +- .../Test_RepositoryFormat/repository.yml | 11 + models/migrations/migrations.go | 2 + models/migrations/v1_22/v286.go | 104 ++++++++++ models/migrations/v1_22/v286_test.go | 62 ++++++ models/pull/review_state.go | 2 +- models/repo/archiver.go | 2 +- models/repo/release.go | 2 +- models/repo/repo.go | 6 +- models/repo/repo_indexer.go | 2 +- modules/git/blame_sha256_test.go | 144 +++++++++++++ modules/git/commit_reader.go | 2 + modules/git/commit_sha256_test.go | 195 ++++++++++++++++++ modules/git/git.go | 8 +- modules/git/object_format.go | 65 +++++- modules/git/object_id.go | 16 ++ modules/git/object_id_gogit.go | 2 + modules/git/repo.go | 13 +- modules/git/repo_base.go | 2 + modules/git/repo_base_gogit.go | 4 + modules/git/repo_base_nogogit.go | 4 + .../git/tests/repos/repo1_bare_sha256/HEAD | 1 + .../git/tests/repos/repo1_bare_sha256/config | 6 + .../tests/repos/repo1_bare_sha256/description | 1 + .../repos/repo1_bare_sha256/info/exclude | 6 + .../tests/repos/repo1_bare_sha256/info/refs | 7 + .../objects/info/commit-graph | Bin 0 -> 2048 bytes .../repo1_bare_sha256/objects/info/packs | 2 + ...65970b0c38c6b495d5fc034bc7a7b95334b.bitmap | Bin 0 -> 710 bytes ...78665970b0c38c6b495d5fc034bc7a7b95334b.idx | Bin 0 -> 2576 bytes ...8665970b0c38c6b495d5fc034bc7a7b95334b.pack | Bin 0 -> 5656 bytes ...78665970b0c38c6b495d5fc034bc7a7b95334b.rev | Bin 0 -> 224 bytes .../tests/repos/repo1_bare_sha256/packed-refs | 8 + .../repos/repo1_bare_sha256/refs/heads/main | 1 + .../git/tests/repos/repo5_pulls_sha256/HEAD | 1 + .../git/tests/repos/repo5_pulls_sha256/config | 6 + .../repos/repo5_pulls_sha256/description | 1 + .../tests/repos/repo5_pulls_sha256/info/refs | 4 + .../objects/info/commit-graph | Bin 0 -> 1544 bytes .../repo5_pulls_sha256/objects/info/packs | 2 + ...45d4a02b788eb26c31022a362312660a29d.bitmap | Bin 0 -> 414 bytes ...fe145d4a02b788eb26c31022a362312660a29d.idx | Bin 0 -> 1736 bytes ...e145d4a02b788eb26c31022a362312660a29d.pack | Bin 0 -> 3140 bytes ...fe145d4a02b788eb26c31022a362312660a29d.rev | Bin 0 -> 140 bytes .../repos/repo5_pulls_sha256/packed-refs | 5 + .../repos/repo5_pulls_sha256/refs/heads/main | 1 + .../git/tests/repos/repo6_blame_sha256/HEAD | 1 + .../git/tests/repos/repo6_blame_sha256/config | 6 + .../repos/repo6_blame_sha256/description | 1 + .../repos/repo6_blame_sha256/info/exclude | 6 + .../tests/repos/repo6_blame_sha256/info/refs | 1 + .../objects/info/commit-graph | Bin 0 -> 1376 bytes .../repo6_blame_sha256/objects/info/packs | 2 + ...1ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap | Bin 0 -> 318 bytes ...b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx | Bin 0 -> 1456 bytes ...611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack | Bin 0 -> 904 bytes ...b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev | Bin 0 -> 112 bytes .../repos/repo6_blame_sha256/packed-refs | 2 + .../repos/repo6_blame_sha256/refs/refs/main | 1 + .../git/tests/repos/repo6_merge_sha256/HEAD | 1 + .../git/tests/repos/repo6_merge_sha256/config | 6 + .../repos/repo6_merge_sha256/description | 1 + .../repos/repo6_merge_sha256/info/exclude | 6 + .../tests/repos/repo6_merge_sha256/info/refs | 4 + .../objects/info/commit-graph | Bin 0 -> 1564 bytes .../repo6_merge_sha256/objects/info/packs | 3 + ...096c7530f577d5c0a79c63d9ac2b44f7510.bitmap | Bin 0 -> 410 bytes ...b6a096c7530f577d5c0a79c63d9ac2b44f7510.idx | Bin 0 -> 1696 bytes ...6a096c7530f577d5c0a79c63d9ac2b44f7510.pack | Bin 0 -> 1556 bytes ...b6a096c7530f577d5c0a79c63d9ac2b44f7510.rev | Bin 0 -> 136 bytes ...e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx | Bin 0 -> 1176 bytes ...bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes | Bin 0 -> 84 bytes ...67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack | Bin 0 -> 447 bytes ...e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev | Bin 0 -> 84 bytes .../repos/repo6_merge_sha256/packed-refs | 5 + .../repos/repo6_merge_sha256/refs/heads/main | 1 + modules/markup/html.go | 36 ++-- modules/markup/html_internal_test.go | 6 +- modules/references/references.go | 2 +- modules/references/references_test.go | 2 +- modules/structs/repo.go | 6 + modules/templates/util_string.go | 4 + options/locale/locale_en-US.ini | 3 + routers/api/v1/repo/repo.go | 2 +- routers/web/githttp.go | 6 +- routers/web/repo/repo.go | 3 +- routers/web/web.go | 14 +- services/repository/create.go | 4 + services/repository/fork.go | 23 ++- templates/admin/repo/list.tmpl | 3 + templates/explore/repo_list.tmpl | 3 + templates/repo/commits_list.tmpl | 2 +- templates/repo/create.tmpl | 13 ++ templates/repo/header.tmpl | 3 + templates/swagger/v1_json.tmpl | 18 ++ 98 files changed, 834 insertions(+), 76 deletions(-) create mode 100644 models/migrations/fixtures/Test_RepositoryFormat/repository.yml create mode 100644 models/migrations/v1_22/v286.go create mode 100644 models/migrations/v1_22/v286_test.go create mode 100644 modules/git/blame_sha256_test.go create mode 100644 modules/git/commit_sha256_test.go create mode 100644 modules/git/tests/repos/repo1_bare_sha256/HEAD create mode 100644 modules/git/tests/repos/repo1_bare_sha256/config create mode 100644 modules/git/tests/repos/repo1_bare_sha256/description create mode 100644 modules/git/tests/repos/repo1_bare_sha256/info/exclude create mode 100644 modules/git/tests/repos/repo1_bare_sha256/info/refs create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/info/commit-graph create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/info/packs create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.bitmap create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.idx create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack create mode 100644 modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.rev create mode 100644 modules/git/tests/repos/repo1_bare_sha256/packed-refs create mode 100644 modules/git/tests/repos/repo1_bare_sha256/refs/heads/main create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/HEAD create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/config create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/description create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/info/refs create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/info/commit-graph create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/info/packs create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.bitmap create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.idx create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.rev create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/packed-refs create mode 100644 modules/git/tests/repos/repo5_pulls_sha256/refs/heads/main create mode 100644 modules/git/tests/repos/repo6_blame_sha256/HEAD create mode 100644 modules/git/tests/repos/repo6_blame_sha256/config create mode 100644 modules/git/tests/repos/repo6_blame_sha256/description create mode 100644 modules/git/tests/repos/repo6_blame_sha256/info/exclude create mode 100644 modules/git/tests/repos/repo6_blame_sha256/info/refs create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/info/commit-graph create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/info/packs create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack create mode 100644 modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev create mode 100644 modules/git/tests/repos/repo6_blame_sha256/packed-refs create mode 100644 modules/git/tests/repos/repo6_blame_sha256/refs/refs/main create mode 100644 modules/git/tests/repos/repo6_merge_sha256/HEAD create mode 100644 modules/git/tests/repos/repo6_merge_sha256/config create mode 100644 modules/git/tests/repos/repo6_merge_sha256/description create mode 100644 modules/git/tests/repos/repo6_merge_sha256/info/exclude create mode 100644 modules/git/tests/repos/repo6_merge_sha256/info/refs create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/info/commit-graph create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/info/packs create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.bitmap create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.idx create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.rev create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack create mode 100644 modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev create mode 100644 modules/git/tests/repos/repo6_merge_sha256/packed-refs create mode 100644 modules/git/tests/repos/repo6_merge_sha256/refs/heads/main diff --git a/models/git/commit_status.go b/models/git/commit_status.go index c126d17f20..1118b6cc8c 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -37,7 +37,7 @@ type CommitStatus struct { SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"` TargetURL string `xorm:"TEXT"` Description string `xorm:"TEXT"` - ContextHash string `xorm:"char(40) index"` + ContextHash string `xorm:"VARCHAR(64) index"` Context string `xorm:"TEXT"` Creator *user_model.User `xorm:"-"` CreatorID int64 diff --git a/models/issues/comment.go b/models/issues/comment.go index a1698d4824..8a3bae5b88 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -270,7 +270,7 @@ type Comment struct { UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` // Reference issue in commit message - CommitSHA string `xorm:"VARCHAR(40)"` + CommitSHA string `xorm:"VARCHAR(64)"` Attachments []*repo_model.Attachment `xorm:"-"` Reactions ReactionList `xorm:"-"` diff --git a/models/issues/pull.go b/models/issues/pull.go index 614ee9a87c..4ae6e38ae1 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -171,11 +171,11 @@ type PullRequest struct { HeadBranch string HeadCommitID string `xorm:"-"` BaseBranch string - MergeBase string `xorm:"VARCHAR(40)"` + MergeBase string `xorm:"VARCHAR(64)"` AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"` HasMerged bool `xorm:"INDEX"` - MergedCommitID string `xorm:"VARCHAR(40)"` + MergedCommitID string `xorm:"VARCHAR(64)"` MergerID int64 `xorm:"INDEX"` Merger *user_model.User `xorm:"-"` MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"` diff --git a/models/issues/review.go b/models/issues/review.go index 4cbfa4f443..f2022ae0aa 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -116,7 +116,7 @@ type Review struct { Content string `xorm:"TEXT"` // Official is a review made by an assigned approver (counts towards approval) Official bool `xorm:"NOT NULL DEFAULT false"` - CommitID string `xorm:"VARCHAR(40)"` + CommitID string `xorm:"VARCHAR(64)"` Stale bool `xorm:"NOT NULL DEFAULT false"` Dismissed bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/fixtures/Test_RepositoryFormat/repository.yml b/models/migrations/fixtures/Test_RepositoryFormat/repository.yml new file mode 100644 index 0000000000..5a3675917c --- /dev/null +++ b/models/migrations/fixtures/Test_RepositoryFormat/repository.yml @@ -0,0 +1,11 @@ +# type Repository struct { +# ID int64 `xorm:"pk autoincr"` +# } +- + id: 1 +- + id: 2 +- + id: 3 +- + id: 10 diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 21675cab8a..beb1f3bb96 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -556,6 +556,8 @@ var migrations = []Migration{ NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable), // v285 -> v286 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 diff --git a/models/migrations/v1_22/v286.go b/models/migrations/v1_22/v286.go new file mode 100644 index 0000000000..ef19f64221 --- /dev/null +++ b/models/migrations/v1_22/v286.go @@ -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) +} diff --git a/models/migrations/v1_22/v286_test.go b/models/migrations/v1_22/v286_test.go new file mode 100644 index 0000000000..e36a18a116 --- /dev/null +++ b/models/migrations/v1_22/v286_test.go @@ -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) +} diff --git a/models/pull/review_state.go b/models/pull/review_state.go index 1a2b1e165f..e46a22a49d 100644 --- a/models/pull/review_state.go +++ b/models/pull/review_state.go @@ -39,7 +39,7 @@ type ReviewState struct { ID int64 `xorm:"pk autoincr"` 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? - 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 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 } diff --git a/models/repo/archiver.go b/models/repo/archiver.go index d9520c670c..14ffa1d89b 100644 --- a/models/repo/archiver.go +++ b/models/repo/archiver.go @@ -33,7 +33,7 @@ type RepoArchiver struct { //revive:disable-line:exported RepoID int64 `xorm:"index unique(s)"` Type git.ArchiveType `xorm:"unique(s)"` Status ArchiverStatus - CommitID string `xorm:"VARCHAR(40) unique(s)"` + CommitID string `xorm:"VARCHAR(64) unique(s)"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"` } diff --git a/models/repo/release.go b/models/repo/release.go index 72a73f8e80..1f37f11b2e 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -75,7 +75,7 @@ type Release struct { Target string TargetBehind string `xorm:"-"` // to handle non-existing or empty target Title string - Sha1 string `xorm:"VARCHAR(40)"` + Sha1 string `xorm:"VARCHAR(64)"` NumCommits int64 NumCommitsBehind int64 `xorm:"-"` Note string `xorm:"TEXT"` diff --git a/models/repo/repo.go b/models/repo/repo.go index 3695e1f78b..4401041cdd 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -180,7 +180,7 @@ type Repository struct { IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"` CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"` Topics []string `xorm:"TEXT JSON"` - ObjectFormatName string `xorm:"-"` + ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"` TrustModel TrustModelType @@ -276,10 +276,6 @@ func (repo *Repository) AfterLoad() { repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects 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. diff --git a/models/repo/repo_indexer.go b/models/repo/repo_indexer.go index bad1248b40..6e19d8f937 100644 --- a/models/repo/repo_indexer.go +++ b/models/repo/repo_indexer.go @@ -27,7 +27,7 @@ const ( type RepoIndexerStatus struct { //revive:disable-line:exported ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"INDEX(s)"` - CommitSha string `xorm:"VARCHAR(40)"` + CommitSha string `xorm:"VARCHAR(64)"` IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"` } diff --git a/modules/git/blame_sha256_test.go b/modules/git/blame_sha256_test.go new file mode 100644 index 0000000000..01de0454a3 --- /dev/null +++ b/modules/git/blame_sha256_test.go @@ -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) + } + }) +} diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go index d74bcffed8..4809d6c7ed 100644 --- a/modules/git/commit_reader.go +++ b/modules/git/commit_reader.go @@ -85,6 +85,8 @@ readLoop: commit.Committer.Decode(data) _, _ = payloadSB.Write(line) case "gpgsig": + fallthrough + case "gpgsig-sha256": // FIXME: no intertop, so only 1 exists at present. _, _ = signatureSB.Write(data) _ = signatureSB.WriteByte('\n') pgpsig = true diff --git a/modules/git/commit_sha256_test.go b/modules/git/commit_sha256_test.go new file mode 100644 index 0000000000..82112cb409 --- /dev/null +++ b/modules/git/commit_sha256_test.go @@ -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 1698676906 +0100 +committer Adam Majer 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 1698676906 +0100 +committer Adam Majer 1698676906 +0100 + +signed commit`, commitFromReader.Signature.Payload) + assert.EqualValues(t, "Adam Majer ", 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) +} diff --git a/modules/git/git.go b/modules/git/git.go index 24eff05afc..89c23ff230 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -185,7 +185,13 @@ func InitFull(ctx context.Context) (err error) { globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=") } 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 CheckGitVersionAtLeast("2.1.2") != nil { return errors.New("LFS server support requires Git >= 2.1.2") diff --git a/modules/git/object_format.go b/modules/git/object_format.go index 27771e7459..a056b20e8a 100644 --- a/modules/git/object_format.go +++ b/modules/git/object_format.go @@ -5,6 +5,7 @@ package git import ( "crypto/sha1" + "crypto/sha256" "regexp" "strconv" ) @@ -12,6 +13,9 @@ import ( // sha1Pattern can be used to determine if a string is an valid sha 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 { // Name returns the name of the object format Name() string @@ -29,11 +33,12 @@ type ObjectFormat interface { ComputeHash(t ObjectType, content []byte) ObjectID } +/* SHA1 Type */ type Sha1ObjectFormatImpl struct{} var ( - emptyObjectID = &Sha1Hash{} - emptyTree = &Sha1Hash{ + emptySha1ObjectID = &Sha1Hash{} + emptySha1Tree = &Sha1Hash{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04, } @@ -41,11 +46,11 @@ var ( func (Sha1ObjectFormatImpl) Name() string { return "sha1" } func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID { - return emptyObjectID + return emptySha1ObjectID } func (Sha1ObjectFormatImpl) EmptyTree() ObjectID { - return emptyTree + return emptySha1Tree } func (Sha1ObjectFormatImpl) FullLength() int { return 40 } func (Sha1ObjectFormatImpl) IsValid(input string) bool { @@ -72,11 +77,59 @@ func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID 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{ Sha1ObjectFormat, - // TODO: add sha256 } func ObjectFormatFromName(name string) ObjectFormat { diff --git a/modules/git/object_id.go b/modules/git/object_id.go index 01c23ed3da..4f8c39ee1d 100644 --- a/modules/git/object_id.go +++ b/modules/git/object_id.go @@ -16,6 +16,7 @@ type ObjectID interface { Type() ObjectFormat } +/* SHA1 */ type Sha1Hash [20]byte func (h *Sha1Hash) String() string { @@ -39,6 +40,21 @@ func MustIDFromString(hexHash string) ObjectID { 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) { var theObjectFormat ObjectFormat for _, objectFormat := range SupportedObjectFormats { diff --git a/modules/git/object_id_gogit.go b/modules/git/object_id_gogit.go index 0cebb0d50b..db4c4ae0bd 100644 --- a/modules/git/object_id_gogit.go +++ b/modules/git/object_id_gogit.go @@ -13,6 +13,8 @@ func ParseGogitHash(h plumbing.Hash) ObjectID { switch hash.Size { case 20: return Sha1ObjectFormat.MustID(h[:]) + case 32: + return Sha256ObjectFormat.MustID(h[:]) } return nil diff --git a/modules/git/repo.go b/modules/git/repo.go index 7ccce0ba20..c3de2eb0ad 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -97,15 +97,12 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma } cmd := NewCommand(ctx, "init") - if SupportHashSha256 { - if objectFormatName == "" { - objectFormatName = Sha1ObjectFormat.Name() - } - if !IsValidObjectFormat(objectFormatName) { - return fmt.Errorf("invalid object format: %s", objectFormatName) - } - cmd.AddOptionValues("--object-format", objectFormatName) + + if !IsValidObjectFormat(objectFormatName) { + return fmt.Errorf("invalid object format: %s", objectFormatName) } + cmd.AddOptionValues("--object-format", objectFormatName) + if bare { cmd.AddArguments("--bare") } diff --git a/modules/git/repo_base.go b/modules/git/repo_base.go index 2c6df8b9c4..a9d91d2deb 100644 --- a/modules/git/repo_base.go +++ b/modules/git/repo_base.go @@ -8,6 +8,8 @@ import ( "io" ) +var isGogit bool + // contextKey is a value for use with context.WithValue. type contextKey struct { name string diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index d0b8e79368..90123ee84b 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -21,6 +21,10 @@ import ( "github.com/go-git/go-git/v5/storage/filesystem" ) +func init() { + isGogit = true +} + // Repository represents a Git repository. type Repository struct { Path string diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index a783366cc1..d5a350a926 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -15,6 +15,10 @@ import ( "code.gitea.io/gitea/modules/log" ) +func init() { + isGogit = false +} + // Repository represents a Git repository. type Repository struct { Path string diff --git a/modules/git/tests/repos/repo1_bare_sha256/HEAD b/modules/git/tests/repos/repo1_bare_sha256/HEAD new file mode 100644 index 0000000000..b870d82622 --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/modules/git/tests/repos/repo1_bare_sha256/config b/modules/git/tests/repos/repo1_bare_sha256/config new file mode 100644 index 0000000000..2388a50b2f --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 1 + filemode = true + bare = true +[extensions] + objectformat = sha256 diff --git a/modules/git/tests/repos/repo1_bare_sha256/description b/modules/git/tests/repos/repo1_bare_sha256/description new file mode 100644 index 0000000000..498b267a8c --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/modules/git/tests/repos/repo1_bare_sha256/info/exclude b/modules/git/tests/repos/repo1_bare_sha256/info/exclude new file mode 100644 index 0000000000..a5196d1be8 --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/info/exclude @@ -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] +# *~ diff --git a/modules/git/tests/repos/repo1_bare_sha256/info/refs b/modules/git/tests/repos/repo1_bare_sha256/info/refs new file mode 100644 index 0000000000..b4de954582 --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/info/refs @@ -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^{} diff --git a/modules/git/tests/repos/repo1_bare_sha256/objects/info/commit-graph b/modules/git/tests/repos/repo1_bare_sha256/objects/info/commit-graph new file mode 100644 index 0000000000000000000000000000000000000000..2985d3e4361fa5d2453795c1d2fa235bc162232b GIT binary patch literal 2048 zcmZ>E5Aa}QVqx(2ba7*V02hBx7as_d#l_jhF$BV9UE=QIXar%iZ-LMtlKlaQBoQ+* zFfbrvCI$uuaxpUl0|PG1!oa{lPt3}|z(8xv#=yWpE@o$7U>FLRgMop8o|uz?fdLtF zF)%QUB+Sjgz(6+U*>Q@;xaipXb|u49(|)F8L+e94ZJQn!#bxf>T=@THpa9ROuh&Gr zG5m75F8H=k{+fbPc&=-X(V`PCH@lanEo_%}T)O_PZm@8vVDIU|%@$U7-$*Sy&~oaE z-tD<_4t!F%ulDlHq4{e|>gL4G_nCWd`}=P)N8-M%xTD&$Z)4;71EDXR9-F+s;Bz_e zRqlewnZm|4YJz!E!8ObCqVv4I++DzA7JW!%p3#F{4huRee=pkWH+`YaX4hs>&o6tz zJcD9ad^?l1uFcC1M9=QU=N6FgE@;6>Ltv|Y``QqV=Q;at))1KxdzQiNy zVZ)dB$XL6~%hDAI?d5SA$F^C{{jlLp)t8V0_m8>(lONap__%qiW895*;+?+Ei+yWN z6!qq8@r{p@ER5+|t8jA7!W>qY;38v7AA`Mik2ai3da$o~(+8F>!jXcthI8Luc(uAG zDDs_B@~!5%rx%-<&n$^Zs=uQaYxuEnk@NX~>l>#n_wz2F`7AzVis}!Ix7GjEl&U^{ z0;SyoNCC`|YQI;(Zat^1t@bZxJE`I+yTp4o>b%@B^T>vynG2U6NR$a`ZUCiisCt1^ z`(5|ab~~@tx%yuBu~O0o}Xw9P2rt8q=x`R>2Od^GcCKL7bL_xc>p4Hc(O zY-V15dFQqGpW97dBqS`k#KQU4eEvL8`2;mzBGvvtkcd|YYiL-Nam}~Yk9tK+JgYTB z!k;V)7g6Mhu$4bHAsgg$sCu4M`@O!dTUdV`m*~>_?=+doRi<=-+Tn!esTV(qb1|Hm zAAR`ZYfxQ*r2Zrk?qP(g7fH3>e~<|E%uw|*srCm}krqBX<$s1W95B9c_uVZ`Z5FmX zzmVn`J8ZS0eEl}B>3&<9JL?t5Y!C+3O{w-fKCF3d_vfj{Njbx9d&PMq)2}R_f1Xdu z{r?H2z5u6r3r#kG%0j4mo>co?J)rO+7C-XdwMV=7H=p>MTF25EY!^!A<}%%@^*d!< Lu4{Ut`Os1T5fY)l literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare_sha256/objects/info/packs b/modules/git/tests/repos/repo1_bare_sha256/objects/info/packs new file mode 100644 index 0000000000..c2d1bb88c5 --- /dev/null +++ b/modules/git/tests/repos/repo1_bare_sha256/objects/info/packs @@ -0,0 +1,2 @@ +P pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.pack + diff --git a/modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.bitmap b/modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.bitmap new file mode 100644 index 0000000000000000000000000000000000000000..535ba168c7bb8af6e3424acea12f72cd1399486f GIT binary patch literal 710 zcmZ?r4Dn@PWME}rVBkI=wNP>A(Z{a;co+TLSCJN3u;Fk|wr6bo0h2vd)l-eV85kIN z85kItpqK#y6DEW^Mc0;aL4fVmW+5?uw0jFvzGST6$u2be}z!62g`01^X9 z@_`5j5D#Q32!jM9cn%0QfEWx649s8}T?GeEgCJOf0TL1n7-lfno6du&PyjQ~&0w@K zodcF&U|^5}GtgBq$S6pFB^VgM@q}p$0}q1$SVc(o0)~kS3=FfpvloB`pu~&^3=I9w zd~cy#Fx9@x@xY`D&n|&EP-2!h7sI3rw@}0;u2o=|lnZhEET5bWP^DmM@{GOlVEcR^ zQ3(-r&>C)ZcrggsWY6V!6{@C7NH?eZ0^m{-BRdHOm(OovKmE literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.idx b/modules/git/tests/repos/repo1_bare_sha256/objects/pack/pack-c01aa121b9c5e345fe0da2f9be78665970b0c38c6b495d5fc034bc7a7b95334b.idx new file mode 100644 index 0000000000000000000000000000000000000000..ab45b6f3129f39a2b3292dbf5889089278c8ae78 GIT binary patch literal 2576 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 literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.idx b/modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.idx new file mode 100644 index 0000000000000000000000000000000000000000..fd43d04e0a7125dd77aaad27bb23b7201f76adac GIT binary patch literal 1736 zcmexg;-AdGz`(>n8en8#V1Qv}1_lO7Fbe|%11`+Uz`%eFvoSC*5QEtn7#Ic;b1*P4 zkb^lH7#L`QxfmE2kTEv{0|N;2FfcF-H0EVsU>FXVkAZ;!ALeIZU?7AA7#JAnin%kl z?@pN=>-NxR^)|P*)~9!igeI&x{{I=v<(hlplZsvWs&zscocnT^J!C4Uyz}3;l#An- zb|Kr|YZG~9?SEuFkFWb5*G}E;l!vD456*5=tzJ{sH$QxDB>$?!xlg4}oUD^GT`GHk z|N6aRW|sp6iEI8fyb!Eok2+boZP6?%mcR+8RDCBhzAgXzw8wjcc-qU{5~ayu9-=k> z(%t{rrsPa;S+6}gJIP8`VcWq>QIDTIbBo`e-ErnhSgwXb=j0EI|33e0`sTt;i?d)Qr?k_>!5usn~yuzU7Fi}O~l4=P=?`aZ~PZ(LmRt#Zo4tD!tfGwr1m zfBFjA@bslJ^zh==va8WKlKSVRUhbF^^IOfNE5P=cg79PAh5rf_ z1aHkcFqgA>iPwu+Z+dr{e$ig9|MT!?gSG$O?0x>Yjk)CCW9D_dLhNe_x?@#O@>cUM zSo&txag)Xcu37tDY_Qw+A>zy7#SOgq)3#iRtL5gK;T)N)bazX2%>0tBbZ`5k$GWp` z>-Bo{xIVF7*e}k@lkIlqS?QumriM)umpwe0^30ISo`HdBD+2@D3UX7t#(*IX>pRFTEe2a0VnPrp0;$|*8?hlMeVkCY8wA_i%FbN)%NSZ Kui3XHyd?nnGFH+6 literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack b/modules/git/tests/repos/repo5_pulls_sha256/objects/pack/pack-bfe8f09d42ef5dd1610bf42641fe145d4a02b788eb26c31022a362312660a29d.pack new file mode 100644 index 0000000000000000000000000000000000000000..689318da321ce6cb4091760f4be5f2685cf60f73 GIT binary patch literal 3140 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 Y{u7DyV%pyETJ5la(&8jTwS+};0S;t1 hQE5Aa}QVqx(2ba7*V02hBx7as_d#l_jhF$Bt9;_l*T1Yxt9Kxh!j>Hs1~@n{H8 zDFhf97#L`YnHU%thAU=fU|^s-p6tFsvghKb0P*nIl@})Wub8{bWUZ>mhr5%$?U^2T zanZlk+Tlxnx#w?syWMyF((+S3CBme3uj=2$(|gRuQBQpNnMYsK_(Vk~G)>SYWZDVay8`t z2T*z`fFwSSRG0TGlk2u@&3F;V${fYQ&3@yo-UdFq3AeU;Z=274RY9I3*Z`y!gc%qZ zSW;cyz0loaY5l2Sk-nIEJezaN^!wFZKPvpq-4CXgmqahi)cOK48mgWr)#befh!4X{ l%T+F0&%L~|%~!?YobuhTravT$4Zb!yb8dYc9okjC7y$hzeSH7` literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_blame_sha256/objects/info/packs b/modules/git/tests/repos/repo6_blame_sha256/objects/info/packs new file mode 100644 index 0000000000..73744cf8f7 --- /dev/null +++ b/modules/git/tests/repos/repo6_blame_sha256/objects/info/packs @@ -0,0 +1,2 @@ +P pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack + diff --git a/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap b/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.bitmap new file mode 100644 index 0000000000000000000000000000000000000000..c34487c53ad7ebe36637dc0c14255794fa88c940 GIT binary patch literal 318 zcmZ?r4Dn@PWME}rU|{~UW0B(a1l7MSqL+^*Z4+FhVyG4W$JU(r`q48JvTwcX1F2zP zU|@n`1}I>M(i~86kUUg~;RKYyi7Cfu0F?t#j35FDgUn)JaKNJLKU5Vnn8v2!8CZq^ z>?iDIw18C1YDfZ67)jcq|<*!m!S5_A1KA)KS_fNjUXE~v-^@%^Cu7{p~%sMT1 Gn*snlfi3C) literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx b/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.idx new file mode 100644 index 0000000000000000000000000000000000000000..faaee22ff4aab77fb7cc84887a94d54d603b713b GIT binary patch literal 1456 zcmexg;-AdGz`(>n9l*%Iz(7w7a`z~P#NS{D2WAEa1`uXtU|^snW@BJrpao`UU|^sW zb1*P4P=Yxb7#Qe|1vTXK_HMQNmbzhf!&%SfrzH|Mv(ETBgh=Wx;kf^d#Z-5TrS+$R zMfzgu@odg5)9+Vv{iyIacR!d~UJ|`5Q|rsbw{mm0ZH;|+ZR-hL@lUSK4GN3gqGon% z)bhK!{J2E-v~vxo*qWj2CgN z%uy`d>^IKpZQ!$;aBI8ww)yN=734XB4OVN1FZt!3zv=CE-}Ot&PyLh#liIzie-}^h zF&jrc@#SX@3cPrB{#lrr@T-+~`9#wLrmWi3n0))t!sK@`-^%!Be7e*vyx2_C*!yFE z(k89sM=N(fu=KvTr*tCQTXU^nxAsqa^fir7RCGeq1kHr?eAoRCx=fPQ=4p74X(kc8 z`OTx*i)U)?k+x~epYgQ%$sSwr0QKA5+m@@ldoKL6QtQr%@^5Z0v(8>-U|`zAz`(@G zz`%5yfq~%+0|T=-0|R3t0|QeX0|Rp?0|NukpB;-7wJh w%-4^enUH09@Y9ivR!s literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack b/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.pack new file mode 100644 index 0000000000000000000000000000000000000000..626f081398c8859462e1323ed5907ca9202772e3 GIT binary patch literal 904 zcmWG=boORoU|?ckVBnl8STSd6pJ(1-10II=b*=AOnRTaVFgZ@NSXXld})kQ7uj*K1Xh_OZY7 z)lNpWVrAnirGrV|7>$FRh5T1ag-<%h8Ii=75ZAJ3>NbJ2sRu5WJUag4&hFh@`R|(d zZ`o~}U%yAD-`RiBdp!}Q|5hI!+^hLe7xgVS`uK(Vw9BDK=H|VgaoarKYW?=#_e$UW zvRM`%GdaM0wm`+4si(dDoDF$cFI0w2v%AqInNa>pZf%UHIS04G)sA^!f zcyrnJ8z+1B%oYaVy^$KVL3K(Tw1UZkq%9nl-IMuNX4DdtGz)@#e(t^*=t?+9mz|{IYES z&x3zNR(_ecV#AXk6Ev0@th@bf-?aamTc;cA<;#5)o-KdvJC}X&O#e9(ctDQ!`Se+$Dg zmCA{Mk^$>koora2g{_@801H7vD#3-W;&iyeeyR`l|hL-;=L9eo2beV%2Lk zydf-;Fm3HM_xHb^r=^#)g3xywB@g^gZQy#`o%3 zpYx~ny{_td>1wB0Xnc5d^JjWu+M)Gf_nr#-^3T|m6`cI(tuy!J`$ucEAJ6}IQectv zn!xo-7PUAAIQ!+l58Iu;Qaa6i&exo}D5XN<*FEcic~@!iVwNOubDTSt{nR z9z4i+K!Jn#K>cz?5yi(16aTuukiFI?<{I~EMt2*#mBYbPD_M45)0_2LPBF3gm(riW z)6Z({4J`y0Y+|aIbNb{N@29621y4$LR=!-R$z@p}XmF5~;Zi?${z7KBk37Jh(O#*M zC~#%M<=eZjzKedVcJ};f9(T@IJ$@~qv~qXLXkd%{{o2pk*QNnPkTX?aVsIm9Q0HsY@$&Xg13kVF#TG7#XT|aJ2r}u}E=yg6iKE(aT4Zwh69LG1Q9xV{6WQ{pgtq*|*;H0RSwb Bt5W~~ literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev b/modules/git/tests/repos/repo6_blame_sha256/objects/pack/pack-fcb8a221b76025fd8415d3c562b611ac24312a5ffc3d3703d7c5cc906bdaee8e.rev new file mode 100644 index 0000000000000000000000000000000000000000..56175555cdd7084859dde3a679efb7a70eae6f12 GIT binary patch literal 112 zcmWIYbctYKU|?imU|?ckVBlb2U|?ooU|@xcu`xgZNREYpfr0(cjzx;w6IB1Uh+aOL zv`ui0ilJ8gA6s+g>qpN_$iDTiufNUyiuOn6=~vcWWa@b8>Z;B7@WMao>5UB!UUA0# H)|?3d(q|(D literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_blame_sha256/packed-refs b/modules/git/tests/repos/repo6_blame_sha256/packed-refs new file mode 100644 index 0000000000..644269299f --- /dev/null +++ b/modules/git/tests/repos/repo6_blame_sha256/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3 refs/heads/main diff --git a/modules/git/tests/repos/repo6_blame_sha256/refs/refs/main b/modules/git/tests/repos/repo6_blame_sha256/refs/refs/main new file mode 100644 index 0000000000..829662cdf5 --- /dev/null +++ b/modules/git/tests/repos/repo6_blame_sha256/refs/refs/main @@ -0,0 +1 @@ +e2f5660e15159082902960af0ed74fc144921d2b0c80e069361853b3ece29ba3 diff --git a/modules/git/tests/repos/repo6_merge_sha256/HEAD b/modules/git/tests/repos/repo6_merge_sha256/HEAD new file mode 100644 index 0000000000..b870d82622 --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/modules/git/tests/repos/repo6_merge_sha256/config b/modules/git/tests/repos/repo6_merge_sha256/config new file mode 100644 index 0000000000..2388a50b2f --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/config @@ -0,0 +1,6 @@ +[core] + repositoryformatversion = 1 + filemode = true + bare = true +[extensions] + objectformat = sha256 diff --git a/modules/git/tests/repos/repo6_merge_sha256/description b/modules/git/tests/repos/repo6_merge_sha256/description new file mode 100644 index 0000000000..498b267a8c --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/modules/git/tests/repos/repo6_merge_sha256/info/exclude b/modules/git/tests/repos/repo6_merge_sha256/info/exclude new file mode 100644 index 0000000000..a5196d1be8 --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/info/exclude @@ -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] +# *~ diff --git a/modules/git/tests/repos/repo6_merge_sha256/info/refs b/modules/git/tests/repos/repo6_merge_sha256/info/refs new file mode 100644 index 0000000000..7dae8a1be7 --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/info/refs @@ -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 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/info/commit-graph b/modules/git/tests/repos/repo6_merge_sha256/objects/info/commit-graph new file mode 100644 index 0000000000000000000000000000000000000000..98068475e872f046ba11bdf7d5893f98a0255cbd GIT binary patch literal 1564 zcmZ>E5Aa}QVrB66ba7*VfB=6_7as_dCBWImF$Bu~;O^pR1Yxs2aCLEag|fduXb{Qz z2SkqI(GVEqA;8GMz(6c!Vqjnx2+YjDz<>|4FfcF-Hq5#*DfIJ-UpbxE?ld!e%-t?0 zbT>7$RbbxnTYg7nrOTt&RS?%*ysxQ8NYx{RlI)|#~NOk#G_si+z#AP8>r`_K^I%XomSJfe% zdEYHW=&P;O9K)?V)4D)$+5pnTz`&F0@`ok)yv_8=+n0VY=3iUC*7r%{-H6mt0v2jp{oD( w7{tedSsEA^7)!73^WM;u{H!_mMbE6Itft9nwUf589{3XS_QdYpSC8fb0QbDjvj6}9 literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/info/packs b/modules/git/tests/repos/repo6_merge_sha256/objects/info/packs new file mode 100644 index 0000000000..f3cf8197ce --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/objects/info/packs @@ -0,0 +1,3 @@ +P pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack +P pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.pack + diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.bitmap b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.bitmap new file mode 100644 index 0000000000000000000000000000000000000000..d1624a0780e2ec1c910e845302f8baed9867beba GIT binary patch literal 410 zcmZ?r4Dn@PWME}rU|`k%&*Aao#;YCQCup6N+O}ZY@nHV&+8D0NW45ynZSgM^0I6YM zU|@n`1}Kn+(tJ>HkUUgKCjrXf$CL|hfXaa=Mi7C7xxj1(OkMT=!7>aC++Z4uidZ4A z3X3djioMg|53axo~(abac#1_oj<3j+fKKFrF%z(6i$V_;yQC1z(} zU?3H9FfcF>i#Zt>7|<~n0|NuCF*gGP13t{dz`#H%=4D`Dpcdw1U|>MU{Jv{)mml1+ z@s#rxrnyzC3}2@Y8zVydG_hV0S-rD5z+3-Q2;Fj|T7ngEvZ_yWy*iu*T;eGscYsy!NgB>d06TZc) zYtOuDviw+!%{HNUu$daxnkyG~A zrL`W?crPuVW5W6C^z$1vdl^oj*lMyeDfIJ-UpbxE?ld!e%-t?0bT>7$RbbxnTYg7n zrOTt`U(J>PdzN!xC%=>O3LSJpI<`{0}nb!4R zduE>g;xv(Dh9@VV%AC%S5UDofbNeM?ZtU-s$r*ZXwx-I~`(Cph)%SeT?#wk2f9UCa zX7er0ncKuhDy|Ci)qmZ7v!iOH;3iXm_U|_z>z`*jG zfq_+nfq~^Z0|ToU0|U!T1_o9!1_tI(1_q`T3=FIfA?cdYje&vHoPmL5Ap-;Bcm4ky z9zSlp+VOpY)=8;t3#J_p<`1up;i^1lJL}LE|55>wy#3qXD^6r_R^yoNSaHyHRbI@5 RhllrCK8bOC`F+l6V*r6fLHhsz literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.pack new file mode 100644 index 0000000000000000000000000000000000000000..3b406be93fc9d11f1670c7816e32b17041b52c0b GIT binary patch literal 1556 zcmWG=boORoU|?ckVBnu4UomHDpRb>cBahqn+OAt06&!Y+`kKtSuz=y5z|K?Od?uHe zugX*^{QZSvW8(Cws{7wpf3pjjYuM(;GDleK9dCD6+dO5aD%}|EEj~#V1su~Bxh#`g zsCr*BeBQl^7rU$z1w_AGTD>f+>J$en&urG$reghDJIb;zM5ifj4bWXRMPuHA7XALn z4425}!ZVTv?(apdGn?v6v_lSDO0t`FQ^H`H#Kj55m0l}fPhXzMwNmS$bBz z;Uc#pdM zhf=>+@6Y+S*xY{K#?;9-?d)bg4&9e1_A}+OJxAxvb<+eY=1e_((3i!K$Khi2suQxD zHz#j=?7`v4DDto~cVmaa>YQo68ig$Wp8lP^D_zglD}Sq*bq+V<6N763x6hV48VfBu z*IuP?IyKz z?$3Mt>E%oI;A)>65C{8uu^I9(T&VTGxL4t<&*xx)i_8@rCZ2^ytc>FKw{92jfADJU zy>PlWt?1Wbi0?ZTF@+~vs@O7Rs>v7!F-b>r#K5pG)c1z&+ zI-@B*vnJ1evy?~SJrCn-YsEzhQ^by~GvztB(0Fm1`rh^5Kc8B^&UpVz_n4oa&*$rJ z|E()$JI^>En{|oM^LD1CD%Q_!u65OKGx4`S<}Y_VeMx+Ep%2q!a0om4wJ7qiU9erA zke?K_Ktw3{3xnLF=4lqk?i>C$_#O^+uif2b!!ubIPA=w|r%@^5byvh8O+Hj=;}ajw zI~TWDR|Ta6AHJ~kq4e_lw;gelPn^o&F5Q-QHSM%Z_iEnM=P6;XOE`nS|J>c}pZIv8 zRsr{p_upSj#`C(@9B!Zgk@Gmnxo73i&R4#EuXActFaHsj#JK*)o3{Vo%sS&}>CZ18 zm^(wfmrdpYB?oUVCP?T`+^g`?#l281deg0#K zs&!SY(nW646LscXP?EY?761H-{cK6AetsWW;ak71CGN}JX0>7+PsJQ#69WTd!$1!o z&rbi-XFRWJuhd99(YxQI(7b+E_x&?h=l!}Q|Nl-A#vo|(HpOcTt;kYxU$yVAoEuSB>HhRi_EbUJ#&hASQ54uqLENMChMo#hlaLy5SzD z&v-s%Vh}jRED93wJ#*%=_DYS1ObmjV%y!!tE9PjQ3_k&OddP*X%^Qq@gLg1QDzP`E zH(FNAu|96mUAX9^4g+@<)2URUiaE27&ahGxWnkUU_{|DQ>k}phkt@v8R&l}u`vlaY z#EgwM)k;dPzs`U9YwG(eemeX2EG~Mt^;E|^hv%y&ow~eR-BQx&%Je74pFdlkvMjX8 z^yrhlwVy4foxS;z{rlU!ucGJsL<>HsC^*@k&B*3|q?RSy2^xGs2WOS}%{V=C-=DIq zz+aCKHGHl4*#F!pOe*_&hu@5YYZiVyRj0*pKHSk5;!+K-vuE|apE5Csaxl-)|Igv^ i(4sG!-6#xK5G5JOS literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.rev b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-2fff0848f8d8eab8f7902ac91ab6a096c7530f577d5c0a79c63d9ac2b44f7510.rev new file mode 100644 index 0000000000000000000000000000000000000000..4a695fc2e5c8b7de3d6739f253ab94d0a94ead1f GIT binary patch literal 136 zcmWIYbctYKU|?imU|?ckVBlh4VBlt8VBlk5VBlb2U|?r}0A2p>(CbeQi0G}Ce``6`hx53 dIVgJUTK{LltM3=Lf4nh;@x*h{SHFHw0Ra4ABzXV; literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.idx new file mode 100644 index 0000000000000000000000000000000000000000..3b58342e68711ff246ea9624745cf1ae9f13639e GIT binary patch literal 1176 zcmexg;-AdGz`(>Xuz-<)fnlUzP*{&*NSYfBhd~k!@;u!WISy+DemZ^W_`TG}+XesZ zunmdW{^epG$Fr}kKX*qt=biG|W$Uu^UtNQ%sjseh9Mjd#jr=MzKL|~jzT@yR@x&W1 zpPgZJU|?Y2VPIf%N)^*?TYr0vO<3BrEA7v!H!WEjAhYn7sm8AxE8YEf)dd7vnE!ex g$M11VRBZKBp{~Xv!^TAcQU6mH&S`h+Yx$W601j|Sm;e9( literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.mtimes new file mode 100644 index 0000000000000000000000000000000000000000..a669a06e2741e4eb21149dab64899024ca52aa37 GIT binary patch literal 84 zcmeYb@pWZjU|?imU|>ph`Nfm!^8IP5n0DLx+iPsX(xzQ$e^$L|$_-^Z3rt{-y=jV+r0x}K83hEovxwg2@Y&!Bb zvo+1wI&9jXKl85ZB~7^)s`Nm@pip)wSY^RDSE zTq339#B_9#-)phWGlD0tV$JIGQF*l~@BgIyX$m`w-LHx+((t=^oMXq|?M+iv9PXas zku(sM-<}%6_T^-C$PC9z?u}|mU`k?ezVcF>|Yl?Q4t$Y8t#$f5^nEoQ8aBq43$2InE)4$)jwYpEf zsI-`|?0@vX84q{HKFG{m{O`}hhvKIf&fM^dtcYEw1 z;Ouz&z=Z=1-KWjBYS@M8#_goK6^HOsS}H+ z(C46pM>~IN&di)DP^ian+EK|cRZP2W{p~e2VQJH@v_Grfv}9?3%)(!$8ozF=bobv? G7XSdge$)*B literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev b/modules/git/tests/repos/repo6_merge_sha256/objects/pack/pack-65162b86afdbac3c566696d487e67bb2a4a5501ca1fa3528fad8a9474fba7e50.rev new file mode 100644 index 0000000000000000000000000000000000000000..c09bb3203ba74067d70d94bad6ae9ec9b7ac8469 GIT binary patch literal 84 zcmWIYbctYKU|?imU|?c^0LD}??Y8x|*Vu%mO}o3_ett$YXdm>~2 literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo6_merge_sha256/packed-refs b/modules/git/tests/repos/repo6_merge_sha256/packed-refs new file mode 100644 index 0000000000..b906893c52 --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/packed-refs @@ -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 diff --git a/modules/git/tests/repos/repo6_merge_sha256/refs/heads/main b/modules/git/tests/repos/repo6_merge_sha256/refs/heads/main new file mode 100644 index 0000000000..c8c02921e1 --- /dev/null +++ b/modules/git/tests/repos/repo6_merge_sha256/refs/heads/main @@ -0,0 +1 @@ +d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1 diff --git a/modules/markup/html.go b/modules/markup/html.go index a64e4c565d..33dc1e9086 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -45,19 +45,19 @@ var ( // valid chars in encoded path and parameter: [-+~_%.a-zA-Z0-9/] - // sha1CurrentPattern 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 + // hashCurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae + // 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. - 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 = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`) // 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 = 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-]+://`) @@ -171,13 +171,13 @@ type processor func(ctx *RenderContext, node *html.Node) var defaultProcessors = []processor{ fullIssuePatternProcessor, comparePatternProcessor, - fullSha1PatternProcessor, + fullHashPatternProcessor, shortLinkProcessor, linkProcessor, mentionProcessor, issueIndexPatternProcessor, commitCrossReferencePatternProcessor, - sha1CurrentPatternProcessor, + hashCurrentPatternProcessor, emailAddressProcessor, emojiProcessor, emojiShortCodeProcessor, @@ -199,12 +199,12 @@ func PostProcess( var commitMessageProcessors = []processor{ fullIssuePatternProcessor, comparePatternProcessor, - fullSha1PatternProcessor, + fullHashPatternProcessor, linkProcessor, mentionProcessor, issueIndexPatternProcessor, commitCrossReferencePatternProcessor, - sha1CurrentPatternProcessor, + hashCurrentPatternProcessor, emailAddressProcessor, emojiProcessor, emojiShortCodeProcessor, @@ -231,12 +231,12 @@ func RenderCommitMessage( var commitMessageSubjectProcessors = []processor{ fullIssuePatternProcessor, comparePatternProcessor, - fullSha1PatternProcessor, + fullHashPatternProcessor, linkProcessor, mentionProcessor, issueIndexPatternProcessor, commitCrossReferencePatternProcessor, - sha1CurrentPatternProcessor, + hashCurrentPatternProcessor, emojiShortCodeProcessor, emojiProcessor, } @@ -273,7 +273,7 @@ func RenderIssueTitle( return renderProcessString(ctx, []processor{ issueIndexPatternProcessor, commitCrossReferencePatternProcessor, - sha1CurrentPatternProcessor, + hashCurrentPatternProcessor, emojiShortCodeProcessor, emojiProcessor, }, title) @@ -946,15 +946,15 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) { } } -// fullSha1PatternProcessor renders SHA containing URLs -func fullSha1PatternProcessor(ctx *RenderContext, node *html.Node) { +// fullHashPatternProcessor renders SHA containing URLs +func fullHashPatternProcessor(ctx *RenderContext, node *html.Node) { if ctx.Metas == nil { return } next := node.NextSibling for node != nil && node != next { - m := anySHA1Pattern.FindStringSubmatchIndex(node.Data) + m := anyHashPattern.FindStringSubmatchIndex(node.Data) if m == nil { 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. -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"] == "" { return } @@ -1124,7 +1124,7 @@ func sha1CurrentPatternProcessor(ctx *RenderContext, node *html.Node) { ctx.ShaExistCache = make(map[string]bool) } for node != nil && node != next && start < len(node.Data) { - m := sha1CurrentPattern.FindStringSubmatchIndex(node.Data[start:]) + m := hashCurrentPattern.FindStringSubmatchIndex(node.Data[start:]) if m == nil { return } diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 5ba9561915..93ba9d7667 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -390,10 +390,10 @@ func TestRegExp_sha1CurrentPattern(t *testing.T) { } for _, testCase := range trueTestCases { - assert.True(t, sha1CurrentPattern.MatchString(testCase)) + assert.True(t, hashCurrentPattern.MatchString(testCase)) } 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 { - assert.Equal(t, anySHA1Pattern.FindStringSubmatch(k)[1:], v) + assert.Equal(t, anyHashPattern.FindStringSubmatch(k)[1:], v) } } diff --git a/modules/references/references.go b/modules/references/references.go index 64a67d7da7..7758312564 100644 --- a/modules/references/references.go +++ b/modules/references/references.go @@ -39,7 +39,7 @@ var ( 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 // 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 = regexp.MustCompile(`(?:.*[0-9a-zA-Z-_])\s`) // timeLogPattern matches string for time tracking diff --git a/modules/references/references_test.go b/modules/references/references_test.go index b60d6b0459..ba7dda80cc 100644 --- a/modules/references/references_test.go +++ b/modules/references/references_test.go @@ -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, }, { diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 3974c4db3a..51e175fba8 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -105,6 +105,9 @@ type Repository struct { AvatarURL string `json:"avatar_url"` Internal bool `json:"internal"` MirrorInterval string `json:"mirror_interval"` + // ObjectFormatName of the underlying git repository + // enum: sha1,sha256 + ObjectFormatName string `json:"object_format_name"` // swagger:strfmt date-time MirrorUpdated time.Time `json:"mirror_updated,omitempty"` RepoTransfer *RepoTransfer `json:"repo_transfer"` @@ -139,6 +142,9 @@ type CreateRepoOption struct { // TrustModel of the repository // enum: default,collaborator,committer,collaboratorcommitter 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 diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go index 18a0d5cacc..2771b1e223 100644 --- a/modules/templates/util_string.go +++ b/modules/templates/util_string.go @@ -41,3 +41,7 @@ func (su *StringUtils) Cut(s, sep string) []any { func (su *StringUtils) EllipsisString(s string, max int) string { return base.EllipsisString(s, max) } + +func (su *StringUtils) ToUpper(s string) string { + return strings.ToUpper(s) +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e8345595aa..5448db4b99 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -970,6 +970,8 @@ issue_labels_helper = Select an issue label set. license = License 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 Choose a license. +object_format = Object Format +object_format_helper = Object format of the repository. Cannot be changed later. SHA1 is most compatible. readme = README readme_helper = Select a README file template. 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.internal = Internal desc.archived = Archived +desc.sha256 = SHA256 template.items = Template Items template.git_content = Git Content (Default Branch) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 8ce03cf29c..9810e461de 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -253,7 +253,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre DefaultBranch: opt.DefaultBranch, TrustModel: repo_model.ToTrustModel(opt.TrustModel), IsTemplate: opt.Template, - ObjectFormatName: git.Sha1ObjectFormat.Name(), + ObjectFormatName: opt.ObjectFormatName, }) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { diff --git a/routers/web/githttp.go b/routers/web/githttp.go index 8d0d1ce03a..ab74e9a333 100644 --- a/routers/web/githttp.go +++ b/routers/web/githttp.go @@ -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/packs", repo.GetInfoPacks) 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/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile) - m.Methods("GET,OPTIONS", "/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile) + 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,64}}.pack", repo.GetPackFile) + 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()) } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index b5c550ae45..b64db91406 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -159,7 +159,6 @@ func Create(ctx *context.Context) { ctx.Data["private"] = getRepoPrivate(ctx) ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate ctx.Data["default_branch"] = setting.Repository.DefaultBranch - ctx.Data["hash_type"] = "sha1" ctxUser := checkContextUser(ctx, ctx.FormInt64("org")) if ctx.Written() { @@ -179,6 +178,8 @@ func Create(ctx *context.Context) { ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo() ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit() + ctx.Data["SupportedObjectFormats"] = git.SupportedObjectFormats + ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat ctx.HTML(http.StatusOK, tplCreate) } diff --git a/routers/web/web.go b/routers/web/web.go index 22f98d95de..ff0ce0c258 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1235,7 +1235,7 @@ func registerRoutes(m *web.Route) { Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost) m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch). 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) }, repo.MustBeEditable) m.Group("", func() { @@ -1377,8 +1377,8 @@ func registerRoutes(m *web.Route) { m.Combo("/*"). Get(repo.Wiki). 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,40}}.{ext:patch|diff}", repo.RawDiff) + 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,64}}.{ext:patch|diff}", repo.RawDiff) }, repo.MustEnableWiki, func(ctx *context.Context) { ctx.Data["PageIsWiki"] = true ctx.Data["CloneButtonOriginLink"] = ctx.Repo.Repository.WikiCloneLink() @@ -1498,9 +1498,9 @@ func registerRoutes(m *web.Route) { m.Group("", func() { 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,40})$}/load-branches-and-tags", repo.LoadBranchesAndTags) - m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) + 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,64})$}/load-branches-and-tags", repo.LoadBranchesAndTags) + m.Get("/cherry-pick/{sha:([a-f0-9]{7,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) m.Get("/rss/branch/*", context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed) @@ -1517,7 +1517,7 @@ func registerRoutes(m *web.Route) { m.Group("", func() { m.Get("/forks", repo.Forks) }, 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()) m.Post("/{username}/{reponame}/lastcommit/*", ignSignInAndCsrf, context.RepoAssignment, context.UnitTypes(), context.RepoRefByType(context.RepoRefCommit), reqRepoCodeReader, repo.LastCommit) diff --git a/services/repository/create.go b/services/repository/create.go index bcf2c85c21..0e89573343 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -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{ OwnerID: u.ID, Owner: u, diff --git a/services/repository/fork.go b/services/repository/fork.go index 851a69c80f..a8ff2717b0 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -76,17 +76,18 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork defaultBranch = opts.SingleBranch } repo := &repo_model.Repository{ - OwnerID: owner.ID, - Owner: owner, - OwnerName: owner.Name, - Name: opts.Name, - LowerName: strings.ToLower(opts.Name), - Description: opts.Description, - DefaultBranch: defaultBranch, - IsPrivate: opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate, - IsEmpty: opts.BaseRepo.IsEmpty, - IsFork: true, - ForkID: opts.BaseRepo.ID, + OwnerID: owner.ID, + Owner: owner, + OwnerName: owner.Name, + Name: opts.Name, + LowerName: strings.ToLower(opts.Name), + Description: opts.Description, + DefaultBranch: defaultBranch, + IsPrivate: opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate, + IsEmpty: opts.BaseRepo.IsEmpty, + IsFork: true, + ForkID: opts.BaseRepo.ID, + ObjectFormatName: opts.BaseRepo.ObjectFormatName, } oldRepoPath := opts.BaseRepo.RepoPath() diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl index 7102f73305..fdba0734a2 100644 --- a/templates/admin/repo/list.tmpl +++ b/templates/admin/repo/list.tmpl @@ -67,6 +67,9 @@ {{if .IsTemplate}} {{ctx.Locale.Tr "repo.desc.template"}} {{end}} + {{if eq .ObjectFormatName "sha256"}} + {{ctx.Locale.Tr "repo.desc.sha256"}} + {{end}} {{if .IsMirror}} {{svg "octicon-mirror"}} {{else if .IsFork}} diff --git a/templates/explore/repo_list.tmpl b/templates/explore/repo_list.tmpl index b28aa02c1e..c51dcaa3ff 100644 --- a/templates/explore/repo_list.tmpl +++ b/templates/explore/repo_list.tmpl @@ -25,6 +25,9 @@ {{if .IsTemplate}} {{ctx.Locale.Tr "repo.desc.template"}} {{end}} + {{if eq .ObjectFormatName "sha256"}} + {{ctx.Locale.Tr "repo.desc.sha256"}} + {{end}}
diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index 7bfed53124..7702770c40 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -3,7 +3,7 @@ {{ctx.Locale.Tr "repo.commits.author"}} - SHA1 + {{StringUtils.ToUpper $.Repository.ObjectFormatName}} {{ctx.Locale.Tr "repo.commits.message"}} {{ctx.Locale.Tr "repo.commits.date"}} diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index 3b4b994be7..66f73fb398 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -185,6 +185,19 @@ {{ctx.Locale.Tr "repo.default_branch_helper"}}
+
+ + + {{ctx.Locale.Tr "repo.object_format_helper"}} +
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index a5ef8daa9a..dac30af600 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -27,6 +27,9 @@ {{ctx.Locale.Tr "repo.desc.template"}}
{{svg "octicon-repo-template" 18}}
{{end}} + {{if eq .ObjectFormatName "sha256"}} + {{ctx.Locale.Tr "repo.desc.sha256"}} + {{end}}
{{if not (or .IsBeingCreated .IsBroken)}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 094a0e9aec..dc04a97b83 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -18370,6 +18370,15 @@ "uniqueItems": true, "x-go-name": "Name" }, + "object_format_name": { + "description": "ObjectFormatName of the underlying git repository", + "type": "string", + "enum": [ + "sha1", + "sha256" + ], + "x-go-name": "ObjectFormatName" + }, "private": { "description": "Whether the repository is private", "type": "boolean", @@ -22185,6 +22194,15 @@ "type": "string", "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": { "type": "integer", "format": "int64",