From 93ef9642b1bb4d06197d268957b8ee63309da9c3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 17:38:11 +0800 Subject: [PATCH 01/17] Use the type RefName for all the needed places --- cmd/hook.go | 18 +++---- models/actions/run.go | 4 +- modules/git/ref.go | 54 +++++++++++++++++++- modules/git/{utils_test.go => ref_test.go} | 10 ++-- modules/git/repo_branch.go | 4 +- modules/git/utils.go | 44 ----------------- modules/notification/action/action.go | 29 +++++------ modules/notification/base/notifier.go | 9 ++-- modules/notification/base/null.go | 9 ++-- modules/notification/indexer/indexer.go | 5 +- modules/notification/notification.go | 17 ++++--- modules/private/hook.go | 5 +- modules/repository/push.go | 41 ++++++---------- routers/api/actions/runner/utils.go | 10 +--- routers/private/hook_post_receive.go | 14 +++--- routers/private/hook_pre_receive.go | 19 ++++---- routers/web/repo/branch.go | 2 +- routers/web/repo/issue.go | 4 +- routers/web/web.go | 2 +- services/actions/notifier.go | 34 ++++++------- services/actions/notifier_helper.go | 2 +- services/agit/agit.go | 4 +- services/issue/issue.go | 2 +- services/mirror/mirror_pull.go | 57 +++++++++++----------- services/mirror/mirror_test.go | 22 +++++++++ services/release/release.go | 10 ++-- services/repository/branch.go | 9 ++-- services/repository/cache.go | 24 +++++---- services/repository/push.go | 16 +++--- services/webhook/dingtalk.go | 6 +-- services/webhook/discord.go | 6 +-- services/webhook/feishu.go | 6 +-- services/webhook/matrix.go | 4 +- services/webhook/msteams.go | 6 +-- services/webhook/notifier.go | 30 ++++++------ services/webhook/slack.go | 4 +- services/webhook/telegram.go | 6 +-- services/webhook/wechatwork.go | 6 +-- 38 files changed, 284 insertions(+), 270 deletions(-) rename modules/git/{utils_test.go => ref_test.go} (64%) create mode 100644 services/mirror/mirror_test.go diff --git a/cmd/hook.go b/cmd/hook.go index bd5575ab6937c..6453267832835 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -201,7 +201,7 @@ Gitea or set your environment appropriately.`, "") oldCommitIDs := make([]string, hookBatchSize) newCommitIDs := make([]string, hookBatchSize) - refFullNames := make([]string, hookBatchSize) + refFullNames := make([]git.RefName, hookBatchSize) count := 0 total := 0 lastline := 0 @@ -236,14 +236,14 @@ Gitea or set your environment appropriately.`, "") oldCommitID := string(fields[0]) newCommitID := string(fields[1]) - refFullName := string(fields[2]) + refFullName := git.RefName(fields[2]) total++ lastline++ // If the ref is a branch or tag, check if it's protected // if supportProcReceive all ref should be checked because // permission check was delayed - if supportProcReceive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) { + if supportProcReceive || refFullName.IsBranch() || refFullName.IsTag() { oldCommitIDs[count] = oldCommitID newCommitIDs[count] = newCommitID refFullNames[count] = refFullName @@ -351,7 +351,7 @@ Gitea or set your environment appropriately.`, "") } oldCommitIDs := make([]string, hookBatchSize) newCommitIDs := make([]string, hookBatchSize) - refFullNames := make([]string, hookBatchSize) + refFullNames := make([]git.RefName, hookBatchSize) count := 0 total := 0 wasEmpty := false @@ -373,7 +373,7 @@ Gitea or set your environment appropriately.`, "") fmt.Fprintf(out, ".") oldCommitIDs[count] = string(fields[0]) newCommitIDs[count] = string(fields[1]) - refFullNames[count] = string(fields[2]) + refFullNames[count] = git.RefName(fields[2]) if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total { masterPushed = true } @@ -575,7 +575,7 @@ Gitea or set your environment appropriately.`, "") } hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize) hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize) - hookOptions.RefFullNames = make([]string, 0, hookBatchSize) + hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize) for { // note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed @@ -593,7 +593,7 @@ Gitea or set your environment appropriately.`, "") } hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0]) hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1]) - hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2]) + hookOptions.RefFullNames = append(hookOptions.RefFullNames, git.RefName(t[2])) } hookOptions.GitPushOptions = make(map[string]string) @@ -640,7 +640,7 @@ Gitea or set your environment appropriately.`, "") for _, rs := range resp.Results { if len(rs.Err) > 0 { - err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err)) + err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef.String()+" "+rs.Err)) if err != nil { return err } @@ -648,7 +648,7 @@ Gitea or set your environment appropriately.`, "") } if rs.IsNotMatched { - err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef)) + err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef.String())) if err != nil { return err } diff --git a/models/actions/run.go b/models/actions/run.go index b58683dd36b35..0654809900c6c 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -70,7 +70,7 @@ func (run *ActionRun) Link() string { // RefLink return the url of run's ref func (run *ActionRun) RefLink() string { refName := git.RefName(run.Ref) - if refName.RefGroup() == "pull" { + if refName.IsPull() { return run.Repo.Link() + "/pulls/" + refName.ShortName() } return git.RefURL(run.Repo.Link(), run.Ref) @@ -79,7 +79,7 @@ func (run *ActionRun) RefLink() string { // PrettyRef return #id for pull ref or ShortName for others func (run *ActionRun) PrettyRef() string { refName := git.RefName(run.Ref) - if refName.RefGroup() == "pull" { + if refName.IsPull() { return "#" + strings.TrimSuffix(strings.TrimPrefix(run.Ref, git.PullPrefix), "/head") } return refName.ShortName() diff --git a/modules/git/ref.go b/modules/git/ref.go index 47cc04b7fbdb7..d8118270d2d7d 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -6,6 +6,8 @@ package git import ( "regexp" "strings" + + "code.gitea.io/gitea/modules/util" ) const ( @@ -63,9 +65,25 @@ func (ref *Reference) RefGroup() string { return RefName(ref.Name).RefGroup() } -// RefName represents a git reference name +// RefName represents a full git reference name type RefName string +func RefNameFromBranch(shortName string) RefName { + return RefName(BranchPrefix + shortName) +} + +func RefNameFromTag(shortName string) RefName { + return RefName(TagPrefix + shortName) +} + +func (ref RefName) IsValid() bool { + return ref.IsBranch() || ref.IsTag() || ref.IsRemote() || ref.IsPull() +} + +func (ref RefName) String() string { + return string(ref) +} + func (ref RefName) IsBranch() bool { return strings.HasPrefix(string(ref), BranchPrefix) } @@ -74,6 +92,18 @@ func (ref RefName) IsTag() bool { return strings.HasPrefix(string(ref), TagPrefix) } +func (ref RefName) IsRemote() bool { + return strings.HasPrefix(string(ref), RemotePrefix) +} + +func (ref RefName) IsPull() bool { + return strings.HasPrefix(string(ref), PullPrefix) +} + +func (ref RefName) IsFor() bool { + return strings.HasPrefix(string(ref), ForPrefix) +} + // ShortName returns the short name of the reference name func (ref RefName) ShortName() string { refName := string(ref) @@ -89,6 +119,9 @@ func (ref RefName) ShortName() string { if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen] } + if strings.HasPrefix(refName, ForPrefix) { + return strings.TrimPrefix(refName, ForPrefix) + } return refName } @@ -108,5 +141,24 @@ func (ref RefName) RefGroup() string { if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { return "pull" } + if strings.HasPrefix(refName, ForPrefix) { + return "for" + } return "" } + +// RefURL returns the absolute URL for a ref in a repository +func RefURL(repoURL, ref string) string { + refName := util.PathEscapeSegments(RefName(ref).ShortName()) + switch { + case strings.HasPrefix(ref, BranchPrefix): + return repoURL + "/src/branch/" + refName + case strings.HasPrefix(ref, TagPrefix): + return repoURL + "/src/tag/" + refName + case !IsValidSHAPattern(ref): + // assume they mean a branch + return repoURL + "/src/branch/" + refName + default: + return repoURL + "/src/commit/" + refName + } +} diff --git a/modules/git/utils_test.go b/modules/git/ref_test.go similarity index 64% rename from modules/git/utils_test.go rename to modules/git/ref_test.go index 718db700aede0..6545dfa0cb661 100644 --- a/modules/git/utils_test.go +++ b/modules/git/ref_test.go @@ -11,15 +11,15 @@ import ( func TestRefEndName(t *testing.T) { // Test branch names (with and without slash). - assert.Equal(t, "foo", RefEndName("refs/heads/foo")) - assert.Equal(t, "feature/foo", RefEndName("refs/heads/feature/foo")) + assert.Equal(t, "foo", RefName("refs/heads/foo").ShortName()) + assert.Equal(t, "feature/foo", RefName("refs/heads/feature/foo").ShortName()) // Test tag names (with and without slash). - assert.Equal(t, "foo", RefEndName("refs/tags/foo")) - assert.Equal(t, "release/foo", RefEndName("refs/tags/release/foo")) + assert.Equal(t, "foo", RefName("refs/tags/foo").ShortName()) + assert.Equal(t, "release/foo", RefName("refs/tags/release/foo").ShortName()) // Test commit hashes. - assert.Equal(t, "c0ffee", RefEndName("c0ffee")) + assert.Equal(t, "c0ffee", RefName("c0ffee").ShortName()) } func TestRefURL(t *testing.T) { diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 14dcf14d8a0da..9da44ede1d408 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -16,9 +16,9 @@ const BranchPrefix = "refs/heads/" // AGit Flow -// PullRequestPrefix special ref to create a pull request: refs/for// +// ForPrefix special ref to create a ref: refs/for// // or refs/for/ -o topic='' -const PullRequestPrefix = "refs/for/" +const ForPrefix = "refs/for/" // TODO: /refs/for-review for suggest change interface diff --git a/modules/git/utils.go b/modules/git/utils.go index 628faf509ff75..b44363820dcfb 100644 --- a/modules/git/utils.go +++ b/modules/git/utils.go @@ -10,8 +10,6 @@ import ( "strconv" "strings" "sync" - - "code.gitea.io/gitea/modules/util" ) // ObjectCache provides thread-safe cache operations. @@ -78,48 +76,6 @@ func ConcatenateError(err error, stderr string) error { return fmt.Errorf("%w - %s", err, stderr) } -// RefEndName return the end name of a ref name -func RefEndName(refStr string) string { - if strings.HasPrefix(refStr, BranchPrefix) { - return refStr[len(BranchPrefix):] - } - - if strings.HasPrefix(refStr, TagPrefix) { - return refStr[len(TagPrefix):] - } - - return refStr -} - -// RefURL returns the absolute URL for a ref in a repository -func RefURL(repoURL, ref string) string { - refName := util.PathEscapeSegments(RefEndName(ref)) - switch { - case strings.HasPrefix(ref, BranchPrefix): - return repoURL + "/src/branch/" + refName - case strings.HasPrefix(ref, TagPrefix): - return repoURL + "/src/tag/" + refName - case !IsValidSHAPattern(ref): - // assume they mean a branch - return repoURL + "/src/branch/" + refName - default: - return repoURL + "/src/commit/" + refName - } -} - -// SplitRefName splits a full refname to reftype and simple refname -func SplitRefName(refStr string) (string, string) { - if strings.HasPrefix(refStr, BranchPrefix) { - return BranchPrefix, refStr[len(BranchPrefix):] - } - - if strings.HasPrefix(refStr, TagPrefix) { - return TagPrefix, refStr[len(TagPrefix):] - } - - return "", refStr -} - // ParseBool returns the boolean value represented by the string as per git's git_config_bool // true will be returned for the result if the string is empty, but valid will be false. // "true", "yes", "on" are all true, true diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index c043ef62d5acb..1d759e4923678 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -13,6 +13,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" @@ -321,7 +322,7 @@ func (a *actionNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mod opType := activities_model.ActionCommitRepo // Check it's tag push or branch. - if opts.IsTag() { + if opts.RefFullName.IsTag() { opType = activities_model.ActionPushTag if opts.IsDelRef() { opType = activities_model.ActionDeleteTag @@ -337,16 +338,16 @@ func (a *actionNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mod Content: string(data), RepoID: repo.ID, Repo: repo, - RefName: opts.RefFullName, + RefName: opts.RefFullName.String(), IsPrivate: repo.IsPrivate, }); err != nil { log.Error("NotifyWatchers: %v", err) } } -func (a *actionNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (a *actionNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { opType := activities_model.ActionCommitRepo - if refType == "tag" { + if refFullName.IsTag() { // has sent same action in `NotifyPushCommits`, so skip it. return } @@ -357,15 +358,15 @@ func (a *actionNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.U RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - RefName: refFullName, + RefName: refFullName.String(), }); err != nil { log.Error("NotifyWatchers: %v", err) } } -func (a *actionNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (a *actionNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { opType := activities_model.ActionDeleteBranch - if refType == "tag" { + if refFullName.IsTag() { // has sent same action in `NotifyPushCommits`, so skip it. return } @@ -376,7 +377,7 @@ func (a *actionNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.U RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - RefName: refFullName, + RefName: refFullName.String(), }); err != nil { log.Error("NotifyWatchers: %v", err) } @@ -396,14 +397,14 @@ func (a *actionNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - RefName: opts.RefFullName, + RefName: opts.RefFullName.String(), Content: string(data), }); err != nil { log.Error("NotifyWatchers: %v", err) } } -func (a *actionNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (a *actionNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{ ActUserID: repo.OwnerID, ActUser: repo.MustOwner(ctx), @@ -411,13 +412,13 @@ func (a *actionNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_mod RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - RefName: refFullName, + RefName: refFullName.String(), }); err != nil { log.Error("NotifyWatchers: %v", err) } } -func (a *actionNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (a *actionNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{ ActUserID: repo.OwnerID, ActUser: repo.MustOwner(ctx), @@ -425,7 +426,7 @@ func (a *actionNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_mod RepoID: repo.ID, Repo: repo, IsPrivate: repo.IsPrivate, - RefName: refFullName, + RefName: refFullName.String(), }); err != nil { log.Error("NotifyWatchers: %v", err) } @@ -444,7 +445,7 @@ func (a *actionNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.R Repo: rel.Repo, IsPrivate: rel.Repo.IsPrivate, Content: rel.Title, - RefName: rel.TagName, + RefName: rel.TagName, // FIXME: use a full ref name? }); err != nil { log.Error("NotifyWatchers: %v", err) } diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 4021bbe141022..87eae3f414a0f 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -10,6 +10,7 @@ import ( packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/repository" ) @@ -54,11 +55,11 @@ type Notifier interface { NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) NotifyDeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) - NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) - NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) + NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) + NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) - NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) - NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) + NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) + NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index 161eadfbecf27..187c36beeb4f8 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -10,6 +10,7 @@ import ( packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/repository" ) @@ -161,11 +162,11 @@ func (*NullNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.U } // NotifyCreateRef notifies branch or tag creation to notifiers -func (*NullNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (*NullNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { } // NotifyDeleteRef notifies branch or tag deletion to notifiers -func (*NullNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (*NullNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { } // NotifyRenameRepository places a place holder function @@ -181,11 +182,11 @@ func (*NullNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_mod } // NotifySyncCreateRef places a place holder function -func (*NullNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (*NullNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { } // NotifySyncDeleteRef places a place holder function -func (*NullNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (*NullNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { } // NotifyRepoPendingTransfer places a place holder function diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index c67f79d0f2ae5..ef93df5e61eba 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -9,7 +9,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/git" code_indexer "code.gitea.io/gitea/modules/indexer/code" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" stats_indexer "code.gitea.io/gitea/modules/indexer/stats" @@ -126,7 +125,7 @@ func (r *indexerNotifier) NotifyMigrateRepository(ctx context.Context, doer, u * } func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { - if setting.Indexer.RepoIndexerEnabled && opts.RefFullName == git.BranchPrefix+repo.DefaultBranch { + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { @@ -135,7 +134,7 @@ func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo } func (r *indexerNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { - if setting.Indexer.RepoIndexerEnabled && opts.RefFullName == git.BranchPrefix+repo.DefaultBranch { + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { diff --git a/modules/notification/notification.go b/modules/notification/notification.go index da2a7ab3a085e..72dd1c99e53dc 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -10,6 +10,7 @@ import ( packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/action" "code.gitea.io/gitea/modules/notification/base" @@ -316,16 +317,16 @@ func NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_ } // NotifyCreateRef notifies branch or tag creation to notifiers -func NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { for _, notifier := range notifiers { - notifier.NotifyCreateRef(ctx, pusher, repo, refType, refFullName, refID) + notifier.NotifyCreateRef(ctx, pusher, repo, refFullName, refID) } } // NotifyDeleteRef notifies branch or tag deletion to notifiers -func NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { for _, notifier := range notifiers { - notifier.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName) + notifier.NotifyDeleteRef(ctx, pusher, repo, refFullName) } } @@ -337,16 +338,16 @@ func NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *r } // NotifySyncCreateRef notifies branch or tag creation to notifiers -func NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { for _, notifier := range notifiers { - notifier.NotifySyncCreateRef(ctx, pusher, repo, refType, refFullName, refID) + notifier.NotifySyncCreateRef(ctx, pusher, repo, refFullName, refID) } } // NotifySyncDeleteRef notifies branch or tag deletion to notifiers -func NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { for _, notifier := range notifiers { - notifier.NotifySyncDeleteRef(ctx, pusher, repo, refType, refFullName) + notifier.NotifySyncDeleteRef(ctx, pusher, repo, refFullName) } } diff --git a/modules/private/hook.go b/modules/private/hook.go index c0fe9ef1fb303..23e03896e4d8b 100644 --- a/modules/private/hook.go +++ b/modules/private/hook.go @@ -10,6 +10,7 @@ import ( "strconv" "time" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" ) @@ -44,7 +45,7 @@ func (g GitPushOptions) Bool(key string, def bool) bool { type HookOptions struct { OldCommitIDs []string NewCommitIDs []string - RefFullNames []string + RefFullNames []git.RefName UserID int64 UserName string GitObjectDirectory string @@ -89,7 +90,7 @@ type HookProcReceiveRefResult struct { OldOID string NewOID string Ref string - OriginalRef string + OriginalRef git.RefName IsForcePush bool IsNotMatched bool Err string diff --git a/modules/repository/push.go b/modules/repository/push.go index aa1552351d515..4485b604c932a 100644 --- a/modules/repository/push.go +++ b/modules/repository/push.go @@ -4,8 +4,6 @@ package repository import ( - "strings" - "code.gitea.io/gitea/modules/git" ) @@ -15,7 +13,7 @@ type PushUpdateOptions struct { PusherName string RepoUserName string RepoName string - RefFullName string // branch, tag or other name to push + RefFullName git.RefName // branch, tag or other name to push OldCommitID string NewCommitID string } @@ -35,59 +33,50 @@ func (opts *PushUpdateOptions) IsUpdateRef() bool { return !opts.IsNewRef() && !opts.IsDelRef() } -// IsTag return true if it's an operation to a tag -func (opts *PushUpdateOptions) IsTag() bool { - return strings.HasPrefix(opts.RefFullName, git.TagPrefix) -} - // IsNewTag return true if it's a creation to a tag func (opts *PushUpdateOptions) IsNewTag() bool { - return opts.IsTag() && opts.IsNewRef() + return opts.RefFullName.IsTag() && opts.IsNewRef() } // IsDelTag return true if it's a deletion to a tag func (opts *PushUpdateOptions) IsDelTag() bool { - return opts.IsTag() && opts.IsDelRef() -} - -// IsBranch return true if it's a push to branch -func (opts *PushUpdateOptions) IsBranch() bool { - return strings.HasPrefix(opts.RefFullName, git.BranchPrefix) + return opts.RefFullName.IsTag() && opts.IsDelRef() } // IsNewBranch return true if it's the first-time push to a branch func (opts *PushUpdateOptions) IsNewBranch() bool { - return opts.IsBranch() && opts.IsNewRef() + return opts.RefFullName.IsBranch() && opts.IsNewRef() } // IsUpdateBranch return true if it's not the first push to a branch func (opts *PushUpdateOptions) IsUpdateBranch() bool { - return opts.IsBranch() && opts.IsUpdateRef() + return opts.RefFullName.IsBranch() && opts.IsUpdateRef() } // IsDelBranch return true if it's a deletion to a branch func (opts *PushUpdateOptions) IsDelBranch() bool { - return opts.IsBranch() && opts.IsDelRef() + return opts.RefFullName.IsBranch() && opts.IsDelRef() } // TagName returns simple tag name if it's an operation to a tag func (opts *PushUpdateOptions) TagName() string { - return opts.RefFullName[len(git.TagPrefix):] + if opts.RefFullName.IsTag() { + return opts.RefFullName.ShortName() + } + return "" } // BranchName returns simple branch name if it's an operation to branch func (opts *PushUpdateOptions) BranchName() string { - return opts.RefFullName[len(git.BranchPrefix):] + if opts.RefFullName.IsBranch() { + return opts.RefFullName.ShortName() + } + return "" } // RefName returns simple name for ref func (opts *PushUpdateOptions) RefName() string { - if strings.HasPrefix(opts.RefFullName, git.TagPrefix) { - return opts.RefFullName[len(git.TagPrefix):] - } else if strings.HasPrefix(opts.RefFullName, git.BranchPrefix) { - return opts.RefFullName[len(git.BranchPrefix):] - } - return "" + return opts.RefFullName.ShortName() } // RepoFullName returns repo full name diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 10f92c29f72e7..77e660026a2a4 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -98,14 +98,8 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { baseRef = pullPayload.PullRequest.Base.Ref headRef = pullPayload.PullRequest.Head.Ref } - refPrefix, refName := git.SplitRefName(t.Job.Run.Ref) - refType := "" - switch refPrefix { - case git.BranchPrefix: - refType = "branch" - case git.TagPrefix: - refType = "tag" - } + refName := git.RefName(t.Job.Run.Ref) + refType := refName.RefGroup() taskContext, _ := structpb.NewStruct(map[string]interface{}{ // standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index cfe20be106cf7..d3b06add4a0a9 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -47,7 +47,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { // tags. Updates to other refs (eg, refs/notes, refs/changes, // or other less-standard refs spaces are ignored since there // may be a very large number of them). - if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) { + if refFullName.IsBranch() || refFullName.IsTag() { if repo == nil { repo = loadRepository(ctx, ownerName, repoName) if ctx.Written() { @@ -67,7 +67,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { RepoName: repoName, } updates = append(updates, option) - if repo.IsEmpty && option.IsBranch() && (option.BranchName() == "master" || option.BranchName() == "main") { + if repo.IsEmpty && refFullName.IsBranch() && (option.BranchName() == "master" || option.BranchName() == "main") { // put the master/main branch first copy(updates[1:], updates) updates[0] = option @@ -124,7 +124,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { newCommitID := opts.NewCommitIDs[i] // post update for agit pull request - if git.SupportProcReceive && strings.HasPrefix(refFullName, git.PullPrefix) { + if git.SupportProcReceive && refFullName.IsPull() { if repo == nil { repo = loadRepository(ctx, ownerName, repoName) if ctx.Written() { @@ -132,7 +132,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } } - pullIndexStr := strings.TrimPrefix(refFullName, git.PullPrefix) + pullIndexStr := refFullName.ShortName() pullIndexStr = strings.Split(pullIndexStr, "/")[0] pullIndex, _ := strconv.ParseInt(pullIndexStr, 10, 64) if pullIndex <= 0 { @@ -160,10 +160,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { continue } - branch := git.RefEndName(opts.RefFullNames[i]) - // If we've pushed a branch (and not deleted it) - if newCommitID != git.EmptySHA && strings.HasPrefix(refFullName, git.BranchPrefix) { + if newCommitID != git.EmptySHA && refFullName.IsBranch() { // First ensure we have the repository loaded, we're allowed pulls requests and we can get the base repo if repo == nil { @@ -197,6 +195,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } } + branch := refFullName.ShortName() + // If our branch is the default branch of an unforked repo - there's no PR to create or refer to if !repo.IsFork && branch == baseRepo.DefaultBranch { results = append(results, private.HookPostReceiveBranchResult{}) diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 63b4a8622e129..150d6ff7502b4 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "os" - "strings" "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -119,11 +118,11 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { refFullName := opts.RefFullNames[i] switch { - case strings.HasPrefix(refFullName, git.BranchPrefix): + case refFullName.IsBranch(): preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName) - case strings.HasPrefix(refFullName, git.TagPrefix): + case refFullName.IsTag(): preReceiveTag(ourCtx, oldCommitID, newCommitID, refFullName) - case git.SupportProcReceive && strings.HasPrefix(refFullName, git.PullRequestPrefix): + case git.SupportProcReceive && refFullName.IsFor(): preReceivePullRequest(ourCtx, oldCommitID, newCommitID, refFullName) default: ourCtx.AssertCanWriteCode() @@ -136,8 +135,8 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { ctx.PlainText(http.StatusOK, "ok") } -func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { - branchName := strings.TrimPrefix(refFullName, git.BranchPrefix) +func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { + branchName := refFullName.ShortName() ctx.branchName = branchName if !ctx.AssertCanWriteCode() { @@ -369,12 +368,12 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN } } -func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { +func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { if !ctx.AssertCanWriteCode() { return } - tagName := strings.TrimPrefix(refFullName, git.TagPrefix) + tagName := refFullName.ShortName() if !ctx.gotProtectedTags { var err error @@ -405,7 +404,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName } } -func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { +func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { if !ctx.AssertCreatePullRequest() { return } @@ -424,7 +423,7 @@ func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID, ref return } - baseBranchName := refFullName[len(git.PullRequestPrefix):] + baseBranchName := refFullName.ShortName() baseBranchExist := false if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 9f26634311125..ea2c01856d45f 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -146,7 +146,7 @@ func RestoreBranchPost(ctx *context.Context) { // Don't return error below this if err := repo_service.PushUpdate( &repo_module.PushUpdateOptions{ - RefFullName: git.BranchPrefix + deletedBranch.Name, + RefFullName: git.RefNameFromBranch(deletedBranch.Name), OldCommitID: git.EmptySHA, NewCommitID: deletedBranch.Commit, PusherID: ctx.Doer.ID, diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index c2f30a01f4736..16c125274b089 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -852,7 +852,7 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0 ctx.Data["label_ids"] = strings.Join(labelIDs, ",") ctx.Data["Reference"] = template.Ref - ctx.Data["RefEndName"] = git.RefEndName(template.Ref) + ctx.Data["RefEndName"] = git.RefName(template.Ref).ShortName() return templateErrs } return templateErrs @@ -1861,7 +1861,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["HasProjectsWritePermission"] = ctx.Repo.CanWrite(unit.TypeProjects) ctx.Data["IsRepoAdmin"] = ctx.IsSigned && (ctx.Repo.IsAdmin() || ctx.Doer.IsAdmin) ctx.Data["LockReasons"] = setting.Repository.Issue.LockReasons - ctx.Data["RefEndName"] = git.RefEndName(issue.Ref) + ctx.Data["RefEndName"] = git.RefName(issue.Ref).ShortName() var hiddenCommentTypes *big.Int if ctx.IsSigned { diff --git a/routers/web/web.go b/routers/web/web.go index b0db8892ea35c..9bdfa1e68374e 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1309,7 +1309,7 @@ func registerRoutes(m *web.Route) { }, repo.MustBeNotEmpty, reqRepoCodeReader) m.Group("", func() { - m.Get("/graph", repo.Graph) + m.Get("/graph", repo.Graph) m.Get("/commit/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff) m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 4ac77276ffe2e..f73ac81f255c2 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -351,9 +351,9 @@ func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo } newNotifyInput(repo, pusher, webhook_module.HookEventPush). - WithRef(opts.RefFullName). + WithRef(opts.RefFullName.String()). WithPayload(&api.PushPayload{ - Ref: opts.RefFullName, + Ref: opts.RefFullName.String(), Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: setting.AppURL + commits.CompareURL, @@ -366,37 +366,35 @@ func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo Notify(ctx) } -func (n *actionsNotifier) NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (n *actionsNotifier) NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { ctx = withMethod(ctx, "NotifyCreateRef") apiPusher := convert.ToUser(ctx, pusher, nil) apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) - refName := git.RefEndName(refFullName) newNotifyInput(repo, pusher, webhook_module.HookEventCreate). - WithRef(refName). + WithRef(refFullName.String()). WithPayload(&api.CreatePayload{ - Ref: refName, + Ref: refFullName.String(), Sha: refID, - RefType: refType, + RefType: refFullName.RefGroup(), Repo: apiRepo, Sender: apiPusher, }). Notify(ctx) } -func (n *actionsNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (n *actionsNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { ctx = withMethod(ctx, "NotifyDeleteRef") apiPusher := convert.ToUser(ctx, pusher, nil) apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) - refName := git.RefEndName(refFullName) newNotifyInput(repo, pusher, webhook_module.HookEventDelete). - WithRef(refName). + WithRef(refFullName.String()). WithPayload(&api.DeletePayload{ - Ref: refName, - RefType: refType, + Ref: refFullName.String(), + RefType: refFullName.RefGroup(), PusherType: api.PusherTypeUser, Repo: apiRepo, Sender: apiPusher, @@ -415,9 +413,9 @@ func (n *actionsNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use } newNotifyInput(repo, pusher, webhook_module.HookEventPush). - WithRef(opts.RefFullName). + WithRef(opts.RefFullName.String()). WithPayload(&api.PushPayload{ - Ref: opts.RefFullName, + Ref: opts.RefFullName.String(), Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: setting.AppURL + commits.CompareURL, @@ -431,14 +429,14 @@ func (n *actionsNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use Notify(ctx) } -func (n *actionsNotifier) NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (n *actionsNotifier) NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { ctx = withMethod(ctx, "NotifySyncCreateRef") - n.NotifyCreateRef(ctx, pusher, repo, refType, refFullName, refID) + n.NotifyCreateRef(ctx, pusher, repo, refFullName, refID) } -func (n *actionsNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (n *actionsNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { ctx = withMethod(ctx, "NotifySyncDeleteRef") - n.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName) + n.NotifyDeleteRef(ctx, pusher, repo, refFullName) } func (n *actionsNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) { diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 376c9820f1983..5e41241d18f01 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -225,7 +225,7 @@ func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo) newNotifyInput(rel.Repo, doer, webhook_module.HookEventRelease). - WithRef(git.TagPrefix + rel.TagName). + WithRef(git.RefNameFromTag(rel.TagName).String()). WithPayload(&api.ReleasePayload{ Action: action, Release: convert.ToRelease(ctx, rel), diff --git a/services/agit/agit.go b/services/agit/agit.go index 32fc3cba4a36e..675dd73bb59fe 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -48,7 +48,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. continue } - if !strings.HasPrefix(opts.RefFullNames[i], git.PullRequestPrefix) { + if !opts.RefFullNames[i].IsFor() { results = append(results, private.HookProcReceiveRefResult{ IsNotMatched: true, OriginalRef: opts.RefFullNames[i], @@ -56,7 +56,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. continue } - baseBranchName := opts.RefFullNames[i][len(git.PullRequestPrefix):] + baseBranchName := opts.RefFullNames[i].ShortName() curentTopicBranch := "" if !gitRepo.IsBranchExist(baseBranchName) { // try match refs/for// diff --git a/services/issue/issue.go b/services/issue/issue.go index d4f827e99af56..6b6ac624fe556 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -199,7 +199,7 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i issueRefURLs := make(map[int64]string, len(issues)) for _, issue := range issues { if issue.Ref != "" { - issueRefEndNames[issue.ID] = git.RefEndName(issue.Ref) + issueRefEndNames[issue.ID] = git.RefName(issue.Ref).ShortName() issueRefURLs[issue.ID] = git.RefURL(repoLink, issue.Ref) } } diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 60699294c18bd..0691146c58ef7 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -78,13 +78,19 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error // If the oldCommitID is "0000000", it means a new reference, the value of newCommitID is empty. // If the newCommitID is "0000000", it means the reference is deleted, the value of oldCommitID is empty. type mirrorSyncResult struct { - refName string + refName git.RefName oldCommitID string newCommitID string } // parseRemoteUpdateOutput detects create, update and delete operations of references from upstream. -func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { +/* possible output example: +* [new tag] v0.1.8 -> v0.1.8 +* [new branch] master -> origin/master +- [deleted] (none) -> origin/test ++ f895a1e...957a993 test -> origin/test (forced update) +*/ +func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { results := make([]*mirrorSyncResult, 0, 3) lines := strings.Split(output, "\n") for i := range lines { @@ -97,19 +103,21 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { refName := lines[i][idx+3:] switch { - case strings.HasPrefix(lines[i], " * "): // New reference - if strings.HasPrefix(lines[i], " * [new tag]") { - refName = git.TagPrefix + refName - } else if strings.HasPrefix(lines[i], " * [new branch]") { - refName = git.BranchPrefix + refName - } + case strings.HasPrefix(lines[i], " * [new tag]"): // new tag results = append(results, &mirrorSyncResult{ - refName: refName, + refName: git.RefNameFromTag(refName), + oldCommitID: gitShortEmptySha, + }) + case strings.HasPrefix(lines[i], " * [new branch]"): // new branch + refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") + results = append(results, &mirrorSyncResult{ + refName: git.RefNameFromBranch(refName), oldCommitID: gitShortEmptySha, }) case strings.HasPrefix(lines[i], " - "): // Delete reference + refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") results = append(results, &mirrorSyncResult{ - refName: refName, + refName: git.RefNameFromBranch(refName), newCommitID: gitShortEmptySha, }) case strings.HasPrefix(lines[i], " + "): // Force update @@ -127,7 +135,7 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { continue } results = append(results, &mirrorSyncResult{ - refName: refName, + refName: git.RefNameFromBranch(refName), oldCommitID: shas[0], newCommitID: shas[1], }) @@ -143,7 +151,7 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { continue } results = append(results, &mirrorSyncResult{ - refName: refName, + refName: git.RefNameFromBranch(refName), oldCommitID: shas[0], newCommitID: shas[1], }) @@ -384,7 +392,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo } m.UpdatedUnix = timeutil.TimeStampNow() - return parseRemoteUpdateOutput(output), true + return parseRemoteUpdateOutput(output, m.GetRemoteName()), true } // SyncPullMirror starts the sync of the pull mirror and schedules the next run. @@ -444,20 +452,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { for _, result := range results { // Discard GitHub pull requests, i.e. refs/pull/* - if strings.HasPrefix(result.refName, git.PullPrefix) { + if result.refName.IsPull() { continue } - tp, _ := git.SplitRefName(result.refName) - // Create reference if result.oldCommitID == gitShortEmptySha { - if tp == git.TagPrefix { - tp = "tag" - } else if tp == git.BranchPrefix { - tp = "branch" - } - commitID, err := gitRepo.GetRefCommitID(result.refName) + commitID, err := gitRepo.GetRefCommitID(result.refName.String()) if err != nil { log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err) continue @@ -467,13 +468,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { OldCommitID: git.EmptySHA, NewCommitID: commitID, }, repo_module.NewPushCommits()) - notification.NotifySyncCreateRef(ctx, m.Repo.MustOwner(ctx), m.Repo, tp, result.refName, commitID) + notification.NotifySyncCreateRef(ctx, m.Repo.MustOwner(ctx), m.Repo, result.refName, commitID) continue } // Delete reference if result.newCommitID == gitShortEmptySha { - notification.NotifySyncDeleteRef(ctx, m.Repo.MustOwner(ctx), m.Repo, tp, result.refName) + notification.NotifySyncDeleteRef(ctx, m.Repo.MustOwner(ctx), m.Repo, result.refName) continue } @@ -547,13 +548,11 @@ func checkAndUpdateEmptyRepository(m *repo_model.Mirror, gitRepo *git.Repository } firstName := "" for _, result := range results { - if strings.HasPrefix(result.refName, git.PullPrefix) { - continue - } - tp, name := git.SplitRefName(result.refName) - if len(tp) > 0 && tp != git.BranchPrefix { + if !result.refName.IsBranch() { continue } + + name := result.refName.ShortName() if len(firstName) == 0 { firstName = name } diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go new file mode 100644 index 0000000000000..3a38b19ccec09 --- /dev/null +++ b/services/mirror/mirror_test.go @@ -0,0 +1,22 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package mirror + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_parseRemoteUpdateOutput(t *testing.T) { + output := ` +* [new tag] v0.1.8 -> v0.1.8 +* [new branch] master -> origin/master +- [deleted] (none) -> origin/test ++ f895a1e...957a993 test -> origin/test (forced update) +` + results := parseRemoteUpdateOutput(output, "origin") + assert.Len(t, results, 4) + assert.EqualValues(t, "refs/tag/v0.1.8", results[0].refName) +} diff --git a/services/release/release.go b/services/release/release.go index a9a5231197762..2f6be933c1ba4 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -80,14 +80,15 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel commits.HeadCommit = repository.CommitToPushCommit(commit) commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String()) + refFullName := git.RefName(git.TagPrefix + rel.TagName) notification.NotifyPushCommits( ctx, rel.Publisher, rel.Repo, &repository.PushUpdateOptions{ - RefFullName: git.TagPrefix + rel.TagName, + RefFullName: refFullName, OldCommitID: git.EmptySHA, NewCommitID: commit.ID.String(), }, commits) - notification.NotifyCreateRef(ctx, rel.Publisher, rel.Repo, "tag", git.TagPrefix+rel.TagName, commit.ID.String()) + notification.NotifyCreateRef(ctx, rel.Publisher, rel.Repo, refFullName, commit.ID.String()) rel.CreatedUnix = timeutil.TimeStampNow() } commit, err := gitRepo.GetTagCommit(rel.TagName) @@ -323,14 +324,15 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del return fmt.Errorf("git tag -d: %w", err) } + refName := git.RefNameFromTag(rel.TagName) notification.NotifyPushCommits( ctx, doer, repo, &repository.PushUpdateOptions{ - RefFullName: git.TagPrefix + rel.TagName, + RefFullName: refName, OldCommitID: rel.Sha1, NewCommitID: git.EmptySHA, }, repository.NewPushCommits()) - notification.NotifyDeleteRef(ctx, doer, repo, "tag", git.TagPrefix+rel.TagName) + notification.NotifyDeleteRef(ctx, doer, repo, refName) if err := repo_model.DeleteReleaseByID(ctx, id); err != nil { return fmt.Errorf("DeleteReleaseByID: %w", err) diff --git a/services/repository/branch.go b/services/repository/branch.go index a085026ae1563..45e9ed7f74077 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -135,13 +135,14 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m }); err != nil { return "", err } - refID, err := gitRepo.GetRefCommitID(git.BranchPrefix + to) + refNameTo := git.RefNameFromBranch(to) + refID, err := gitRepo.GetRefCommitID(refNameTo.String()) if err != nil { return "", err } - notification.NotifyDeleteRef(ctx, doer, repo, "branch", git.BranchPrefix+from) - notification.NotifyCreateRef(ctx, doer, repo, "branch", git.BranchPrefix+to, refID) + notification.NotifyDeleteRef(ctx, doer, repo, git.RefNameFromBranch(from)) + notification.NotifyCreateRef(ctx, doer, repo, refNameTo, refID) return "", nil } @@ -183,7 +184,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // Don't return error below this if err := PushUpdate( &repo_module.PushUpdateOptions{ - RefFullName: git.BranchPrefix + branchName, + RefFullName: git.RefName(git.BranchPrefix + branchName), OldCommitID: commit.ID.String(), NewCommitID: git.EmptySHA, PusherID: doer.ID, diff --git a/services/repository/cache.go b/services/repository/cache.go index 6fd4fa7250f50..1c61bb6457df6 100644 --- a/services/repository/cache.go +++ b/services/repository/cache.go @@ -5,7 +5,6 @@ package repository import ( "context" - "strings" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/cache" @@ -13,28 +12,27 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func getRefName(fullRefName string) string { - if strings.HasPrefix(fullRefName, git.TagPrefix) { - return fullRefName[len(git.TagPrefix):] - } else if strings.HasPrefix(fullRefName, git.BranchPrefix) { - return fullRefName[len(git.BranchPrefix):] - } - return "" -} - // CacheRef cachhe last commit information of the branch or the tag -func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, fullRefName string) error { +func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, fullRefName git.RefName) error { if !setting.CacheService.LastCommit.Enabled { return nil } - commit, err := gitRepo.GetCommit(fullRefName) + var commit *git.Commit + var err error + if fullRefName.IsBranch() { + commit, err = gitRepo.GetBranchCommit(fullRefName.ShortName()) + } else if fullRefName.IsTag() { + commit, err = gitRepo.GetTagCommit(fullRefName.ShortName()) + } else { + return nil + } if err != nil { return err } if gitRepo.LastCommitCache == nil { - commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(getRefName(fullRefName), true), commit.CommitsCount) + commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(fullRefName.ShortName(), true), commit.CommitsCount) if err != nil { return err } diff --git a/services/repository/push.go b/services/repository/push.go index c7ea8f336e538..aba625ddb0b2a 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -107,7 +107,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { if opts.IsNewRef() && opts.IsDelRef() { return fmt.Errorf("old and new revisions are both %s", git.EmptySHA) } - if opts.IsTag() { // If is tag reference + if opts.RefFullName.IsTag() { // If is tag reference if pusher == nil || pusher.ID != opts.PusherID { if opts.PusherID == user_model.ActionsUserID { pusher = user_model.NewActionsUser() @@ -123,13 +123,13 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { notification.NotifyPushCommits( ctx, pusher, repo, &repo_module.PushUpdateOptions{ - RefFullName: git.TagPrefix + tagName, + RefFullName: git.RefName(git.TagPrefix + tagName), OldCommitID: opts.OldCommitID, NewCommitID: git.EmptySHA, }, repo_module.NewPushCommits()) delTags = append(delTags, tagName) - notification.NotifyDeleteRef(ctx, pusher, repo, "tag", opts.RefFullName) + notification.NotifyDeleteRef(ctx, pusher, repo, opts.RefFullName) } else { // is new tag newCommit, err := gitRepo.GetCommit(opts.NewCommitID) if err != nil { @@ -143,15 +143,15 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { notification.NotifyPushCommits( ctx, pusher, repo, &repo_module.PushUpdateOptions{ - RefFullName: git.TagPrefix + tagName, + RefFullName: opts.RefFullName, OldCommitID: git.EmptySHA, NewCommitID: opts.NewCommitID, }, commits) addTags = append(addTags, tagName) - notification.NotifyCreateRef(ctx, pusher, repo, "tag", opts.RefFullName, opts.NewCommitID) + notification.NotifyCreateRef(ctx, pusher, repo, opts.RefFullName, opts.NewCommitID) } - } else if opts.IsBranch() { // If is branch reference + } else if opts.RefFullName.IsBranch() { // If is branch reference if pusher == nil || pusher.ID != opts.PusherID { if opts.PusherID == user_model.ActionsUserID { pusher = user_model.NewActionsUser() @@ -198,7 +198,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { if err != nil { return fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err) } - notification.NotifyCreateRef(ctx, pusher, repo, "branch", opts.RefFullName, opts.NewCommitID) + notification.NotifyCreateRef(ctx, pusher, repo, opts.RefFullName, opts.NewCommitID) } else { l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) if err != nil { @@ -269,7 +269,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) } } else { - notification.NotifyDeleteRef(ctx, pusher, repo, "branch", opts.RefFullName) + notification.NotifyDeleteRef(ctx, pusher, repo, opts.RefFullName) if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil { // close all related pulls log.Error("close related pull request failed: %v", err) diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 99ee6e4d192b8..69fae03299a83 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -36,7 +36,7 @@ func (d *DingtalkPayload) JSONPayload() ([]byte, error) { // Create implements PayloadConvertor Create method func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil @@ -45,7 +45,7 @@ func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete implements PayloadConvertor Delete method func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil @@ -61,7 +61,7 @@ func (d *DingtalkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 02f0fb8720533..204587eca5b1e 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -112,7 +112,7 @@ var _ PayloadConvertor = &DiscordPayload{} // Create implements PayloadConvertor Create method func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName), greenColor), nil @@ -121,7 +121,7 @@ func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete implements PayloadConvertor Delete method func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // deleted tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName), redColor), nil @@ -137,7 +137,7 @@ func (d *DiscordPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 4fbf8f76a90ae..885cde3bc5195 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -48,7 +48,7 @@ var _ PayloadConvertor = &FeishuPayload{} // Create implements PayloadConvertor Create method func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() text := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) return newFeishuTextPayload(text), nil @@ -57,7 +57,7 @@ func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete implements PayloadConvertor Delete method func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() text := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) return newFeishuTextPayload(text), nil @@ -73,7 +73,7 @@ func (f *FeishuPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index cf2b503cdc2df..df97b43b64ca1 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -73,7 +73,7 @@ func MatrixLinkFormatter(url, text string) string { // MatrixLinkToRef Matrix-formatter link to a repo ref func MatrixLinkToRef(repoURL, ref string) string { - refName := git.RefEndName(ref) + refName := git.RefName(ref).ShortName() switch { case strings.HasPrefix(ref, git.BranchPrefix): return MatrixLinkFormatter(repoURL+"/src/branch/"+util.PathEscapeSegments(refName), refName) @@ -95,7 +95,7 @@ func (m *MatrixPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete composes Matrix payload for delete a branch or tag. func (m *MatrixPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName) text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index 60ef334ded9ac..6ad58a6247fd1 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -70,7 +70,7 @@ var _ PayloadConvertor = &MSTeamsPayload{} // Create implements PayloadConvertor Create method func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) return createMSTeamsPayload( @@ -87,7 +87,7 @@ func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete implements PayloadConvertor Delete method func (m *MSTeamsPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // deleted tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) return createMSTeamsPayload( @@ -119,7 +119,7 @@ func (m *MSTeamsPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 1f7cb8d988a38..55cc6378c9f98 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -596,7 +596,7 @@ func (m *webhookNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo } if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ - Ref: opts.RefFullName, + Ref: opts.RefFullName.String(), // Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: setting.AppURL + commits.CompareURL, @@ -719,15 +719,15 @@ func (m *webhookNotifier) NotifyPullRequestReview(ctx context.Context, pr *issue } } -func (m *webhookNotifier) NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { +func (m *webhookNotifier) NotifyCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { apiPusher := convert.ToUser(ctx, pusher, nil) apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) - refName := git.RefEndName(refFullName) + refName := refFullName.ShortName() if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventCreate, &api.CreatePayload{ - Ref: refName, + Ref: refName, // FIXME: should it be a full ref name? Sha: refID, - RefType: refType, + RefType: refFullName.RefGroup(), Repo: apiRepo, Sender: apiPusher, }); err != nil { @@ -756,19 +756,19 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(ctx context.Context, doe } } -func (m *webhookNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { +func (m *webhookNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { apiPusher := convert.ToUser(ctx, pusher, nil) apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) - refName := git.RefEndName(refFullName) + refName := refFullName.ShortName() if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventDelete, &api.DeletePayload{ - Ref: refName, - RefType: refType, + Ref: refName, // FIXME: should it be a full ref name? + RefType: refFullName.RefGroup(), PusherType: api.PusherTypeUser, Repo: apiRepo, Sender: apiPusher, }); err != nil { - log.Error("PrepareWebhooks.(delete %s): %v", refType, err) + log.Error("PrepareWebhooks.(delete %s): %v", refFullName.RefGroup(), err) } } @@ -810,7 +810,7 @@ func (m *webhookNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use } if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ - Ref: opts.RefFullName, + Ref: opts.RefFullName.String(), Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: setting.AppURL + commits.CompareURL, @@ -825,12 +825,12 @@ func (m *webhookNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use } } -func (m *webhookNotifier) NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { - m.NotifyCreateRef(ctx, pusher, repo, refType, refFullName, refID) +func (m *webhookNotifier) NotifySyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { + m.NotifyCreateRef(ctx, pusher, repo, refFullName, refID) } -func (m *webhookNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refType, refFullName string) { - m.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName) +func (m *webhookNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { + m.NotifyDeleteRef(ctx, pusher, repo, refFullName) } func (m *webhookNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { diff --git a/services/webhook/slack.go b/services/webhook/slack.go index c2d4a7731e0a4..0cb27bb3dd6dc 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -93,7 +93,7 @@ func SlackLinkFormatter(url, text string) string { // SlackLinkToRef slack-formatter link to a repo ref func SlackLinkToRef(repoURL, ref string) string { url := git.RefURL(repoURL, ref) - refName := git.RefEndName(ref) + refName := git.RefName(ref).ShortName() return SlackLinkFormatter(url, refName) } @@ -110,7 +110,7 @@ func (s *SlackPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete composes Slack payload for delete a branch or tag. func (s *SlackPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName) text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index e5c731fc9291c..2d0484648bb8e 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -57,7 +57,7 @@ func (t *TelegramPayload) JSONPayload() ([]byte, error) { // Create implements PayloadConvertor Create method func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf(`[%s] %s %s created`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, p.Repo.HTMLURL+"/src/"+refName, refName) @@ -67,7 +67,7 @@ func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // Delete implements PayloadConvertor Delete method func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf(`[%s] %s %s deleted`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, p.Repo.HTMLURL+"/src/"+refName, refName) @@ -84,7 +84,7 @@ func (t *TelegramPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index dc8810c4a6ae2..a7680f1c67112 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -56,7 +56,7 @@ var _ PayloadConvertor = &WechatworkPayload{} // Create implements PayloadConvertor Create method func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) return newWechatworkMarkdownPayload(title), nil @@ -65,7 +65,7 @@ func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) // Delete implements PayloadConvertor Delete method func (f *WechatworkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { // created tag/branch - refName := git.RefEndName(p.Ref) + refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) return newWechatworkMarkdownPayload(title), nil @@ -81,7 +81,7 @@ func (f *WechatworkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { // Push implements PayloadConvertor Push method func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) { var ( - branchName = git.RefEndName(p.Ref) + branchName = git.RefName(p.Ref).ShortName() commitDesc string ) From 3cba6057c09d3081ab7b338fab5dd2df2e650c2a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 17:49:28 +0800 Subject: [PATCH 02/17] Fix fmt --- routers/web/web.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/web.go b/routers/web/web.go index 9bdfa1e68374e..b0db8892ea35c 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1309,7 +1309,7 @@ func registerRoutes(m *web.Route) { }, repo.MustBeNotEmpty, reqRepoCodeReader) m.Group("", func() { - m.Get("/graph", repo.Graph) + m.Get("/graph", repo.Graph) m.Get("/commit/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff) m.Get("/cherry-pick/{sha:([a-f0-9]{7,40})$}", repo.SetEditorconfigIfExists, repo.CherryPick) }, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) From 4346019fa652e7abb20389984b5c0d844a9f3da6 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 18:09:41 +0800 Subject: [PATCH 03/17] revert some changes and fix tests --- modules/git/ref.go | 4 ---- services/actions/notifier.go | 8 ++++---- services/mirror/mirror_pull.go | 1 + services/mirror/mirror_test.go | 22 +++++++++++++++++----- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/modules/git/ref.go b/modules/git/ref.go index d8118270d2d7d..d7197b5241601 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -76,10 +76,6 @@ func RefNameFromTag(shortName string) RefName { return RefName(TagPrefix + shortName) } -func (ref RefName) IsValid() bool { - return ref.IsBranch() || ref.IsTag() || ref.IsRemote() || ref.IsPull() -} - func (ref RefName) String() string { return string(ref) } diff --git a/services/actions/notifier.go b/services/actions/notifier.go index f73ac81f255c2..48eec5283b21b 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -373,9 +373,9 @@ func (n *actionsNotifier) NotifyCreateRef(ctx context.Context, pusher *user_mode apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) newNotifyInput(repo, pusher, webhook_module.HookEventCreate). - WithRef(refFullName.String()). + WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name WithPayload(&api.CreatePayload{ - Ref: refFullName.String(), + Ref: refFullName.ShortName(), Sha: refID, RefType: refFullName.RefGroup(), Repo: apiRepo, @@ -391,9 +391,9 @@ func (n *actionsNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_mode apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) newNotifyInput(repo, pusher, webhook_module.HookEventDelete). - WithRef(refFullName.String()). + WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name WithPayload(&api.DeletePayload{ - Ref: refFullName.String(), + Ref: refFullName.ShortName(), RefType: refFullName.RefGroup(), PusherType: api.PusherTypeUser, Repo: apiRepo, diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 0691146c58ef7..5b2f2c5eb7e7e 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -93,6 +93,7 @@ type mirrorSyncResult struct { func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { results := make([]*mirrorSyncResult, 0, 3) lines := strings.Split(output, "\n") + fmt.Println("----", lines) for i := range lines { // Make sure reference name is presented before continue idx := strings.Index(lines[i], "-> ") diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go index 3a38b19ccec09..1c1fa0d01fd85 100644 --- a/services/mirror/mirror_test.go +++ b/services/mirror/mirror_test.go @@ -6,17 +6,29 @@ package mirror import ( "testing" + "code.gitea.io/gitea/modules/git" "github.com/stretchr/testify/assert" ) func Test_parseRemoteUpdateOutput(t *testing.T) { output := ` -* [new tag] v0.1.8 -> v0.1.8 -* [new branch] master -> origin/master -- [deleted] (none) -> origin/test -+ f895a1e...957a993 test -> origin/test (forced update) + * [new tag] v0.1.8 -> v0.1.8 + * [new branch] master -> origin/master + - [deleted] (none) -> origin/test + + f895a1e...957a993 test -> origin/test (forced update) ` results := parseRemoteUpdateOutput(output, "origin") assert.Len(t, results, 4) - assert.EqualValues(t, "refs/tag/v0.1.8", results[0].refName) + assert.EqualValues(t, "refs/tags/v0.1.8", results[0].refName.String()) + assert.EqualValues(t, git.EmptySHA, results[0].oldCommitID) + + assert.EqualValues(t, "refs/heads/master", results[1].refName.String()) + assert.EqualValues(t, git.EmptySHA, results[1].oldCommitID) + + assert.EqualValues(t, "refs/heads/test", results[2].refName.String()) + assert.EqualValues(t, git.EmptySHA, results[2].newCommitID) + + assert.EqualValues(t, "refs/heads/test", results[3].refName.String()) + assert.EqualValues(t, "f895a1e", results[3].oldCommitID) + assert.EqualValues(t, "957a993", results[3].newCommitID) } From a3bfbdb65016f798a92d635d82e450e490bef03c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 21:37:08 +0800 Subject: [PATCH 04/17] Apply suggestions from code review Co-authored-by: delvh --- modules/git/repo_branch.go | 2 +- services/release/release.go | 2 +- services/repository/branch.go | 2 +- services/repository/push.go | 6 +++--- services/webhook/notifier.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 9da44ede1d408..acd5b29405d66 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -16,7 +16,7 @@ const BranchPrefix = "refs/heads/" // AGit Flow -// ForPrefix special ref to create a ref: refs/for// +// ForPrefix special ref to create a pull request: refs/for// // or refs/for/ -o topic='' const ForPrefix = "refs/for/" diff --git a/services/release/release.go b/services/release/release.go index 2f6be933c1ba4..c1190305b6688 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -80,7 +80,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel commits.HeadCommit = repository.CommitToPushCommit(commit) commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String()) - refFullName := git.RefName(git.TagPrefix + rel.TagName) + refFullName := git.RefNameFromTag(rel.TagName) notification.NotifyPushCommits( ctx, rel.Publisher, rel.Repo, &repository.PushUpdateOptions{ diff --git a/services/repository/branch.go b/services/repository/branch.go index 45e9ed7f74077..f0dc02a436822 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -184,7 +184,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R // Don't return error below this if err := PushUpdate( &repo_module.PushUpdateOptions{ - RefFullName: git.RefName(git.BranchPrefix + branchName), + RefFullName: git.RefNameFromBranch(branchName), OldCommitID: commit.ID.String(), NewCommitID: git.EmptySHA, PusherID: doer.ID, diff --git a/services/repository/push.go b/services/repository/push.go index aba625ddb0b2a..2b160f525d2a5 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -107,7 +107,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { if opts.IsNewRef() && opts.IsDelRef() { return fmt.Errorf("old and new revisions are both %s", git.EmptySHA) } - if opts.RefFullName.IsTag() { // If is tag reference + if opts.RefFullName.IsTag() { if pusher == nil || pusher.ID != opts.PusherID { if opts.PusherID == user_model.ActionsUserID { pusher = user_model.NewActionsUser() @@ -123,7 +123,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { notification.NotifyPushCommits( ctx, pusher, repo, &repo_module.PushUpdateOptions{ - RefFullName: git.RefName(git.TagPrefix + tagName), + RefFullName: git.RefNameFromTag(tagName), OldCommitID: opts.OldCommitID, NewCommitID: git.EmptySHA, }, repo_module.NewPushCommits()) @@ -151,7 +151,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { addTags = append(addTags, tagName) notification.NotifyCreateRef(ctx, pusher, repo, opts.RefFullName, opts.NewCommitID) } - } else if opts.RefFullName.IsBranch() { // If is branch reference + } else if opts.RefFullName.IsBranch() { if pusher == nil || pusher.ID != opts.PusherID { if opts.PusherID == user_model.ActionsUserID { pusher = user_model.NewActionsUser() diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 55cc6378c9f98..7e22529da2c12 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -596,7 +596,7 @@ func (m *webhookNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo } if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ - Ref: opts.RefFullName.String(), // + Ref: opts.RefFullName.String(), Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: setting.AppURL + commits.CompareURL, From 13e683b1a19e006ef06b83fbfdb4016d9aad7367 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 21:39:12 +0800 Subject: [PATCH 05/17] Fix lint --- modules/git/ref.go | 7 ++++--- services/mirror/mirror_pull.go | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/git/ref.go b/modules/git/ref.go index d7197b5241601..cfae5b3b7b658 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -145,11 +145,12 @@ func (ref RefName) RefGroup() string { // RefURL returns the absolute URL for a ref in a repository func RefURL(repoURL, ref string) string { - refName := util.PathEscapeSegments(RefName(ref).ShortName()) + refFullName := RefName(ref) + refName := util.PathEscapeSegments(refFullName.ShortName()) switch { - case strings.HasPrefix(ref, BranchPrefix): + case refFullName.IsBranch(): return repoURL + "/src/branch/" + refName - case strings.HasPrefix(ref, TagPrefix): + case refFullName.IsTag(): return repoURL + "/src/tag/" + refName case !IsValidSHAPattern(ref): // assume they mean a branch diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 5b2f2c5eb7e7e..0691146c58ef7 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -93,7 +93,6 @@ type mirrorSyncResult struct { func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { results := make([]*mirrorSyncResult, 0, 3) lines := strings.Split(output, "\n") - fmt.Println("----", lines) for i := range lines { // Make sure reference name is presented before continue idx := strings.Index(lines[i], "-> ") From ce9207c0d3716efd9f97ea23a0c090a794039622 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 21:55:17 +0800 Subject: [PATCH 06/17] Fix test --- services/mirror/mirror_pull.go | 14 +++++++++----- services/mirror/mirror_test.go | 25 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 0691146c58ef7..02f26257feb65 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -84,11 +84,13 @@ type mirrorSyncResult struct { } // parseRemoteUpdateOutput detects create, update and delete operations of references from upstream. -/* possible output example: -* [new tag] v0.1.8 -> v0.1.8 -* [new branch] master -> origin/master -- [deleted] (none) -> origin/test -+ f895a1e...957a993 test -> origin/test (forced update) +// possible output example: +/* +// * [new tag] v0.1.8 -> v0.1.8 +// * [new branch] master -> origin/master +// - [deleted] (none) -> origin/test +// 957a993..a87ba5f test -> origin/test +// + f895a1e...957a993 test -> origin/test (forced update) */ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { results := make([]*mirrorSyncResult, 0, 3) @@ -124,6 +126,7 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { if idx := strings.Index(refName, " "); idx > -1 { refName = refName[:idx] } + refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") delimIdx := strings.Index(lines[i][3:], " ") if delimIdx == -1 { log.Error("SHA delimiter not found: %q", lines[i]) @@ -150,6 +153,7 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { log.Error("Expect two SHAs but not what found: %q", lines[i]) continue } + refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") results = append(results, &mirrorSyncResult{ refName: git.RefNameFromBranch(refName), oldCommitID: shas[0], diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go index 1c1fa0d01fd85..a789e44683611 100644 --- a/services/mirror/mirror_test.go +++ b/services/mirror/mirror_test.go @@ -6,7 +6,6 @@ package mirror import ( "testing" - "code.gitea.io/gitea/modules/git" "github.com/stretchr/testify/assert" ) @@ -14,21 +13,29 @@ func Test_parseRemoteUpdateOutput(t *testing.T) { output := ` * [new tag] v0.1.8 -> v0.1.8 * [new branch] master -> origin/master - - [deleted] (none) -> origin/test - + f895a1e...957a993 test -> origin/test (forced update) + - [deleted] (none) -> origin/test1 + + f895a1e...957a993 test2 -> origin/test2 (forced update) + 957a993..a87ba5f test3 -> origin/test3 ` results := parseRemoteUpdateOutput(output, "origin") - assert.Len(t, results, 4) + assert.Len(t, results, 5) assert.EqualValues(t, "refs/tags/v0.1.8", results[0].refName.String()) - assert.EqualValues(t, git.EmptySHA, results[0].oldCommitID) + assert.EqualValues(t, gitShortEmptySha, results[0].oldCommitID) + assert.EqualValues(t, "", results[0].newCommitID) assert.EqualValues(t, "refs/heads/master", results[1].refName.String()) - assert.EqualValues(t, git.EmptySHA, results[1].oldCommitID) + assert.EqualValues(t, gitShortEmptySha, results[1].oldCommitID) + assert.EqualValues(t, "", results[1].newCommitID) - assert.EqualValues(t, "refs/heads/test", results[2].refName.String()) - assert.EqualValues(t, git.EmptySHA, results[2].newCommitID) + assert.EqualValues(t, "refs/heads/test1", results[2].refName.String()) + assert.EqualValues(t, "", results[2].oldCommitID) + assert.EqualValues(t, gitShortEmptySha, results[2].newCommitID) - assert.EqualValues(t, "refs/heads/test", results[3].refName.String()) + assert.EqualValues(t, "refs/heads/test2", results[3].refName.String()) assert.EqualValues(t, "f895a1e", results[3].oldCommitID) assert.EqualValues(t, "957a993", results[3].newCommitID) + + assert.EqualValues(t, "refs/heads/test3", results[4].refName.String()) + assert.EqualValues(t, "957a993", results[4].oldCommitID) + assert.EqualValues(t, "a87ba5f", results[4].newCommitID) } From 40e37a4db6731281ca4d1d8b5d94311c8037641a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 10 May 2023 22:22:18 +0800 Subject: [PATCH 07/17] revert some change --- models/activities/action.go | 13 +------------ services/repository/cache.go | 10 +--------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 33e476e34ddb9..57f579372f805 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -26,7 +26,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" "xorm.io/builder" "xorm.io/xorm/schemas" @@ -367,17 +366,7 @@ func (a *Action) GetBranch() string { // GetRefLink returns the action's ref link. func (a *Action) GetRefLink() string { - switch { - case strings.HasPrefix(a.RefName, git.BranchPrefix): - return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) - case strings.HasPrefix(a.RefName, git.TagPrefix): - return a.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.TagPrefix)) - case len(a.RefName) == git.SHAFullLength && git.IsValidSHAPattern(a.RefName): - return a.GetRepoLink() + "/src/commit/" + a.RefName - default: - // FIXME: we will just assume it's a branch - this was the old way - at some point we may want to enforce that there is always a ref here. - return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) - } + return git.RefURL(a.GetRepoLink(), a.RefName) } // GetTag returns the action's repository tag. diff --git a/services/repository/cache.go b/services/repository/cache.go index 1c61bb6457df6..91351cbf491ae 100644 --- a/services/repository/cache.go +++ b/services/repository/cache.go @@ -18,15 +18,7 @@ func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep return nil } - var commit *git.Commit - var err error - if fullRefName.IsBranch() { - commit, err = gitRepo.GetBranchCommit(fullRefName.ShortName()) - } else if fullRefName.IsTag() { - commit, err = gitRepo.GetTagCommit(fullRefName.ShortName()) - } else { - return nil - } + commit, err := gitRepo.GetCommit(fullRefName.String()) if err != nil { return err } From 3b61f567d7038260277821bf0dbd3af36fce3d42 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 11 May 2023 14:38:05 +0800 Subject: [PATCH 08/17] handle more situation --- services/mirror/mirror_pull.go | 28 +++++++++++++++++----------- services/mirror/mirror_test.go | 19 ++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 02f26257feb65..3d2f8542e7d70 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -88,10 +88,12 @@ type mirrorSyncResult struct { /* // * [new tag] v0.1.8 -> v0.1.8 // * [new branch] master -> origin/master -// - [deleted] (none) -> origin/test +// - [deleted] (none) -> origin/test // delete a branch +// - [deleted] (none) -> 1 // delete a tag // 957a993..a87ba5f test -> origin/test // + f895a1e...957a993 test -> origin/test (forced update) */ +// TODO: return whether it's a force update func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { results := make([]*mirrorSyncResult, 0, 3) lines := strings.Split(output, "\n") @@ -102,7 +104,7 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { continue } - refName := lines[i][idx+3:] + refName := strings.TrimSpace(lines[i][idx+3:]) switch { case strings.HasPrefix(lines[i], " * [new tag]"): // new tag @@ -111,22 +113,27 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { oldCommitID: gitShortEmptySha, }) case strings.HasPrefix(lines[i], " * [new branch]"): // new branch - refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") + refName = strings.TrimPrefix(refName, remoteName+"/") results = append(results, &mirrorSyncResult{ refName: git.RefNameFromBranch(refName), oldCommitID: gitShortEmptySha, }) case strings.HasPrefix(lines[i], " - "): // Delete reference - refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") + isTag := !strings.HasPrefix(refName, remoteName+"/") + var refFullName git.RefName + if isTag { + refFullName = git.RefNameFromTag(refName) + } else { + refFullName = git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")) + } results = append(results, &mirrorSyncResult{ - refName: git.RefNameFromBranch(refName), + refName: refFullName, newCommitID: gitShortEmptySha, }) case strings.HasPrefix(lines[i], " + "): // Force update if idx := strings.Index(refName, " "); idx > -1 { refName = refName[:idx] } - refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") delimIdx := strings.Index(lines[i][3:], " ") if delimIdx == -1 { log.Error("SHA delimiter not found: %q", lines[i]) @@ -138,7 +145,7 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { continue } results = append(results, &mirrorSyncResult{ - refName: git.RefNameFromBranch(refName), + refName: git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")), oldCommitID: shas[0], newCommitID: shas[1], }) @@ -153,9 +160,8 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult { log.Error("Expect two SHAs but not what found: %q", lines[i]) continue } - refName = strings.TrimPrefix(strings.TrimSpace(refName), remoteName+"/") results = append(results, &mirrorSyncResult{ - refName: git.RefNameFromBranch(refName), + refName: git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")), oldCommitID: shas[0], newCommitID: shas[1], }) @@ -216,11 +222,11 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) - cmd := git.NewCommand(ctx, "remote", "update") + cmd := git.NewCommand(ctx, "fetch") if m.EnablePrune { cmd.AddArguments("--prune") } - cmd.AddDynamicArguments(m.GetRemoteName()) + cmd.AddArguments("--tags").AddDynamicArguments(m.GetRemoteName()) remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName()) if remoteErr != nil { diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_test.go index a789e44683611..8ad524b608de4 100644 --- a/services/mirror/mirror_test.go +++ b/services/mirror/mirror_test.go @@ -14,11 +14,12 @@ func Test_parseRemoteUpdateOutput(t *testing.T) { * [new tag] v0.1.8 -> v0.1.8 * [new branch] master -> origin/master - [deleted] (none) -> origin/test1 + - [deleted] (none) -> tag1 + f895a1e...957a993 test2 -> origin/test2 (forced update) 957a993..a87ba5f test3 -> origin/test3 ` results := parseRemoteUpdateOutput(output, "origin") - assert.Len(t, results, 5) + assert.Len(t, results, 6) assert.EqualValues(t, "refs/tags/v0.1.8", results[0].refName.String()) assert.EqualValues(t, gitShortEmptySha, results[0].oldCommitID) assert.EqualValues(t, "", results[0].newCommitID) @@ -31,11 +32,15 @@ func Test_parseRemoteUpdateOutput(t *testing.T) { assert.EqualValues(t, "", results[2].oldCommitID) assert.EqualValues(t, gitShortEmptySha, results[2].newCommitID) - assert.EqualValues(t, "refs/heads/test2", results[3].refName.String()) - assert.EqualValues(t, "f895a1e", results[3].oldCommitID) - assert.EqualValues(t, "957a993", results[3].newCommitID) + assert.EqualValues(t, "refs/tags/tag1", results[3].refName.String()) + assert.EqualValues(t, "", results[3].oldCommitID) + assert.EqualValues(t, gitShortEmptySha, results[3].newCommitID) - assert.EqualValues(t, "refs/heads/test3", results[4].refName.String()) - assert.EqualValues(t, "957a993", results[4].oldCommitID) - assert.EqualValues(t, "a87ba5f", results[4].newCommitID) + assert.EqualValues(t, "refs/heads/test2", results[4].refName.String()) + assert.EqualValues(t, "f895a1e", results[4].oldCommitID) + assert.EqualValues(t, "957a993", results[4].newCommitID) + + assert.EqualValues(t, "refs/heads/test3", results[5].refName.String()) + assert.EqualValues(t, "957a993", results[5].oldCommitID) + assert.EqualValues(t, "a87ba5f", results[5].newCommitID) } From 4261cc745d5a741ca83da00cb72ff3f94bb81cf0 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 11 May 2023 15:18:16 +0800 Subject: [PATCH 09/17] fetch tags when migrating a mirror repository --- modules/repository/repo.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/repository/repo.go b/modules/repository/repo.go index a1dba8fc6af0a..ff273d8931ca5 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -200,7 +200,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, mirrorModel.Interval = 0 mirrorModel.NextUpdateUnix = 0 } else if parsedInterval < setting.Mirror.MinInterval { - err := fmt.Errorf("Interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) + err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval) log.Error("Interval: %s is too frequent", opts.MirrorInterval) return repo, err } else { @@ -217,6 +217,15 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, if err = UpdateRepository(ctx, repo, false); err != nil { return nil, err } + + // this is necessary for sync local tags from remote + if stdout, _, err := git.NewCommand(ctx, "config", "--add"). + AddDynamicArguments(fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName())). + AddDynamicArguments(`+refs/tags/*:refs/tags/*`). + RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { + log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) + } } else { if err = UpdateRepoSize(ctx, repo); err != nil { log.Error("Failed to update size for repository: %v", err) From 6faac1efc505642291cfeba3f87d444d92199c8a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 11 May 2023 15:23:19 +0800 Subject: [PATCH 10/17] make code simple --- modules/repository/repo.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/repository/repo.go b/modules/repository/repo.go index ff273d8931ca5..62e1f31b9e5e6 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -219,9 +219,9 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, } // this is necessary for sync local tags from remote - if stdout, _, err := git.NewCommand(ctx, "config", "--add"). - AddDynamicArguments(fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName())). - AddDynamicArguments(`+refs/tags/*:refs/tags/*`). + configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) + if stdout, _, err := git.NewCommand(ctx, "config"). + AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). RunStdString(&git.RunOpts{Dir: repoPath}); err != nil { log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) From 5b31c36f20b746eb7d2ff6f7636c63620dab7857 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 11 May 2023 21:33:57 +0800 Subject: [PATCH 11/17] Fix the problem --- modules/git/ref_test.go | 4 +++- modules/notification/indexer/indexer.go | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/git/ref_test.go b/modules/git/ref_test.go index 6545dfa0cb661..f177a9f6d3032 100644 --- a/modules/git/ref_test.go +++ b/modules/git/ref_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestRefEndName(t *testing.T) { +func TestRefName(t *testing.T) { // Test branch names (with and without slash). assert.Equal(t, "foo", RefName("refs/heads/foo").ShortName()) assert.Equal(t, "feature/foo", RefName("refs/heads/feature/foo").ShortName()) @@ -18,6 +18,8 @@ func TestRefEndName(t *testing.T) { assert.Equal(t, "foo", RefName("refs/tags/foo").ShortName()) assert.Equal(t, "release/foo", RefName("refs/tags/release/foo").ShortName()) + assert.Equal(t, "main", RefName("refs/for/main").ShortName()) + // Test commit hashes. assert.Equal(t, "c0ffee", RefName("c0ffee").ShortName()) } diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index ef93df5e61eba..d38cea89f6072 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -125,6 +125,10 @@ func (r *indexerNotifier) NotifyMigrateRepository(ctx context.Context, doer, u * } func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { + if !opts.RefFullName.IsBranch() { + return + } + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } @@ -134,6 +138,10 @@ func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo } func (r *indexerNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { + if !opts.RefFullName.IsBranch() { + return + } + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } From 87e15647375bd205c3f6bdce209d514d42b7373a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 25 May 2023 20:42:35 +0800 Subject: [PATCH 12/17] Use branch name when necessary --- modules/actions/workflows.go | 8 ++++---- modules/git/ref.go | 24 ++++++++++++++++++++++++ modules/notification/indexer/indexer.go | 4 ++-- modules/repository/push.go | 16 ---------------- routers/private/hook_post_receive.go | 6 +++--- routers/private/hook_pre_receive.go | 6 +++--- services/agit/agit.go | 2 +- services/mirror/mirror_pull.go | 2 +- services/repository/push.go | 4 ++-- 9 files changed, 40 insertions(+), 32 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index d560b7718f27a..d9459288b183e 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -204,7 +204,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa if err != nil { break } - if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + if !workflowpattern.Skip(patterns, []string{refName.BranchName()}, &workflowpattern.EmptyTraceWriter{}) { matchTimes++ } case "branches-ignore": @@ -216,7 +216,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa if err != nil { break } - if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + if !workflowpattern.Filter(patterns, []string{refName.BranchName()}, &workflowpattern.EmptyTraceWriter{}) { matchTimes++ } case "tags": @@ -228,7 +228,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa if err != nil { break } - if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + if !workflowpattern.Skip(patterns, []string{refName.TagName()}, &workflowpattern.EmptyTraceWriter{}) { matchTimes++ } case "tags-ignore": @@ -240,7 +240,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa if err != nil { break } - if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + if !workflowpattern.Filter(patterns, []string{refName.TagName()}, &workflowpattern.EmptyTraceWriter{}) { matchTimes++ } case "paths": diff --git a/modules/git/ref.go b/modules/git/ref.go index cfae5b3b7b658..13af3f02a792e 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -100,6 +100,30 @@ func (ref RefName) IsFor() bool { return strings.HasPrefix(string(ref), ForPrefix) } +// TagName returns simple tag name if it's an operation to a tag +func (ref RefName) TagName() string { + if ref.IsTag() { + return ref.ShortName() + } + return "" +} + +// BranchName returns simple branch name if it's an operation to branch +func (ref RefName) BranchName() string { + if ref.IsBranch() { + return ref.ShortName() + } + return "" +} + +func (ref RefName) ForBranchName() string { + refName := string(ref) + if strings.HasPrefix(refName, ForPrefix) { + return strings.TrimPrefix(refName, ForPrefix) + } + return "" +} + // ShortName returns the short name of the reference name func (ref RefName) ShortName() string { refName := string(ref) diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index d38cea89f6072..0661c2c1ab49d 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -129,7 +129,7 @@ func (r *indexerNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo return } - if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.BranchName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { @@ -142,7 +142,7 @@ func (r *indexerNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use return } - if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.ShortName() == repo.DefaultBranch { + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.BranchName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { diff --git a/modules/repository/push.go b/modules/repository/push.go index 4485b604c932a..ea03f9e1537f7 100644 --- a/modules/repository/push.go +++ b/modules/repository/push.go @@ -58,22 +58,6 @@ func (opts *PushUpdateOptions) IsDelBranch() bool { return opts.RefFullName.IsBranch() && opts.IsDelRef() } -// TagName returns simple tag name if it's an operation to a tag -func (opts *PushUpdateOptions) TagName() string { - if opts.RefFullName.IsTag() { - return opts.RefFullName.ShortName() - } - return "" -} - -// BranchName returns simple branch name if it's an operation to branch -func (opts *PushUpdateOptions) BranchName() string { - if opts.RefFullName.IsBranch() { - return opts.RefFullName.ShortName() - } - return "" -} - // RefName returns simple name for ref func (opts *PushUpdateOptions) RefName() string { return opts.RefFullName.ShortName() diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index d3b06add4a0a9..5ec787dba659c 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -67,7 +67,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { RepoName: repoName, } updates = append(updates, option) - if repo.IsEmpty && refFullName.IsBranch() && (option.BranchName() == "master" || option.BranchName() == "main") { + if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") { // put the master/main branch first copy(updates[1:], updates) updates[0] = option @@ -79,7 +79,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { if err := repo_service.PushUpdates(updates); err != nil { log.Error("Failed to Update: %s/%s Total Updates: %d", ownerName, repoName, len(updates)) for i, update := range updates { - log.Error("Failed to Update: %s/%s Update: %d/%d: Branch: %s", ownerName, repoName, i, len(updates), update.BranchName()) + log.Error("Failed to Update: %s/%s Update: %d/%d: Branch: %s", ownerName, repoName, i, len(updates), update.RefFullName.BranchName()) } log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err) @@ -195,7 +195,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } } - branch := refFullName.ShortName() + branch := refFullName.BranchName() // If our branch is the default branch of an unforked repo - there's no PR to create or refer to if !repo.IsFork && branch == baseRepo.DefaultBranch { diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 150d6ff7502b4..27d55bd869269 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -136,7 +136,7 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { } func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { - branchName := refFullName.ShortName() + branchName := refFullName.BranchName() ctx.branchName = branchName if !ctx.AssertCanWriteCode() { @@ -373,7 +373,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID string, refF return } - tagName := refFullName.ShortName() + tagName := refFullName.TagName() if !ctx.gotProtectedTags { var err error @@ -423,7 +423,7 @@ func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID stri return } - baseBranchName := refFullName.ShortName() + baseBranchName := refFullName.BranchName() baseBranchExist := false if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { diff --git a/services/agit/agit.go b/services/agit/agit.go index 675dd73bb59fe..208ea109f4c7b 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -56,7 +56,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. continue } - baseBranchName := opts.RefFullNames[i].ShortName() + baseBranchName := opts.RefFullNames[i].ForBranchName() curentTopicBranch := "" if !gitRepo.IsBranchExist(baseBranchName) { // try match refs/for// diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 3d2f8542e7d70..739731048d217 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -562,7 +562,7 @@ func checkAndUpdateEmptyRepository(m *repo_model.Mirror, gitRepo *git.Repository continue } - name := result.refName.ShortName() + name := result.refName.BranchName() if len(firstName) == 0 { firstName = name } diff --git a/services/repository/push.go b/services/repository/push.go index 2b160f525d2a5..f213948916928 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -118,7 +118,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } } } - tagName := opts.TagName() + tagName := opts.RefFullName.TagName() if opts.IsDelRef() { notification.NotifyPushCommits( ctx, pusher, repo, @@ -163,7 +163,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } } - branch := opts.BranchName() + branch := opts.RefFullName.BranchName() if !opts.IsDelRef() { log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name) go pull_service.AddTestPullRequestTask(pusher, repo.ID, branch, true, opts.OldCommitID, opts.NewCommitID) From 82f60cb9f2d1199f23e574303ba8c9d85e81c502 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 25 May 2023 20:58:12 +0800 Subject: [PATCH 13/17] refactor --- modules/git/ref.go | 51 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/modules/git/ref.go b/modules/git/ref.go index 13af3f02a792e..998062d19faca 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -100,47 +100,48 @@ func (ref RefName) IsFor() bool { return strings.HasPrefix(string(ref), ForPrefix) } -// TagName returns simple tag name if it's an operation to a tag -func (ref RefName) TagName() string { - if ref.IsTag() { - return ref.ShortName() +func (ref RefName) nameWithoutPrefix(prefix string) string { + if strings.HasPrefix(string(ref), prefix) { + return strings.TrimPrefix(string(ref), prefix) } return "" } +// TagName returns simple tag name if it's an operation to a tag +func (ref RefName) TagName() string { + return ref.nameWithoutPrefix(TagPrefix) +} + // BranchName returns simple branch name if it's an operation to branch func (ref RefName) BranchName() string { - if ref.IsBranch() { - return ref.ShortName() - } - return "" + return ref.nameWithoutPrefix(BranchPrefix) } func (ref RefName) ForBranchName() string { - refName := string(ref) - if strings.HasPrefix(refName, ForPrefix) { - return strings.TrimPrefix(refName, ForPrefix) - } - return "" + return ref.nameWithoutPrefix(ForPrefix) +} + +func (ref RefName) RemoteName() string { + return ref.nameWithoutPrefix(RemotePrefix) } // ShortName returns the short name of the reference name func (ref RefName) ShortName() string { refName := string(ref) - if strings.HasPrefix(refName, BranchPrefix) { - return strings.TrimPrefix(refName, BranchPrefix) + if ref.IsBranch() { + return ref.BranchName() } - if strings.HasPrefix(refName, TagPrefix) { - return strings.TrimPrefix(refName, TagPrefix) + if ref.IsTag() { + return ref.TagName() } - if strings.HasPrefix(refName, RemotePrefix) { - return strings.TrimPrefix(refName, RemotePrefix) + if ref.IsRemote() { + return ref.RemoteName() } if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen] } - if strings.HasPrefix(refName, ForPrefix) { - return strings.TrimPrefix(refName, ForPrefix) + if ref.IsFor() { + return ref.ForBranchName() } return refName @@ -149,19 +150,19 @@ func (ref RefName) ShortName() string { // RefGroup returns the group type of the reference func (ref RefName) RefGroup() string { refName := string(ref) - if strings.HasPrefix(refName, BranchPrefix) { + if ref.IsBranch() { return "heads" } - if strings.HasPrefix(refName, TagPrefix) { + if ref.IsTag() { return "tags" } - if strings.HasPrefix(refName, RemotePrefix) { + if ref.IsRemote() { return "remotes" } if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { return "pull" } - if strings.HasPrefix(refName, ForPrefix) { + if ref.IsFor() { return "for" } return "" From fb468ee395c894082ce9dd2b3ee7240cf48149bc Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 25 May 2023 21:24:35 +0800 Subject: [PATCH 14/17] Add comment for using git fetch instead of git remote update when mirroring --- services/mirror/mirror_pull.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 739731048d217..53ab632b01c19 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -222,6 +222,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) + // use fetch but not remote update because git fetch support --tags but remote update doesn't cmd := git.NewCommand(ctx, "fetch") if m.EnablePrune { cmd.AddArguments("--prune") From 416d7cfe6302126060cdf457062db16e8c03d01b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 25 May 2023 23:51:50 +0800 Subject: [PATCH 15/17] move variable --- modules/git/ref.go | 7 +++++++ modules/git/repo_branch.go | 8 -------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/git/ref.go b/modules/git/ref.go index 998062d19faca..cca9eb3ca8b0c 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -65,6 +65,12 @@ func (ref *Reference) RefGroup() string { return RefName(ref.Name).RefGroup() } +// ForPrefix special ref to create a pull request: refs/for// +// or refs/for/ -o topic='' +const ForPrefix = "refs/for/" + +// TODO: /refs/for-review for suggest change interface + // RefName represents a full git reference name type RefName string @@ -117,6 +123,7 @@ func (ref RefName) BranchName() string { return ref.nameWithoutPrefix(BranchPrefix) } +// ForBranchName returns the branch name part of refs like refs/for/ func (ref RefName) ForBranchName() string { return ref.nameWithoutPrefix(ForPrefix) } diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index ca751a7937c10..59580939757c1 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -14,14 +14,6 @@ import ( // BranchPrefix base dir of the branch information file store on git const BranchPrefix = "refs/heads/" -// AGit Flow - -// ForPrefix special ref to create a pull request: refs/for// -// or refs/for/ -o topic='' -const ForPrefix = "refs/for/" - -// TODO: /refs/for-review for suggest change interface - // IsReferenceExist returns true if given reference exists in the repository. func IsReferenceExist(ctx context.Context, repoPath, name string) bool { _, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath}) From 70f619cd3d4e7e14deb091f31e60f7fc2ab5757c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 26 May 2023 08:17:21 +0800 Subject: [PATCH 16/17] Fix test --- routers/private/hook_post_receive.go | 2 +- routers/private/hook_pre_receive.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index 5ec787dba659c..85016e4784419 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -132,7 +132,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } } - pullIndexStr := refFullName.ShortName() + pullIndexStr := strings.TrimPrefix(refFullName.String(), git.PullPrefix) pullIndexStr = strings.Split(pullIndexStr, "/")[0] pullIndex, _ := strconv.ParseInt(pullIndexStr, 10, 64) if pullIndex <= 0 { diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 27d55bd869269..7f37d73795a05 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -123,7 +123,7 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { case refFullName.IsTag(): preReceiveTag(ourCtx, oldCommitID, newCommitID, refFullName) case git.SupportProcReceive && refFullName.IsFor(): - preReceivePullRequest(ourCtx, oldCommitID, newCommitID, refFullName) + preReceiveFor(ourCtx, oldCommitID, newCommitID, refFullName) default: ourCtx.AssertCanWriteCode() } @@ -404,7 +404,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID string, refF } } -func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { +func preReceiveFor(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { if !ctx.AssertCreatePullRequest() { return } @@ -423,7 +423,7 @@ func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID stri return } - baseBranchName := refFullName.BranchName() + baseBranchName := refFullName.ForBranchName() baseBranchExist := false if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { From 92e4ff824d35867ca40deb50b0cc8ffd5de5e3f2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 26 May 2023 08:38:06 +0800 Subject: [PATCH 17/17] More improvements --- modules/git/ref.go | 26 ++++++++++++++------------ modules/git/ref_test.go | 16 +++++++++++----- routers/private/hook_post_receive.go | 6 ++---- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/modules/git/ref.go b/modules/git/ref.go index cca9eb3ca8b0c..d3d1320e5065c 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -15,8 +15,6 @@ const ( RemotePrefix = "refs/remotes/" // PullPrefix is the base directory of the pull information of git. PullPrefix = "refs/pull/" - - pullLen = len(PullPrefix) ) // refNamePatternInvalid is regular expression with unallowed characters in git reference name @@ -55,11 +53,6 @@ func (ref *Reference) Commit() (*Commit, error) { return ref.repo.getCommit(ref.Object) } -// ShortName returns the short name of the reference -func (ref *Reference) ShortName() string { - return RefName(ref.Name).ShortName() -} - // RefGroup returns the group type of the reference func (ref *Reference) RefGroup() string { return RefName(ref.Name).RefGroup() @@ -99,7 +92,7 @@ func (ref RefName) IsRemote() bool { } func (ref RefName) IsPull() bool { - return strings.HasPrefix(string(ref), PullPrefix) + return strings.HasPrefix(string(ref), PullPrefix) && strings.IndexByte(string(ref)[len(PullPrefix):], '/') > -1 } func (ref RefName) IsFor() bool { @@ -123,6 +116,16 @@ func (ref RefName) BranchName() string { return ref.nameWithoutPrefix(BranchPrefix) } +// PullName returns the pull request name part of refs like refs/pull//head +func (ref RefName) PullName() string { + refName := string(ref) + lastIdx := strings.LastIndexByte(refName[len(PullPrefix):], '/') + if strings.HasPrefix(refName, PullPrefix) && lastIdx > -1 { + return refName[len(PullPrefix) : lastIdx+len(PullPrefix)] + } + return "" +} + // ForBranchName returns the branch name part of refs like refs/for/ func (ref RefName) ForBranchName() string { return ref.nameWithoutPrefix(ForPrefix) @@ -144,8 +147,8 @@ func (ref RefName) ShortName() string { if ref.IsRemote() { return ref.RemoteName() } - if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { - return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen] + if ref.IsPull() { + return ref.PullName() } if ref.IsFor() { return ref.ForBranchName() @@ -156,7 +159,6 @@ func (ref RefName) ShortName() string { // RefGroup returns the group type of the reference func (ref RefName) RefGroup() string { - refName := string(ref) if ref.IsBranch() { return "heads" } @@ -166,7 +168,7 @@ func (ref RefName) RefGroup() string { if ref.IsRemote() { return "remotes" } - if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { + if ref.IsPull() { return "pull" } if ref.IsFor() { diff --git a/modules/git/ref_test.go b/modules/git/ref_test.go index f177a9f6d3032..58f679b7d6ee8 100644 --- a/modules/git/ref_test.go +++ b/modules/git/ref_test.go @@ -11,14 +11,20 @@ import ( func TestRefName(t *testing.T) { // Test branch names (with and without slash). - assert.Equal(t, "foo", RefName("refs/heads/foo").ShortName()) - assert.Equal(t, "feature/foo", RefName("refs/heads/feature/foo").ShortName()) + assert.Equal(t, "foo", RefName("refs/heads/foo").BranchName()) + assert.Equal(t, "feature/foo", RefName("refs/heads/feature/foo").BranchName()) // Test tag names (with and without slash). - assert.Equal(t, "foo", RefName("refs/tags/foo").ShortName()) - assert.Equal(t, "release/foo", RefName("refs/tags/release/foo").ShortName()) + assert.Equal(t, "foo", RefName("refs/tags/foo").TagName()) + assert.Equal(t, "release/foo", RefName("refs/tags/release/foo").TagName()) - assert.Equal(t, "main", RefName("refs/for/main").ShortName()) + // Test pull names + assert.Equal(t, "1", RefName("refs/pull/1/head").PullName()) + assert.Equal(t, "my/pull", RefName("refs/pull/my/pull/head").PullName()) + + // Test for branch names + assert.Equal(t, "main", RefName("refs/for/main").ForBranchName()) + assert.Equal(t, "my/branch", RefName("refs/for/my/branch").ForBranchName()) // Test commit hashes. assert.Equal(t, "c0ffee", RefName("c0ffee").ShortName()) diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index 85016e4784419..0c9a2a10fa6dd 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "strconv" - "strings" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -124,6 +123,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { newCommitID := opts.NewCommitIDs[i] // post update for agit pull request + // FIXME: use pr.Flow to test whether it's an Agit PR or a GH PR if git.SupportProcReceive && refFullName.IsPull() { if repo == nil { repo = loadRepository(ctx, ownerName, repoName) @@ -132,9 +132,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } } - pullIndexStr := strings.TrimPrefix(refFullName.String(), git.PullPrefix) - pullIndexStr = strings.Split(pullIndexStr, "/")[0] - pullIndex, _ := strconv.ParseInt(pullIndexStr, 10, 64) + pullIndex, _ := strconv.ParseInt(refFullName.PullName(), 10, 64) if pullIndex <= 0 { continue }