summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2023-05-26 09:04:48 +0800
committerGitHub <noreply@github.com>2023-05-26 01:04:48 +0000
commitf9cfd6ce5bd7f27e2655fd307022461a802fc49c (patch)
tree9279cab7249c1c7e66a81e694f1096e709c1a8a1 /modules
parent26fa94bc25ecba731a12af16b6172768389287a7 (diff)
downloadgitea-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.go8
-rw-r--r--modules/git/ref.go125
-rw-r--r--modules/git/ref_test.go38
-rw-r--r--modules/git/repo_branch.go8
-rw-r--r--modules/git/utils.go44
-rw-r--r--modules/git/utils_test.go30
-rw-r--r--modules/notification/action/action.go29
-rw-r--r--modules/notification/base/notifier.go9
-rw-r--r--modules/notification/base/null.go9
-rw-r--r--modules/notification/indexer/indexer.go13
-rw-r--r--modules/notification/notification.go17
-rw-r--r--modules/private/hook.go5
-rw-r--r--modules/repository/push.go41
-rw-r--r--modules/repository/repo.go11
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)