diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index e1f1dd7367..9adc6c855b 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -26,7 +26,7 @@ fork_id: 0 is_template: false template_id: 0 - size: 7320 + size: 7597 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 59fc8acbdf..dc3738938c 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -572,6 +572,8 @@ var migrations = []*xormigrate.Migration{ NewMigration("Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired), // v303 -> v304 NewMigration("Add metadata column for comment table", v1_23.AddCommentMetaDataColumn), + // v304 -> v305 + NewMigration("Add index for release sha1", v1_23.AddIndexForReleaseSha1), } // EnsureUpToDate will check if the db is at the correct version diff --git a/models/migrations/v1_23/v304.go b/models/migrations/v1_23/v304.go index c283603a3d..65cffedbd9 100644 --- a/models/migrations/v1_23/v304.go +++ b/models/migrations/v1_23/v304.go @@ -3,303 +3,11 @@ package v1_23 //nolint -import ( - "fmt" +import "xorm.io/xorm" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - - "src.techknowlogick.com/xormigrate" - "xorm.io/xorm" -) - -const ( - minDBVersion = 70 // Gitea 1.5.3 - oldMigrationsCount = 230 - expectedVersion = minDBVersion + oldMigrationsCount -) - -var oldMigrationNames = []string{ - "add issue_dependencies", - "protect each scratch token", - "add review", - "add must_change_password column for users table", - "add approval whitelists to protected branches", - "clear nonused data which not deleted when user was deleted", - "add pull request rebase with merge commit", - "add theme to users", - "rename repo is_bare to repo is_empty", - "add can close issues via commit in any branch", - "add is locked to issues", - "update U2F counter type", - "hot fix for wrong release sha1 on release table", - "add uploader id for table attachment", - "add table to store original imported gpg keys", - "hash application token", - "add http method to webhook", - "add avatar field to repository", - "add commit status context field to commit_status", - "add original author/url migration info to issues, comments, and repo ", - "change length of some repository columns", - "add index on owner_id of repository and type, review_id of comment", - "remove orphaned repository index statuses", - "add email notification enabled preference to user", - "add enable_status_check, status_check_contexts to protected_branch", - "add table columns for cross referencing issues", - "delete orphaned attachments", - "add repo_admin_change_team_access to user", - "add original author name and id on migrated release", - "add task table and status column for repository table", - "update migration repositories' service type", - "change length of some external login users columns", - "update migration repositories' service type v2", - "Add WhitelistDeployKeys to protected branch", - "remove unnecessary columns from label", - "add includes_all_repositories to teams", - "add column `mode` to table watch", - "Add template options to repository", - "Add comment_id on table notification", - "add can_create_org_repo to team", - "change review content type to text", - "update branch protection for can push and whitelist enable", - "remove release attachments which repository deleted", - "new feature: change target branch of pull requests", - "Remove authentication credentials from stored URL", - "add user_id prefix to existing user avatar name", - "Extend TrackedTimes", - "Add block on rejected reviews branch protection", - "Add commit id and stale to reviews", - "Fix migrated repositories' git service type", - "Add owner_name on table repository", - "add is_restricted column for users table", - "Add Require Signed Commits to ProtectedBranch", - "Add original information for reactions", - "Add columns to user and repository", - "Add some columns on review for migration", - "Fix topic repository count", - "add repository code language statistics", - "fix merge base for pull requests", - "remove dependencies from deleted repositories", - "Expand webhooks for more granularity", - "Add IsSystemWebhook column to webhooks table", - "Add Branch Protection Protected Files Column", - "Add EmailHash Table", - "Refix merge base for merged pull requests", - "Add OrgID column to Labels table", - "Add CommitsAhead and CommitsBehind Column to PullRequest Table", - "Add Branch Protection Block Outdated Branch", - "Add ResolveDoerID to Comment table", - "prepend refs/heads/ to issue refs", - "Save detected language file size to database instead of percent", - "Add KeepActivityPrivate to User table", - "Ensure Repository.IsArchived is not null", - "recalculate Stars number for all user", - "update Matrix Webhook http method to 'PUT'", - "Increase Language field to 50 in LanguageStats", - "Add projects info to repository table", - "create review for 0 review id code comments", - "remove issue dependency comments who refer to non existing issues", - "Add Created and Updated to Milestone table", - "add primary key to repo_topic", - "set default password algorithm to Argon2", - "add TrustModel field to Repository", - "add Team review request support", - "add timestamps to Star, Label, Follow, Watch and Collaboration", - "add changed_protected_files column for pull_request table", - "fix publisher ID for tag releases", - "ensure repo topics are up-to-date", - "code comment replies should have the commitID of the review they are replying to", - "update reactions constraint", - "Add block on official review requests branch protection", - "Convert task type from int to string", - "Convert webhook task type from int to string", - "Convert topic name from 25 to 50", - "Add scope and nonce columns to oauth2_grant table", - "Convert hook task type from char(16) to varchar(16) and trim the column", - "Where Password is Valid with Empty String delete it", - "Add user redirect", - "Recreate user table to fix default values", - "Update DeleteBranch comments to set the old_ref to the commit_sha", - "Add Dismissed to Review table", - "Add Sorting to ProjectBoard table", - "Add sessions table for go-chi/session", - "Add time_id column to Comment", - "Create repo transfer table", - "Fix Postgres ID Sequences broken by recreate-table", - "Remove invalid labels from comments", - "Delete orphaned IssueLabels", - "Add LFS columns to Mirror", - "Convert avatar url to text", - "Delete credentials from past migrations", - "Always save primary email on email address table", - "Add issue resource index table", - "Create PushMirror table", - "Rename Task errors to message", - "Add new table repo_archiver", - "Create protected tag table", - "Drop unneeded webhook related columns", - "Add key is verified to gpg key", - "Unwrap ldap.Sources", - "Add agit flow pull request support", - "Alter issue/comment table TEXT fields to LONGTEXT", - "RecreateIssueResourceIndexTable to have a primary key instead of an unique index", - "Add repo id column for attachment table", - "Add Branch Protection Unprotected Files Column", - "Add table commit_status_index", - "Add Color to ProjectBoard table", - "Add renamed_branch table", - "Add issue content history table", - "No-op (remote version is using AppState now)", - "Add table app_state", - "Drop table remote_version (if exists)", - "Create key/value table for user settings", - "Add Sorting to ProjectIssue table", - "Add key is verified to ssh key", - "Migrate to higher varchar on user struct", - "Add authorize column to team_unit table", - "Add webauthn table and migrate u2f data to webauthn - NO-OPED", - "Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", - "Increase WebAuthentication CredentialID size to 410 - NO-OPED", - "v208 was completely broken - remigrate", - "Create ForeignReference table", - "Add package tables", - "Add allow edits from maintainers to PullRequest table", - "Add auto merge table", - "allow to view files in PRs", - "No-op (Improve Action table indices v1)", - "Alter hook_task table TEXT fields to LONGTEXT", - "Improve Action table indices v2", - "Add sync_on_commit column to push_mirror table", - "Add container repository property", - "Store WebAuthentication CredentialID as bytes and increase size to at least 1024", - "Drop old CredentialID column", - "Rename CredentialIDBytes column to CredentialID", - "Add badges to users", - "Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", - "Conan and generic packages do not need to be semantically versioned", - "Create key/value table for system settings", - "Add TeamInvite table", - "Update counts of all open milestones", - "Add ConfidentialClient column (default true) to OAuth2Application table", - "Add index for hook_task", - "Alter package_version.metadata_json to LONGTEXT", - "Add header_authorization_encrypted column to webhook table", - "Add package cleanup rule table", - "Add index for access_token", - "Create secrets table", - "Drop ForeignReference table", - "Add updated unix to LFSMetaObject", - "Add scope for access_token", - "Add actions tables", - "Add card_type column to project table", - "Alter gpg_key_import content TEXT field to MEDIUMTEXT", - "Add exclusive label", - "Add NeedApproval to actions tables", - "Rename Webhook org_id to owner_id", - "Add missed column owner_id for project table", - "Fix incorrect project type", - "Add version column to action_runner table", - "Improve Action table indices v3", - "Change Container Metadata", - "Fix incorrect owner team unit access mode", - "Fix incorrect admin team unit access mode", - "Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", - "Add ActionTaskOutput table", - "Add ArchivedUnix Column", - "Add is_internal column to package", - "Add Actions Artifact table", - "Add PinOrder Column", - "Convert scoped access tokens", - "Drop custom_labels column of action_runner table", - "Add variable table", - "Add TriggerEvent to action_run table", - "Add git_size and lfs_size columns to repository table", - "Add branch table", - "Alter Actions Artifact table", - "Reduce commit status", - "Add action_tasks_version table", - "Update Action Ref", - "Drop deleted branch table", - "Fix PackageProperty typo", - "Allow archiving labels", - "Add Version to ActionRun table", - "Add Action Schedule Table", - "Add Actions artifacts expiration date", - "Add ScheduleID for ActionRun", - "Add RemoteAddress to mirrors", - "Add Index to issue_user.issue_id", - "Add Index to comment.dependent_issue_id", - "Add Index to action.user_id", - "Rename user themes", - "Add auth_token table", - "Add Index to pull_auto_merge.doer_id", - "Add combined Index to issue_user.uid and issue_id", - "Add ignore stale approval column on branch table", - "Add PreviousDuration to ActionRun", - "Add support for SHA256 git repositories", - "Use Slug instead of ID for Badges", - "Add user_blocking table", - "Add default_wiki_branch to repository table", - "Add PayloadVersion to HookTask", - "Add Index to attachment.comment_id", - "Ensure every project has exactly one default column - No Op", - "Ensure every project has exactly one default column", - "Add unique index for project issue table", - "Add commit status summary table", - "Add missing field of commit status summary table", - "Add everyone_access_mode for repo_unit", - "Drop wrongly created table o_auth2_application", - "Add content version to issue and comment table", - "Add force-push branch protection support", - "Add skip_secondary_authorization option to oauth2 application table", - "Add metadata column for comment table", -} - -// Version describes the version table. Should have only one row with id==1 -type Version struct { - ID int64 `xorm:"pk autoincr"` - Version int64 -} - -func MigrateToXormigrate(x *xorm.Engine) error { - if err := x.Sync(new(Version)); err != nil { - return fmt.Errorf("sync: %w", err) - } - - currentVersion := &Version{ID: 1} - has, err := x.Get(currentVersion) - if err != nil { - return fmt.Errorf("get: %w", err) - } else if !has { - // This should not happen - return fmt.Errorf("could not get version") - } - - v := currentVersion.Version - if minDBVersion > v { - log.Fatal(`Gitea no longer supports auto-migration from your previously installed version. -Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`) - return nil - } - - // Downgrading Gitea's database version not supported - if int(v-minDBVersion) > oldMigrationsCount { - msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", v, expectedVersion) - msg += "\nGitea will exit to keep your database safe and unchanged. Please use the correct Gitea release, do not change the migration version manually (incorrect manual operation may lose data)." - if !setting.IsProd { - msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", expectedVersion) - } - log.Fatal("Migration Error: %s", msg) - return nil - } - - // add migrations that already have been run - for _, i := range oldMigrationNames[:v-minDBVersion] { - if _, err := x.Insert(&xormigrate.Migration{ID: i}); err != nil { - return err - } - } - - // Remove old version table - return x.DropTables(new(Version)) +func AddIndexForReleaseSha1(x *xorm.Engine) error { + type Release struct { + Sha1 string `xorm:"INDEX VARCHAR(64)"` + } + return x.Sync(new(Release)) } diff --git a/models/migrations/v1_23/v305.go b/models/migrations/v1_23/v305.go new file mode 100644 index 0000000000..c283603a3d --- /dev/null +++ b/models/migrations/v1_23/v305.go @@ -0,0 +1,305 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_23 //nolint + +import ( + "fmt" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "src.techknowlogick.com/xormigrate" + "xorm.io/xorm" +) + +const ( + minDBVersion = 70 // Gitea 1.5.3 + oldMigrationsCount = 230 + expectedVersion = minDBVersion + oldMigrationsCount +) + +var oldMigrationNames = []string{ + "add issue_dependencies", + "protect each scratch token", + "add review", + "add must_change_password column for users table", + "add approval whitelists to protected branches", + "clear nonused data which not deleted when user was deleted", + "add pull request rebase with merge commit", + "add theme to users", + "rename repo is_bare to repo is_empty", + "add can close issues via commit in any branch", + "add is locked to issues", + "update U2F counter type", + "hot fix for wrong release sha1 on release table", + "add uploader id for table attachment", + "add table to store original imported gpg keys", + "hash application token", + "add http method to webhook", + "add avatar field to repository", + "add commit status context field to commit_status", + "add original author/url migration info to issues, comments, and repo ", + "change length of some repository columns", + "add index on owner_id of repository and type, review_id of comment", + "remove orphaned repository index statuses", + "add email notification enabled preference to user", + "add enable_status_check, status_check_contexts to protected_branch", + "add table columns for cross referencing issues", + "delete orphaned attachments", + "add repo_admin_change_team_access to user", + "add original author name and id on migrated release", + "add task table and status column for repository table", + "update migration repositories' service type", + "change length of some external login users columns", + "update migration repositories' service type v2", + "Add WhitelistDeployKeys to protected branch", + "remove unnecessary columns from label", + "add includes_all_repositories to teams", + "add column `mode` to table watch", + "Add template options to repository", + "Add comment_id on table notification", + "add can_create_org_repo to team", + "change review content type to text", + "update branch protection for can push and whitelist enable", + "remove release attachments which repository deleted", + "new feature: change target branch of pull requests", + "Remove authentication credentials from stored URL", + "add user_id prefix to existing user avatar name", + "Extend TrackedTimes", + "Add block on rejected reviews branch protection", + "Add commit id and stale to reviews", + "Fix migrated repositories' git service type", + "Add owner_name on table repository", + "add is_restricted column for users table", + "Add Require Signed Commits to ProtectedBranch", + "Add original information for reactions", + "Add columns to user and repository", + "Add some columns on review for migration", + "Fix topic repository count", + "add repository code language statistics", + "fix merge base for pull requests", + "remove dependencies from deleted repositories", + "Expand webhooks for more granularity", + "Add IsSystemWebhook column to webhooks table", + "Add Branch Protection Protected Files Column", + "Add EmailHash Table", + "Refix merge base for merged pull requests", + "Add OrgID column to Labels table", + "Add CommitsAhead and CommitsBehind Column to PullRequest Table", + "Add Branch Protection Block Outdated Branch", + "Add ResolveDoerID to Comment table", + "prepend refs/heads/ to issue refs", + "Save detected language file size to database instead of percent", + "Add KeepActivityPrivate to User table", + "Ensure Repository.IsArchived is not null", + "recalculate Stars number for all user", + "update Matrix Webhook http method to 'PUT'", + "Increase Language field to 50 in LanguageStats", + "Add projects info to repository table", + "create review for 0 review id code comments", + "remove issue dependency comments who refer to non existing issues", + "Add Created and Updated to Milestone table", + "add primary key to repo_topic", + "set default password algorithm to Argon2", + "add TrustModel field to Repository", + "add Team review request support", + "add timestamps to Star, Label, Follow, Watch and Collaboration", + "add changed_protected_files column for pull_request table", + "fix publisher ID for tag releases", + "ensure repo topics are up-to-date", + "code comment replies should have the commitID of the review they are replying to", + "update reactions constraint", + "Add block on official review requests branch protection", + "Convert task type from int to string", + "Convert webhook task type from int to string", + "Convert topic name from 25 to 50", + "Add scope and nonce columns to oauth2_grant table", + "Convert hook task type from char(16) to varchar(16) and trim the column", + "Where Password is Valid with Empty String delete it", + "Add user redirect", + "Recreate user table to fix default values", + "Update DeleteBranch comments to set the old_ref to the commit_sha", + "Add Dismissed to Review table", + "Add Sorting to ProjectBoard table", + "Add sessions table for go-chi/session", + "Add time_id column to Comment", + "Create repo transfer table", + "Fix Postgres ID Sequences broken by recreate-table", + "Remove invalid labels from comments", + "Delete orphaned IssueLabels", + "Add LFS columns to Mirror", + "Convert avatar url to text", + "Delete credentials from past migrations", + "Always save primary email on email address table", + "Add issue resource index table", + "Create PushMirror table", + "Rename Task errors to message", + "Add new table repo_archiver", + "Create protected tag table", + "Drop unneeded webhook related columns", + "Add key is verified to gpg key", + "Unwrap ldap.Sources", + "Add agit flow pull request support", + "Alter issue/comment table TEXT fields to LONGTEXT", + "RecreateIssueResourceIndexTable to have a primary key instead of an unique index", + "Add repo id column for attachment table", + "Add Branch Protection Unprotected Files Column", + "Add table commit_status_index", + "Add Color to ProjectBoard table", + "Add renamed_branch table", + "Add issue content history table", + "No-op (remote version is using AppState now)", + "Add table app_state", + "Drop table remote_version (if exists)", + "Create key/value table for user settings", + "Add Sorting to ProjectIssue table", + "Add key is verified to ssh key", + "Migrate to higher varchar on user struct", + "Add authorize column to team_unit table", + "Add webauthn table and migrate u2f data to webauthn - NO-OPED", + "Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", + "Increase WebAuthentication CredentialID size to 410 - NO-OPED", + "v208 was completely broken - remigrate", + "Create ForeignReference table", + "Add package tables", + "Add allow edits from maintainers to PullRequest table", + "Add auto merge table", + "allow to view files in PRs", + "No-op (Improve Action table indices v1)", + "Alter hook_task table TEXT fields to LONGTEXT", + "Improve Action table indices v2", + "Add sync_on_commit column to push_mirror table", + "Add container repository property", + "Store WebAuthentication CredentialID as bytes and increase size to at least 1024", + "Drop old CredentialID column", + "Rename CredentialIDBytes column to CredentialID", + "Add badges to users", + "Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", + "Conan and generic packages do not need to be semantically versioned", + "Create key/value table for system settings", + "Add TeamInvite table", + "Update counts of all open milestones", + "Add ConfidentialClient column (default true) to OAuth2Application table", + "Add index for hook_task", + "Alter package_version.metadata_json to LONGTEXT", + "Add header_authorization_encrypted column to webhook table", + "Add package cleanup rule table", + "Add index for access_token", + "Create secrets table", + "Drop ForeignReference table", + "Add updated unix to LFSMetaObject", + "Add scope for access_token", + "Add actions tables", + "Add card_type column to project table", + "Alter gpg_key_import content TEXT field to MEDIUMTEXT", + "Add exclusive label", + "Add NeedApproval to actions tables", + "Rename Webhook org_id to owner_id", + "Add missed column owner_id for project table", + "Fix incorrect project type", + "Add version column to action_runner table", + "Improve Action table indices v3", + "Change Container Metadata", + "Fix incorrect owner team unit access mode", + "Fix incorrect admin team unit access mode", + "Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", + "Add ActionTaskOutput table", + "Add ArchivedUnix Column", + "Add is_internal column to package", + "Add Actions Artifact table", + "Add PinOrder Column", + "Convert scoped access tokens", + "Drop custom_labels column of action_runner table", + "Add variable table", + "Add TriggerEvent to action_run table", + "Add git_size and lfs_size columns to repository table", + "Add branch table", + "Alter Actions Artifact table", + "Reduce commit status", + "Add action_tasks_version table", + "Update Action Ref", + "Drop deleted branch table", + "Fix PackageProperty typo", + "Allow archiving labels", + "Add Version to ActionRun table", + "Add Action Schedule Table", + "Add Actions artifacts expiration date", + "Add ScheduleID for ActionRun", + "Add RemoteAddress to mirrors", + "Add Index to issue_user.issue_id", + "Add Index to comment.dependent_issue_id", + "Add Index to action.user_id", + "Rename user themes", + "Add auth_token table", + "Add Index to pull_auto_merge.doer_id", + "Add combined Index to issue_user.uid and issue_id", + "Add ignore stale approval column on branch table", + "Add PreviousDuration to ActionRun", + "Add support for SHA256 git repositories", + "Use Slug instead of ID for Badges", + "Add user_blocking table", + "Add default_wiki_branch to repository table", + "Add PayloadVersion to HookTask", + "Add Index to attachment.comment_id", + "Ensure every project has exactly one default column - No Op", + "Ensure every project has exactly one default column", + "Add unique index for project issue table", + "Add commit status summary table", + "Add missing field of commit status summary table", + "Add everyone_access_mode for repo_unit", + "Drop wrongly created table o_auth2_application", + "Add content version to issue and comment table", + "Add force-push branch protection support", + "Add skip_secondary_authorization option to oauth2 application table", + "Add metadata column for comment table", +} + +// Version describes the version table. Should have only one row with id==1 +type Version struct { + ID int64 `xorm:"pk autoincr"` + Version int64 +} + +func MigrateToXormigrate(x *xorm.Engine) error { + if err := x.Sync(new(Version)); err != nil { + return fmt.Errorf("sync: %w", err) + } + + currentVersion := &Version{ID: 1} + has, err := x.Get(currentVersion) + if err != nil { + return fmt.Errorf("get: %w", err) + } else if !has { + // This should not happen + return fmt.Errorf("could not get version") + } + + v := currentVersion.Version + if minDBVersion > v { + log.Fatal(`Gitea no longer supports auto-migration from your previously installed version. +Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`) + return nil + } + + // Downgrading Gitea's database version not supported + if int(v-minDBVersion) > oldMigrationsCount { + msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Gitea, you can not use the newer database for this old Gitea release (%d).", v, expectedVersion) + msg += "\nGitea will exit to keep your database safe and unchanged. Please use the correct Gitea release, do not change the migration version manually (incorrect manual operation may lose data)." + if !setting.IsProd { + msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", expectedVersion) + } + log.Fatal("Migration Error: %s", msg) + return nil + } + + // add migrations that already have been run + for _, i := range oldMigrationNames[:v-minDBVersion] { + if _, err := x.Insert(&xormigrate.Migration{ID: i}); err != nil { + return err + } + } + + // Remove old version table + return x.DropTables(new(Version)) +} diff --git a/models/repo/release.go b/models/repo/release.go index 3123edd978..1643258301 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -77,7 +77,7 @@ type Release struct { Target string TargetBehind string `xorm:"-"` // to handle non-existing or empty target Title string - Sha1 string `xorm:"VARCHAR(64)"` + Sha1 string `xorm:"INDEX VARCHAR(64)"` NumCommits int64 NumCommitsBehind int64 `xorm:"-"` Note string `xorm:"TEXT"` @@ -537,3 +537,17 @@ func InsertReleases(ctx context.Context, rels ...*Release) error { return committer.Commit() } + +func FindTagsByCommitIDs(ctx context.Context, repoID int64, commitIDs ...string) (map[string][]*Release, error) { + releases := make([]*Release, 0, len(commitIDs)) + if err := db.GetEngine(ctx).Where("repo_id=?", repoID). + In("sha1", commitIDs). + Find(&releases); err != nil { + return nil, err + } + res := make(map[string][]*Release, len(releases)) + for _, r := range releases { + res[r.Sha1] = append(res[r.Sha1], r) + } + return res, nil +} diff --git a/models/repo/release_test.go b/models/repo/release_test.go index 3643bff7f1..41ea083229 100644 --- a/models/repo/release_test.go +++ b/models/repo/release_test.go @@ -25,3 +25,16 @@ func TestMigrate_InsertReleases(t *testing.T) { err := InsertReleases(db.DefaultContext, r) assert.NoError(t, err) } + +func Test_FindTagsByCommitIDs(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + sha1Rels, err := FindTagsByCommitIDs(db.DefaultContext, 1, "65f1bf27bc3bf70f64657658635e66094edbcb4d") + assert.NoError(t, err) + assert.Len(t, sha1Rels, 1) + rels := sha1Rels["65f1bf27bc3bf70f64657658635e66094edbcb4d"] + assert.Len(t, rels, 3) + assert.Equal(t, "v1.1", rels[0].TagName) + assert.Equal(t, "delete-tag", rels[1].TagName) + assert.Equal(t, "v1.0", rels[2].TagName) +} diff --git a/modules/git/batch.go b/modules/git/batch.go new file mode 100644 index 0000000000..3ec4f1ddcc --- /dev/null +++ b/modules/git/batch.go @@ -0,0 +1,46 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "bufio" + "context" +) + +type Batch struct { + cancel context.CancelFunc + Reader *bufio.Reader + Writer WriteCloserError +} + +func (repo *Repository) NewBatch(ctx context.Context) (*Batch, error) { + // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first! + if err := ensureValidGitRepository(ctx, repo.Path); err != nil { + return nil, err + } + + var batch Batch + batch.Writer, batch.Reader, batch.cancel = catFileBatch(ctx, repo.Path) + return &batch, nil +} + +func (repo *Repository) NewBatchCheck(ctx context.Context) (*Batch, error) { + // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first! + if err := ensureValidGitRepository(ctx, repo.Path); err != nil { + return nil, err + } + + var check Batch + check.Writer, check.Reader, check.cancel = catFileBatchCheck(ctx, repo.Path) + return &check, nil +} + +func (b *Batch) Close() { + if b.cancel != nil { + b.cancel() + b.Reader = nil + b.Writer = nil + b.cancel = nil + } +} diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index c988d6ab86..3b1a466b2e 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -26,10 +26,10 @@ type WriteCloserError interface { CloseWithError(err error) error } -// EnsureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository. +// ensureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository. // Run before opening git cat-file. // This is needed otherwise the git cat-file will hang for invalid repositories. -func EnsureValidGitRepository(ctx context.Context, repoPath string) error { +func ensureValidGitRepository(ctx context.Context, repoPath string) error { stderr := strings.Builder{} err := NewCommand(ctx, "rev-parse"). SetDescription(fmt.Sprintf("%s rev-parse [repo_path: %s]", GitExecutable, repoPath)). @@ -43,8 +43,8 @@ func EnsureValidGitRepository(ctx context.Context, repoPath string) error { return nil } -// CatFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function -func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { +// catFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function +func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { batchStdinReader, batchStdinWriter := io.Pipe() batchStdoutReader, batchStdoutWriter := io.Pipe() ctx, ctxCancel := context.WithCancel(ctx) @@ -93,8 +93,8 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, return batchStdinWriter, batchReader, cancel } -// CatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function -func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { +// catFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function +func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) { // We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary. // so let's create a batch stdin and stdout batchStdinReader, batchStdinWriter := io.Pipe() diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go index 945a6bc432..af3ce376d6 100644 --- a/modules/git/blob_nogogit.go +++ b/modules/git/blob_nogogit.go @@ -26,9 +26,12 @@ type Blob struct { // DataAsync gets a ReadCloser for the contents of a blob without reading it all. // Calling the Close function on the result will discard all unread output. func (b *Blob) DataAsync() (io.ReadCloser, error) { - wr, rd, cancel := b.repo.CatFileBatch(b.repo.Ctx) + wr, rd, cancel, err := b.repo.CatFileBatch(b.repo.Ctx) + if err != nil { + return nil, err + } - _, err := wr.Write([]byte(b.ID.String() + "\n")) + _, err = wr.Write([]byte(b.ID.String() + "\n")) if err != nil { cancel() return nil, err @@ -64,9 +67,13 @@ func (b *Blob) Size() int64 { return b.size } - wr, rd, cancel := b.repo.CatFileBatchCheck(b.repo.Ctx) + wr, rd, cancel, err := b.repo.CatFileBatchCheck(b.repo.Ctx) + if err != nil { + log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err) + return 0 + } defer cancel() - _, err := wr.Write([]byte(b.ID.String() + "\n")) + _, err = wr.Write([]byte(b.ID.String() + "\n")) if err != nil { log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err) return 0 diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index 7c369b07f9..cfde64a033 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -124,7 +124,10 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, return nil, err } - batchStdinWriter, batchReader, cancel := commit.repo.CatFileBatch(ctx) + batchStdinWriter, batchReader, cancel, err := commit.repo.CatFileBatch(ctx) + if err != nil { + return nil, err + } defer cancel() commitsMap := map[string]*Commit{} diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 349cfbd9ce..b22805c132 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -46,7 +46,10 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err // Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary. // so let's create a batch stdin and stdout - batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx) + batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() // We'll use a scanner for the revList because it's simpler than a bufio.Reader diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index bc241cdd79..3eb2e2ee6b 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -25,15 +25,11 @@ type Repository struct { gpgSettings *GPGSettings - batchInUse bool - batchCancel context.CancelFunc - batchReader *bufio.Reader - batchWriter WriteCloserError + batchInUse bool + batch *Batch - checkInUse bool - checkCancel context.CancelFunc - checkReader *bufio.Reader - checkWriter WriteCloserError + checkInUse bool + check *Batch Ctx context.Context LastCommitCache *LastCommitCache @@ -55,63 +51,75 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { return nil, util.NewNotExistErrorf("no such file or directory") } - // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first! - if err := EnsureValidGitRepository(ctx, repoPath); err != nil { - return nil, err - } - - repo := &Repository{ + return &Repository{ Path: repoPath, tagCache: newObjectCache(), Ctx: ctx, - } - - repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath) - repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repoPath) - - return repo, nil + }, nil } // CatFileBatch obtains a CatFileBatch for this repository -func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) { - if repo.batchCancel == nil || repo.batchInUse { - log.Debug("Opening temporary cat file batch for: %s", repo.Path) - return CatFileBatch(ctx, repo.Path) +func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) { + if repo.batch == nil { + var err error + repo.batch, err = repo.NewBatch(ctx) + if err != nil { + return nil, nil, nil, err + } } - repo.batchInUse = true - return repo.batchWriter, repo.batchReader, func() { - repo.batchInUse = false + + if !repo.batchInUse { + repo.batchInUse = true + return repo.batch.Writer, repo.batch.Reader, func() { + repo.batchInUse = false + }, nil } + + log.Debug("Opening temporary cat file batch for: %s", repo.Path) + tempBatch, err := repo.NewBatch(ctx) + if err != nil { + return nil, nil, nil, err + } + return tempBatch.Writer, tempBatch.Reader, tempBatch.Close, nil } // CatFileBatchCheck obtains a CatFileBatchCheck for this repository -func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) { - if repo.checkCancel == nil || repo.checkInUse { - log.Debug("Opening temporary cat file batch-check for: %s", repo.Path) - return CatFileBatchCheck(ctx, repo.Path) +func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) { + if repo.check == nil { + var err error + repo.check, err = repo.NewBatchCheck(ctx) + if err != nil { + return nil, nil, nil, err + } } - repo.checkInUse = true - return repo.checkWriter, repo.checkReader, func() { - repo.checkInUse = false + + if !repo.checkInUse { + repo.checkInUse = true + return repo.check.Writer, repo.check.Reader, func() { + repo.checkInUse = false + }, nil } + + log.Debug("Opening temporary cat file batch-check for: %s", repo.Path) + tempBatchCheck, err := repo.NewBatchCheck(ctx) + if err != nil { + return nil, nil, nil, err + } + return tempBatchCheck.Writer, tempBatchCheck.Reader, tempBatchCheck.Close, nil } func (repo *Repository) Close() error { if repo == nil { return nil } - if repo.batchCancel != nil { - repo.batchCancel() - repo.batchReader = nil - repo.batchWriter = nil - repo.batchCancel = nil + if repo.batch != nil { + repo.batch.Close() + repo.batch = nil repo.batchInUse = false } - if repo.checkCancel != nil { - repo.checkCancel() - repo.checkCancel = nil - repo.checkReader = nil - repo.checkWriter = nil + if repo.check != nil { + repo.check.Close() + repo.check = nil repo.checkInUse = false } repo.LastCommitCache = nil diff --git a/modules/git/repo_branch_nogogit.go b/modules/git/repo_branch_nogogit.go index 63d0f7268a..0d2efd4a6b 100644 --- a/modules/git/repo_branch_nogogit.go +++ b/modules/git/repo_branch_nogogit.go @@ -22,9 +22,13 @@ func (repo *Repository) IsObjectExist(name string) bool { return false } - wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) + if err != nil { + log.Debug("Error writing to CatFileBatchCheck %v", err) + return false + } defer cancel() - _, err := wr.Write([]byte(name + "\n")) + _, err = wr.Write([]byte(name + "\n")) if err != nil { log.Debug("Error writing to CatFileBatchCheck %v", err) return false @@ -39,9 +43,13 @@ func (repo *Repository) IsReferenceExist(name string) bool { return false } - wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) + if err != nil { + log.Debug("Error writing to CatFileBatchCheck %v", err) + return false + } defer cancel() - _, err := wr.Write([]byte(name + "\n")) + _, err = wr.Write([]byte(name + "\n")) if err != nil { log.Debug("Error writing to CatFileBatchCheck %v", err) return false diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index ae4c21aaa3..f5ed282a45 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -33,9 +33,12 @@ func (repo *Repository) ResolveReference(name string) (string, error) { // GetRefCommitID returns the last commit ID string of given reference (branch or tag). func (repo *Repository) GetRefCommitID(name string) (string, error) { - wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) + if err != nil { + return "", err + } defer cancel() - _, err := wr.Write([]byte(name + "\n")) + _, err = wr.Write([]byte(name + "\n")) if err != nil { return "", err } @@ -61,12 +64,19 @@ func (repo *Repository) RemoveReference(name string) error { // IsCommitExist returns true if given commit exists in current repository. func (repo *Repository) IsCommitExist(name string) bool { + if err := ensureValidGitRepository(repo.Ctx, repo.Path); err != nil { + log.Error("IsCommitExist: %v", err) + return false + } _, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path}) return err == nil } func (repo *Repository) getCommit(id ObjectID) (*Commit, error) { - wr, rd, cancel := repo.CatFileBatch(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() _, _ = wr.Write([]byte(id.String() + "\n")) @@ -143,7 +153,10 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { } } - wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() _, err = wr.Write([]byte(commitID + "\n")) if err != nil { diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index 318fc091ce..de7707bd6c 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -20,7 +20,10 @@ import ( func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) { // We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary. // so let's create a batch stdin and stdout - batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx) + batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() writeID := func(id string) error { diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index cbab39f8c5..8b06a6a1c3 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -31,9 +31,12 @@ func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) { // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) func (repo *Repository) GetTagType(id ObjectID) (string, error) { - wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx) + if err != nil { + return "", err + } defer cancel() - _, err := wr.Write([]byte(id.String() + "\n")) + _, err = wr.Write([]byte(id.String() + "\n")) if err != nil { return "", err } @@ -89,7 +92,10 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { } // The tag is an annotated tag with a message. - wr, rd, cancel := repo.CatFileBatch(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil { diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index e82012de6f..d74769ccb2 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -10,7 +10,10 @@ import ( ) func (repo *Repository) getTree(id ObjectID) (*Tree, error) { - wr, rd, cancel := repo.CatFileBatch(repo.Ctx) + wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx) + if err != nil { + return nil, err + } defer cancel() _, _ = wr.Write([]byte(id.String() + "\n")) diff --git a/modules/git/tree_entry_nogogit.go b/modules/git/tree_entry_nogogit.go index 89244e27ee..1c3bcd197a 100644 --- a/modules/git/tree_entry_nogogit.go +++ b/modules/git/tree_entry_nogogit.go @@ -42,9 +42,13 @@ func (te *TreeEntry) Size() int64 { return te.size } - wr, rd, cancel := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx) + wr, rd, cancel, err := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx) + if err != nil { + log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err) + return 0 + } defer cancel() - _, err := wr.Write([]byte(te.ID.String() + "\n")) + _, err = wr.Write([]byte(te.ID.String() + "\n")) if err != nil { log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err) return 0 diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go index e0a72de5b8..993b98edc2 100644 --- a/modules/git/tree_nogogit.go +++ b/modules/git/tree_nogogit.go @@ -33,7 +33,10 @@ func (t *Tree) ListEntries() (Entries, error) { } if t.repo != nil { - wr, rd, cancel := t.repo.CatFileBatch(t.repo.Ctx) + wr, rd, cancel, err := t.repo.CatFileBatch(t.repo.Ctx) + if err != nil { + return nil, err + } defer cancel() _, _ = wr.Write([]byte(t.ID.String() + "\n")) diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index 8056b58ec2..542bdfb501 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -16,10 +16,10 @@ import ( "code.gitea.io/gitea/modules/analyze" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/indexer/code/internal" indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/typesniffer" @@ -189,21 +189,23 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository, batch func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error { batch := inner_bleve.NewFlushingBatch(b.inner.Indexer, maxBatchSize) if len(changes.Updates) > 0 { - // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first! - if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil { - log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err) + r, err := gitrepo.OpenRepository(ctx, repo) + if err != nil { return err } - - batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath()) - defer cancel() + defer r.Close() + gitBatch, err := r.NewBatch(ctx) + if err != nil { + return err + } + defer gitBatch.Close() for _, update := range changes.Updates { - if err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo, batch); err != nil { + if err := b.addUpdate(ctx, gitBatch.Writer, gitBatch.Reader, sha, update, repo, batch); err != nil { return err } } - cancel() + gitBatch.Close() } for _, filename := range changes.RemovedFilenames { if err := b.addDelete(filename, repo, batch); err != nil { diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go index e4622fd66e..0bda180fac 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch.go +++ b/modules/indexer/code/elasticsearch/elasticsearch.go @@ -15,11 +15,11 @@ import ( "code.gitea.io/gitea/modules/analyze" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/indexer/code/internal" indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch" "code.gitea.io/gitea/modules/json" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/typesniffer" @@ -154,17 +154,19 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository) elasti func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error { reqs := make([]elastic.BulkableRequest, 0) if len(changes.Updates) > 0 { - // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first! - if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil { - log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err) + r, err := gitrepo.OpenRepository(ctx, repo) + if err != nil { return err } - - batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath()) - defer cancel() + defer r.Close() + batch, err := r.NewBatch(ctx) + if err != nil { + return err + } + defer batch.Close() for _, update := range changes.Updates { - updateReqs, err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo) + updateReqs, err := b.addUpdate(ctx, batch.Writer, batch.Reader, sha, update, repo) if err != nil { return err } @@ -172,7 +174,7 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st reqs = append(reqs, updateReqs...) } } - cancel() + batch.Close() } for _, filename := range changes.RemovedFilenames { diff --git a/modules/migration/pullrequest.go b/modules/migration/pullrequest.go index 4e7500f0d6..1435991bd2 100644 --- a/modules/migration/pullrequest.go +++ b/modules/migration/pullrequest.go @@ -45,7 +45,7 @@ func (p *PullRequest) GetContext() DownloaderContext { return p.Context } // IsForkPullRequest returns true if the pull request from a forked repository but not the same repository func (p *PullRequest) IsForkPullRequest() bool { - return p.Head.RepoPath() != p.Base.RepoPath() + return p.Head.RepoFullName() != p.Base.RepoFullName() } // GetGitRefName returns pull request relative path to head @@ -62,8 +62,8 @@ type PullRequestBranch struct { OwnerName string `yaml:"owner_name"` } -// RepoPath returns pull request repo path -func (p PullRequestBranch) RepoPath() string { +// RepoFullName returns pull request repo full name +func (p PullRequestBranch) RepoFullName() string { return fmt.Sprintf("%s/%s", p.OwnerName, p.RepoName) } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ef7628967c..042fd549a0 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1274,6 +1274,7 @@ commit_graph.color = Color commit.contained_in = This commit is contained in: commit.contained_in_default_branch = This commit is part of the default branch commit.load_referencing_branches_and_tags = Load branches and tags referencing this commit +commit.load_tags_failed = Load tags failed because of internal error blame = Blame download_file = Download file normal_view = Normal View diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 17a1e82ecc..33b87267f9 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -628,6 +628,7 @@ org_still_own_repo=Esta organização ainda possui um ou mais repositórios, eli org_still_own_packages=Esta organização ainda possui um ou mais pacotes, elimine-os primeiro. target_branch_not_exist=O ramo de destino não existe. +target_ref_not_exist=A referência de destino não existe %s admin_cannot_delete_self=Não se pode auto-remover quando tem privilégios de administração. Remova esses privilégios primeiro. @@ -1273,6 +1274,7 @@ commit_graph.color=Colorido commit.contained_in=Este cometimento está contido em: commit.contained_in_default_branch=Este cometimento é parte do ramo principal commit.load_referencing_branches_and_tags=Carregar ramos e etiquetas que referenciem este cometimento +commit.load_tags_failed=O carregamento das etiquetas falhou por causa de um erro interno blame=Responsabilidade download_file=Descarregar ficheiro normal_view=Vista normal @@ -3700,6 +3702,11 @@ workflow.disable_success=A sequência de trabalho '%s' foi desabilitada com suce workflow.enable=Habilitar sequência de trabalho workflow.enable_success=A sequência de trabalho '%s' foi habilitada com sucesso. workflow.disabled=A sequência de trabalho está desabilitada. +workflow.run=Executar sequência de trabalho +workflow.not_found=A sequência de trabalho '%s' não foi encontrada. +workflow.run_success=A sequência de trabalho '%s' foi executada com sucesso. +workflow.from_ref=Usar sequência de trabalho de +workflow.has_workflow_dispatch=Esta sequência de trabalho tem um despoletador de eventos workflow_dispatch. need_approval_desc=É necessária aprovação para executar sequências de trabalho para a derivação do pedido de integração. diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index b9c35331d0..2776137426 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1117,7 +1117,7 @@ projects=Проекты packages=Пакеты actions=Действия labels=Метки -org_labels_desc=Метки уровня организации, которые можно использовать с всеми репозиториями< / strong> в этой организации +org_labels_desc=Метки уровня организации, которые можно использовать с всеми репозиториями в этой организации org_labels_desc_manage=управлять milestones=Этапы diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 868832948b..0d15ac7f43 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -1217,7 +1217,7 @@ clear_ref='Geçerli referansı temizle' filter_branch_and_tag=Dal veya biçim imini filtrele find_tag=Etiketi bul branches=Dal -tags=Etiket +tags=Etiketler issues=Konular pulls=Değişiklik İstekleri projects=Projeler diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index 24130df634..519431d92b 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -40,6 +40,7 @@ func LinkAccount(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration ctx.Data["ShowRegistrationButton"] = false @@ -132,6 +133,7 @@ func LinkAccountPostSignIn(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false @@ -219,6 +221,7 @@ func LinkAccountPostRegister(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 2143b8096a..83268faacb 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -307,6 +307,7 @@ func RegisterOpenID(ctx *context.Context) { ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["OpenID"] = oid userName, _ := ctx.Session.Get("openid_determined_username").(string) if userName != "" { diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index e5d84db617..c91d5fad05 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -83,7 +83,17 @@ func Commits(ctx *context.Context) { return } ctx.Data["Commits"] = processGitCommits(ctx, commits) - + commitIDs := make([]string, 0, len(commits)) + for _, c := range commits { + commitIDs = append(commitIDs, c.ID.String()) + } + commitsTagsMap, err := repo_model.FindTagsByCommitIDs(ctx, ctx.Repo.Repository.ID, commitIDs...) + if err != nil { + log.Error("FindTagsByCommitIDs: %v", err) + ctx.Flash.Error(ctx.Tr("repo.commit.load_tags_failed")) + } else { + ctx.Data["CommitsTagsMap"] = commitsTagsMap + } ctx.Data["Username"] = ctx.Repo.Owner.Name ctx.Data["Reponame"] = ctx.Repo.Repository.Name ctx.Data["CommitCount"] = commitsCount diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 3f9140857a..485bd927fa 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -240,7 +240,8 @@ func SettingsPost(ctx *context.Context) { remoteAddress, err := util.SanitizeURL(form.MirrorAddress) if err != nil { - ctx.ServerError("SanitizeURL", err) + ctx.Data["Err_MirrorAddress"] = true + handleSettingRemoteAddrError(ctx, err, form) return } pullMirror.RemoteAddress = remoteAddress @@ -401,7 +402,8 @@ func SettingsPost(ctx *context.Context) { remoteAddress, err := util.SanitizeURL(form.PushMirrorAddress) if err != nil { - ctx.ServerError("SanitizeURL", err) + ctx.Data["Err_PushMirrorAddress"] = true + handleSettingRemoteAddrError(ctx, err, form) return } diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 6551da39e7..a4ebdf9e88 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -386,7 +386,7 @@ func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.U // Add to hook queue for created repo after session commit. if u.IsOrganization() { newNotifyInput(repo, doer, webhook_module.HookEventRepository). - WithRef(oldRepo.DefaultBranch). + WithRef(git.RefNameFromBranch(oldRepo.DefaultBranch).String()). WithPayload(&api.RepositoryPayload{ Action: api.HookRepoCreated, Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 1d09a222c0..0030ef9a91 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -65,7 +65,7 @@ type notifyInput struct { Event webhook_module.HookEventType // optional - Ref string + Ref git.RefName Payload api.Payloader PullRequest *issues_model.PullRequest } @@ -89,7 +89,7 @@ func (input *notifyInput) WithDoer(doer *user_model.User) *notifyInput { } func (input *notifyInput) WithRef(ref string) *notifyInput { - input.Ref = ref + input.Ref = git.RefName(ref) return input } @@ -101,7 +101,7 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput { func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput { input.PullRequest = pr if input.Ref == "" { - input.Ref = pr.GetGitRefName() + input.Ref = git.RefName(pr.GetGitRefName()) } return input } @@ -144,20 +144,25 @@ func notify(ctx context.Context, input *notifyInput) error { defer gitRepo.Close() ref := input.Ref - if ref != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) { + if ref.BranchName() != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) { if ref != "" { log.Warn("Event %q should only trigger workflows on the default branch, but its ref is %q. Will fall back to the default branch", input.Event, ref) } - ref = input.Repo.DefaultBranch + ref = git.RefNameFromBranch(input.Repo.DefaultBranch) } if ref == "" { log.Warn("Ref of event %q is empty, will fall back to the default branch", input.Event) - ref = input.Repo.DefaultBranch + ref = git.RefNameFromBranch(input.Repo.DefaultBranch) + } + + commitID, err := gitRepo.GetRefCommitID(ref.String()) + if err != nil { + return fmt.Errorf("gitRepo.GetRefCommitID: %w", err) } // Get the commit object for the ref - commit, err := gitRepo.GetCommit(ref) + commit, err := gitRepo.GetCommit(commitID) if err != nil { return fmt.Errorf("gitRepo.GetCommit: %w", err) } @@ -168,7 +173,7 @@ func notify(ctx context.Context, input *notifyInput) error { var detectedWorkflows []*actions_module.DetectedWorkflow actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig() - shouldDetectSchedules := input.Event == webhook_module.HookEventPush && git.RefName(input.Ref).BranchName() == input.Repo.DefaultBranch + shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit, input.Event, input.Payload, @@ -220,12 +225,12 @@ func notify(ctx context.Context, input *notifyInput) error { } if shouldDetectSchedules { - if err := handleSchedules(ctx, schedules, commit, input, ref); err != nil { + if err := handleSchedules(ctx, schedules, commit, input, ref.String()); err != nil { return err } } - return handleWorkflows(ctx, detectedWorkflows, commit, input, ref) + return handleWorkflows(ctx, detectedWorkflows, commit, input, ref.String()) } func skipWorkflows(input *notifyInput, commit *git.Commit) bool { diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 10f3c28d56..ed7a0141b9 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -245,9 +245,21 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { defer headGitRepo.Close() } - headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) - if pr.HeadRepo == nil || !headBranchExist { - log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) + switch pr.Flow { + case issues_model.PullRequestFlowGithub: + headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) + if pr.HeadRepo == nil || !headBranchExist { + log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) + return + } + case issues_model.PullRequestFlowAGit: + headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName()) + if !headBranchExist { + log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch) + return + } + default: + log.Error("wrong flow type %d", pr.Flow) return } diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index dcfe082276..3c8e5846d7 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -20,9 +20,11 @@
- {{if .DefaultBranchBranch.IsProtected}}{{svg "octicon-shield-lock"}}{{end}} {{.DefaultBranchBranch.DBBranch.Name}} - + {{if .DefaultBranchBranch.IsProtected}} + {{svg "octicon-shield-lock"}} + {{end}} + {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}

{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}}  {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}

@@ -39,7 +41,7 @@ {{end}} {{if .EnableFeed}} - {{svg "octicon-rss"}} + {{svg "octicon-rss"}} {{end}} {{if not $.DisableDownloadSourceArchives}}