diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2023-05-26 09:04:48 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-26 01:04:48 +0000 |
commit | f9cfd6ce5bd7f27e2655fd307022461a802fc49c (patch) | |
tree | 9279cab7249c1c7e66a81e694f1096e709c1a8a1 /modules | |
parent | 26fa94bc25ecba731a12af16b6172768389287a7 (diff) | |
download | gitea-f9cfd6ce5bd7f27e2655fd307022461a802fc49c.tar.gz gitea-f9cfd6ce5bd7f27e2655fd307022461a802fc49c.zip |
Use the type RefName for all the needed places and fix pull mirror sync bugs (#24634)
This PR replaces all string refName as a type `git.RefName` to make the
code more maintainable.
Fix #15367
Replaces #23070
It also fixed a bug that tags are not sync because `git remote --prune
origin` will not remove local tags if remote removed.
We in fact should use `git fetch --prune --tags origin` but not `git
remote update origin` to do the sync.
Some answer from ChatGPT as ref.
> If the git fetch --prune --tags command is not working as expected,
there could be a few reasons why. Here are a few things to check:
>
>Make sure that you have the latest version of Git installed on your
system. You can check the version by running git --version in your
terminal. If you have an outdated version, try updating Git and see if
that resolves the issue.
>
>Check that your Git repository is properly configured to track the
remote repository's tags. You can check this by running git config
--get-all remote.origin.fetch and verifying that it includes
+refs/tags/*:refs/tags/*. If it does not, you can add it by running git
config --add remote.origin.fetch "+refs/tags/*:refs/tags/*".
>
>Verify that the tags you are trying to prune actually exist on the
remote repository. You can do this by running git ls-remote --tags
origin to list all the tags on the remote repository.
>
>Check if any local tags have been created that match the names of tags
on the remote repository. If so, these local tags may be preventing the
git fetch --prune --tags command from working properly. You can delete
local tags using the git tag -d command.
---------
Co-authored-by: delvh <dev.lh@web.de>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/actions/workflows.go | 8 | ||||
-rw-r--r-- | modules/git/ref.go | 125 | ||||
-rw-r--r-- | modules/git/ref_test.go | 38 | ||||
-rw-r--r-- | modules/git/repo_branch.go | 8 | ||||
-rw-r--r-- | modules/git/utils.go | 44 | ||||
-rw-r--r-- | modules/git/utils_test.go | 30 | ||||
-rw-r--r-- | modules/notification/action/action.go | 29 | ||||
-rw-r--r-- | modules/notification/base/notifier.go | 9 | ||||
-rw-r--r-- | modules/notification/base/null.go | 9 | ||||
-rw-r--r-- | modules/notification/indexer/indexer.go | 13 | ||||
-rw-r--r-- | modules/notification/notification.go | 17 | ||||
-rw-r--r-- | modules/private/hook.go | 5 | ||||
-rw-r--r-- | modules/repository/push.go | 41 | ||||
-rw-r--r-- | modules/repository/repo.go | 11 |
14 files changed, 210 insertions, 177 deletions
diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index d560b7718f..d9459288b1 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 47cc04b7fb..d3d1320e50 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 ( @@ -13,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 @@ -53,19 +53,32 @@ 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() } -// RefName represents a git reference name +// ForPrefix special ref to create a pull request: refs/for/<target-branch>/<topic-branch> +// or refs/for/<targe-branch> -o topic='<topic-branch>' +const ForPrefix = "refs/for/" + +// TODO: /refs/for-review for suggest change interface + +// 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) String() string { + return string(ref) +} + func (ref RefName) IsBranch() bool { return strings.HasPrefix(string(ref), BranchPrefix) } @@ -74,20 +87,71 @@ 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) && strings.IndexByte(string(ref)[len(PullPrefix):], '/') > -1 +} + +func (ref RefName) IsFor() bool { + return strings.HasPrefix(string(ref), ForPrefix) +} + +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 { + return ref.nameWithoutPrefix(BranchPrefix) +} + +// PullName returns the pull request name part of refs like refs/pull/<pull_name>/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/<branch_name> +func (ref RefName) ForBranchName() string { + 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 ref.IsTag() { + return ref.TagName() } - if strings.HasPrefix(refName, TagPrefix) { - return strings.TrimPrefix(refName, TagPrefix) + if ref.IsRemote() { + return ref.RemoteName() } - if strings.HasPrefix(refName, RemotePrefix) { - return strings.TrimPrefix(refName, RemotePrefix) + if ref.IsPull() { + return ref.PullName() } - if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { - return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen] + if ref.IsFor() { + return ref.ForBranchName() } return refName @@ -95,18 +159,37 @@ 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 { + if ref.IsPull() { return "pull" } + if ref.IsFor() { + return "for" + } return "" } + +// RefURL returns the absolute URL for a ref in a repository +func RefURL(repoURL, ref string) string { + refFullName := RefName(ref) + refName := util.PathEscapeSegments(refFullName.ShortName()) + switch { + case refFullName.IsBranch(): + return repoURL + "/src/branch/" + refName + case refFullName.IsTag(): + 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/ref_test.go b/modules/git/ref_test.go new file mode 100644 index 0000000000..58f679b7d6 --- /dev/null +++ b/modules/git/ref_test.go @@ -0,0 +1,38 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRefName(t *testing.T) { + // Test branch names (with and without slash). + 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").TagName()) + assert.Equal(t, "release/foo", RefName("refs/tags/release/foo").TagName()) + + // 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()) +} + +func TestRefURL(t *testing.T) { + repoURL := "/user/repo" + assert.Equal(t, repoURL+"/src/branch/foo", RefURL(repoURL, "refs/heads/foo")) + assert.Equal(t, repoURL+"/src/tag/foo", RefURL(repoURL, "refs/tags/foo")) + assert.Equal(t, repoURL+"/src/commit/c0ffee", RefURL(repoURL, "c0ffee")) +} diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 3bb6ef5223..5958093975 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 - -// PullRequestPrefix special ref to create a pull request: refs/for/<targe-branch>/<topic-branch> -// or refs/for/<targe-branch> -o topic='<topic-branch>' -const PullRequestPrefix = "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}) diff --git a/modules/git/utils.go b/modules/git/utils.go index 628faf509f..b44363820d 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/git/utils_test.go b/modules/git/utils_test.go deleted file mode 100644 index 718db700ae..0000000000 --- a/modules/git/utils_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package git - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -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")) - - // 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")) - - // Test commit hashes. - assert.Equal(t, "c0ffee", RefEndName("c0ffee")) -} - -func TestRefURL(t *testing.T) { - repoURL := "/user/repo" - assert.Equal(t, repoURL+"/src/branch/foo", RefURL(repoURL, "refs/heads/foo")) - assert.Equal(t, repoURL+"/src/tag/foo", RefURL(repoURL, "refs/tags/foo")) - assert.Equal(t, repoURL+"/src/commit/c0ffee", RefURL(repoURL, "c0ffee")) -} diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index c043ef62d5..1d759e4923 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 4021bbe141..87eae3f414 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 161eadfbec..187c36beeb 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 c67f79d0f2..0661c2c1ab 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,11 @@ 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 !opts.RefFullName.IsBranch() { + return + } + + if setting.Indexer.RepoIndexerEnabled && opts.RefFullName.BranchName() == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { @@ -135,7 +138,11 @@ 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 !opts.RefFullName.IsBranch() { + return + } + + 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/notification/notification.go b/modules/notification/notification.go index da2a7ab3a0..72dd1c99e5 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 c0fe9ef1fb..23e03896e4 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 aa1552351d..ea03f9e153 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,34 @@ 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() -} - -// TagName returns simple tag name if it's an operation to a tag -func (opts *PushUpdateOptions) TagName() string { - return opts.RefFullName[len(git.TagPrefix):] -} - -// BranchName returns simple branch name if it's an operation to branch -func (opts *PushUpdateOptions) BranchName() string { - return opts.RefFullName[len(git.BranchPrefix):] + return opts.RefFullName.IsBranch() && opts.IsDelRef() } // 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/modules/repository/repo.go b/modules/repository/repo.go index a1dba8fc6a..62e1f31b9e 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 + 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 <remote> +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add <remote> +refs/tags/*:refs/tags/*): %w", err) + } } else { if err = UpdateRepoSize(ctx, repo); err != nil { log.Error("Failed to update size for repository: %v", err) |