mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 02:46:04 +01:00 
			
		
		
		
	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>
This commit is contained in:
		
							
								
								
									
										18
									
								
								cmd/hook.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								cmd/hook.go
									
									
									
									
									
								
							| @@ -201,7 +201,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
|  |  | ||||||
| 	oldCommitIDs := make([]string, hookBatchSize) | 	oldCommitIDs := make([]string, hookBatchSize) | ||||||
| 	newCommitIDs := make([]string, hookBatchSize) | 	newCommitIDs := make([]string, hookBatchSize) | ||||||
| 	refFullNames := make([]string, hookBatchSize) | 	refFullNames := make([]git.RefName, hookBatchSize) | ||||||
| 	count := 0 | 	count := 0 | ||||||
| 	total := 0 | 	total := 0 | ||||||
| 	lastline := 0 | 	lastline := 0 | ||||||
| @@ -236,14 +236,14 @@ Gitea or set your environment appropriately.`, "") | |||||||
|  |  | ||||||
| 		oldCommitID := string(fields[0]) | 		oldCommitID := string(fields[0]) | ||||||
| 		newCommitID := string(fields[1]) | 		newCommitID := string(fields[1]) | ||||||
| 		refFullName := string(fields[2]) | 		refFullName := git.RefName(fields[2]) | ||||||
| 		total++ | 		total++ | ||||||
| 		lastline++ | 		lastline++ | ||||||
|  |  | ||||||
| 		// If the ref is a branch or tag, check if it's protected | 		// If the ref is a branch or tag, check if it's protected | ||||||
| 		// if supportProcReceive all ref should be checked because | 		// if supportProcReceive all ref should be checked because | ||||||
| 		// permission check was delayed | 		// 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 | 			oldCommitIDs[count] = oldCommitID | ||||||
| 			newCommitIDs[count] = newCommitID | 			newCommitIDs[count] = newCommitID | ||||||
| 			refFullNames[count] = refFullName | 			refFullNames[count] = refFullName | ||||||
| @@ -351,7 +351,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
| 	} | 	} | ||||||
| 	oldCommitIDs := make([]string, hookBatchSize) | 	oldCommitIDs := make([]string, hookBatchSize) | ||||||
| 	newCommitIDs := make([]string, hookBatchSize) | 	newCommitIDs := make([]string, hookBatchSize) | ||||||
| 	refFullNames := make([]string, hookBatchSize) | 	refFullNames := make([]git.RefName, hookBatchSize) | ||||||
| 	count := 0 | 	count := 0 | ||||||
| 	total := 0 | 	total := 0 | ||||||
| 	wasEmpty := false | 	wasEmpty := false | ||||||
| @@ -373,7 +373,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
| 		fmt.Fprintf(out, ".") | 		fmt.Fprintf(out, ".") | ||||||
| 		oldCommitIDs[count] = string(fields[0]) | 		oldCommitIDs[count] = string(fields[0]) | ||||||
| 		newCommitIDs[count] = string(fields[1]) | 		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 { | 		if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total { | ||||||
| 			masterPushed = true | 			masterPushed = true | ||||||
| 		} | 		} | ||||||
| @@ -575,7 +575,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
| 	} | 	} | ||||||
| 	hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize) | 	hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize) | ||||||
| 	hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize) | 	hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize) | ||||||
| 	hookOptions.RefFullNames = make([]string, 0, hookBatchSize) | 	hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize) | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed | 		// 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.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0]) | ||||||
| 		hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1]) | 		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) | 	hookOptions.GitPushOptions = make(map[string]string) | ||||||
| @@ -640,7 +640,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
|  |  | ||||||
| 	for _, rs := range resp.Results { | 	for _, rs := range resp.Results { | ||||||
| 		if len(rs.Err) > 0 { | 		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 { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| @@ -648,7 +648,7 @@ Gitea or set your environment appropriately.`, "") | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if rs.IsNotMatched { | 		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 { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ func (run *ActionRun) Link() string { | |||||||
| // RefLink return the url of run's ref | // RefLink return the url of run's ref | ||||||
| func (run *ActionRun) RefLink() string { | func (run *ActionRun) RefLink() string { | ||||||
| 	refName := git.RefName(run.Ref) | 	refName := git.RefName(run.Ref) | ||||||
| 	if refName.RefGroup() == "pull" { | 	if refName.IsPull() { | ||||||
| 		return run.Repo.Link() + "/pulls/" + refName.ShortName() | 		return run.Repo.Link() + "/pulls/" + refName.ShortName() | ||||||
| 	} | 	} | ||||||
| 	return git.RefURL(run.Repo.Link(), run.Ref) | 	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 | // PrettyRef return #id for pull ref or ShortName for others | ||||||
| func (run *ActionRun) PrettyRef() string { | func (run *ActionRun) PrettyRef() string { | ||||||
| 	refName := git.RefName(run.Ref) | 	refName := git.RefName(run.Ref) | ||||||
| 	if refName.RefGroup() == "pull" { | 	if refName.IsPull() { | ||||||
| 		return "#" + strings.TrimSuffix(strings.TrimPrefix(run.Ref, git.PullPrefix), "/head") | 		return "#" + strings.TrimSuffix(strings.TrimPrefix(run.Ref, git.PullPrefix), "/head") | ||||||
| 	} | 	} | ||||||
| 	return refName.ShortName() | 	return refName.ShortName() | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
|  |  | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| 	"xorm.io/xorm/schemas" | 	"xorm.io/xorm/schemas" | ||||||
| @@ -367,17 +366,7 @@ func (a *Action) GetBranch() string { | |||||||
|  |  | ||||||
| // GetRefLink returns the action's ref link. | // GetRefLink returns the action's ref link. | ||||||
| func (a *Action) GetRefLink() string { | func (a *Action) GetRefLink() string { | ||||||
| 	switch { | 	return git.RefURL(a.GetRepoLink(), a.RefName) | ||||||
| 	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)) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetTag returns the action's repository tag. | // GetTag returns the action's repository tag. | ||||||
|   | |||||||
| @@ -204,7 +204,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { | 			if !workflowpattern.Skip(patterns, []string{refName.BranchName()}, &workflowpattern.EmptyTraceWriter{}) { | ||||||
| 				matchTimes++ | 				matchTimes++ | ||||||
| 			} | 			} | ||||||
| 		case "branches-ignore": | 		case "branches-ignore": | ||||||
| @@ -216,7 +216,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { | 			if !workflowpattern.Filter(patterns, []string{refName.BranchName()}, &workflowpattern.EmptyTraceWriter{}) { | ||||||
| 				matchTimes++ | 				matchTimes++ | ||||||
| 			} | 			} | ||||||
| 		case "tags": | 		case "tags": | ||||||
| @@ -228,7 +228,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { | 			if !workflowpattern.Skip(patterns, []string{refName.TagName()}, &workflowpattern.EmptyTraceWriter{}) { | ||||||
| 				matchTimes++ | 				matchTimes++ | ||||||
| 			} | 			} | ||||||
| 		case "tags-ignore": | 		case "tags-ignore": | ||||||
| @@ -240,7 +240,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 			if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { | 			if !workflowpattern.Filter(patterns, []string{refName.TagName()}, &workflowpattern.EmptyTraceWriter{}) { | ||||||
| 				matchTimes++ | 				matchTimes++ | ||||||
| 			} | 			} | ||||||
| 		case "paths": | 		case "paths": | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ package git | |||||||
| import ( | import ( | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -13,8 +15,6 @@ const ( | |||||||
| 	RemotePrefix = "refs/remotes/" | 	RemotePrefix = "refs/remotes/" | ||||||
| 	// PullPrefix is the base directory of the pull information of git. | 	// PullPrefix is the base directory of the pull information of git. | ||||||
| 	PullPrefix = "refs/pull/" | 	PullPrefix = "refs/pull/" | ||||||
|  |  | ||||||
| 	pullLen = len(PullPrefix) |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // refNamePatternInvalid is regular expression with unallowed characters in git reference name | // 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) | 	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 | // RefGroup returns the group type of the reference | ||||||
| func (ref *Reference) RefGroup() string { | func (ref *Reference) RefGroup() string { | ||||||
| 	return RefName(ref.Name).RefGroup() | 	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 | 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 { | func (ref RefName) IsBranch() bool { | ||||||
| 	return strings.HasPrefix(string(ref), BranchPrefix) | 	return strings.HasPrefix(string(ref), BranchPrefix) | ||||||
| } | } | ||||||
| @@ -74,20 +87,71 @@ func (ref RefName) IsTag() bool { | |||||||
| 	return strings.HasPrefix(string(ref), TagPrefix) | 	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 | // ShortName returns the short name of the reference name | ||||||
| func (ref RefName) ShortName() string { | func (ref RefName) ShortName() string { | ||||||
| 	refName := string(ref) | 	refName := string(ref) | ||||||
| 	if strings.HasPrefix(refName, BranchPrefix) { | 	if ref.IsBranch() { | ||||||
| 		return strings.TrimPrefix(refName, BranchPrefix) | 		return ref.BranchName() | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, TagPrefix) { | 	if ref.IsTag() { | ||||||
| 		return strings.TrimPrefix(refName, TagPrefix) | 		return ref.TagName() | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, RemotePrefix) { | 	if ref.IsRemote() { | ||||||
| 		return strings.TrimPrefix(refName, RemotePrefix) | 		return ref.RemoteName() | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { | 	if ref.IsPull() { | ||||||
| 		return refName[pullLen : strings.IndexByte(refName[pullLen:], '/')+pullLen] | 		return ref.PullName() | ||||||
|  | 	} | ||||||
|  | 	if ref.IsFor() { | ||||||
|  | 		return ref.ForBranchName() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return refName | 	return refName | ||||||
| @@ -95,18 +159,37 @@ func (ref RefName) ShortName() string { | |||||||
|  |  | ||||||
| // RefGroup returns the group type of the reference | // RefGroup returns the group type of the reference | ||||||
| func (ref RefName) RefGroup() string { | func (ref RefName) RefGroup() string { | ||||||
| 	refName := string(ref) | 	if ref.IsBranch() { | ||||||
| 	if strings.HasPrefix(refName, BranchPrefix) { |  | ||||||
| 		return "heads" | 		return "heads" | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, TagPrefix) { | 	if ref.IsTag() { | ||||||
| 		return "tags" | 		return "tags" | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, RemotePrefix) { | 	if ref.IsRemote() { | ||||||
| 		return "remotes" | 		return "remotes" | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(refName, PullPrefix) && strings.IndexByte(refName[pullLen:], '/') > -1 { | 	if ref.IsPull() { | ||||||
| 		return "pull" | 		return "pull" | ||||||
| 	} | 	} | ||||||
|  | 	if ref.IsFor() { | ||||||
|  | 		return "for" | ||||||
|  | 	} | ||||||
| 	return "" | 	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 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								modules/git/ref_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								modules/git/ref_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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")) | ||||||
|  | } | ||||||
| @@ -14,14 +14,6 @@ import ( | |||||||
| // BranchPrefix base dir of the branch information file store on git | // BranchPrefix base dir of the branch information file store on git | ||||||
| const BranchPrefix = "refs/heads/" | 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. | // IsReferenceExist returns true if given reference exists in the repository. | ||||||
| func IsReferenceExist(ctx context.Context, repoPath, name string) bool { | func IsReferenceExist(ctx context.Context, repoPath, name string) bool { | ||||||
| 	_, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath}) | 	_, _, err := NewCommand(ctx, "show-ref", "--verify").AddDashesAndList(name).RunStdString(&RunOpts{Dir: repoPath}) | ||||||
|   | |||||||
| @@ -10,8 +10,6 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ObjectCache provides thread-safe cache operations. | // ObjectCache provides thread-safe cache operations. | ||||||
| @@ -78,48 +76,6 @@ func ConcatenateError(err error, stderr string) error { | |||||||
| 	return fmt.Errorf("%w - %s", err, stderr) | 	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 | // 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 will be returned for the result if the string is empty, but valid will be false. | ||||||
| // "true", "yes", "on" are all true, true | // "true", "yes", "on" are all true, true | ||||||
|   | |||||||
| @@ -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")) |  | ||||||
| } |  | ||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	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/json" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/notification/base" | 	"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 | 	opType := activities_model.ActionCommitRepo | ||||||
|  |  | ||||||
| 	// Check it's tag push or branch. | 	// Check it's tag push or branch. | ||||||
| 	if opts.IsTag() { | 	if opts.RefFullName.IsTag() { | ||||||
| 		opType = activities_model.ActionPushTag | 		opType = activities_model.ActionPushTag | ||||||
| 		if opts.IsDelRef() { | 		if opts.IsDelRef() { | ||||||
| 			opType = activities_model.ActionDeleteTag | 			opType = activities_model.ActionDeleteTag | ||||||
| @@ -337,16 +338,16 @@ func (a *actionNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mod | |||||||
| 		Content:   string(data), | 		Content:   string(data), | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		RefName:   opts.RefFullName, | 		RefName:   opts.RefFullName.String(), | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		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 | 	opType := activities_model.ActionCommitRepo | ||||||
| 	if refType == "tag" { | 	if refFullName.IsTag() { | ||||||
| 		// has sent same action in `NotifyPushCommits`, so skip it. | 		// has sent same action in `NotifyPushCommits`, so skip it. | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -357,15 +358,15 @@ func (a *actionNotifier) NotifyCreateRef(ctx context.Context, doer *user_model.U | |||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 		RefName:   refFullName, | 		RefName:   refFullName.String(), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		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 | 	opType := activities_model.ActionDeleteBranch | ||||||
| 	if refType == "tag" { | 	if refFullName.IsTag() { | ||||||
| 		// has sent same action in `NotifyPushCommits`, so skip it. | 		// has sent same action in `NotifyPushCommits`, so skip it. | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -376,7 +377,7 @@ func (a *actionNotifier) NotifyDeleteRef(ctx context.Context, doer *user_model.U | |||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 		RefName:   refFullName, | 		RefName:   refFullName.String(), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		log.Error("NotifyWatchers: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -396,14 +397,14 @@ func (a *actionNotifier) NotifySyncPushCommits(ctx context.Context, pusher *user | |||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 		RefName:   opts.RefFullName, | 		RefName:   opts.RefFullName.String(), | ||||||
| 		Content:   string(data), | 		Content:   string(data), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		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{ | 	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{ | ||||||
| 		ActUserID: repo.OwnerID, | 		ActUserID: repo.OwnerID, | ||||||
| 		ActUser:   repo.MustOwner(ctx), | 		ActUser:   repo.MustOwner(ctx), | ||||||
| @@ -411,13 +412,13 @@ func (a *actionNotifier) NotifySyncCreateRef(ctx context.Context, doer *user_mod | |||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 		RefName:   refFullName, | 		RefName:   refFullName.String(), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		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{ | 	if err := activities_model.NotifyWatchers(ctx, &activities_model.Action{ | ||||||
| 		ActUserID: repo.OwnerID, | 		ActUserID: repo.OwnerID, | ||||||
| 		ActUser:   repo.MustOwner(ctx), | 		ActUser:   repo.MustOwner(ctx), | ||||||
| @@ -425,7 +426,7 @@ func (a *actionNotifier) NotifySyncDeleteRef(ctx context.Context, doer *user_mod | |||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| 		RefName:   refFullName, | 		RefName:   refFullName.String(), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		log.Error("NotifyWatchers: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -444,7 +445,7 @@ func (a *actionNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.R | |||||||
| 		Repo:      rel.Repo, | 		Repo:      rel.Repo, | ||||||
| 		IsPrivate: rel.Repo.IsPrivate, | 		IsPrivate: rel.Repo.IsPrivate, | ||||||
| 		Content:   rel.Title, | 		Content:   rel.Title, | ||||||
| 		RefName:   rel.TagName, | 		RefName:   rel.TagName, // FIXME: use a full ref name? | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		log.Error("NotifyWatchers: %v", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/repository" | 	"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) | 	NotifyUpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) | ||||||
| 	NotifyDeleteRelease(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) | 	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) | 	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, refType, refFullName 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) | 	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) | 	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, refType, refFullName 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) | 	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) | 	NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) | ||||||
| 	NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) | 	NotifyPackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/repository" | 	"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 | // 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 | // 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 | // 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 | // 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 | // 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 | // NotifyRepoPendingTransfer places a place holder function | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ import ( | |||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/git" |  | ||||||
| 	code_indexer "code.gitea.io/gitea/modules/indexer/code" | 	code_indexer "code.gitea.io/gitea/modules/indexer/code" | ||||||
| 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | ||||||
| 	stats_indexer "code.gitea.io/gitea/modules/indexer/stats" | 	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) { | 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) | 		code_indexer.UpdateRepoIndexer(repo) | ||||||
| 	} | 	} | ||||||
| 	if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { | 	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) { | 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) | 		code_indexer.UpdateRepoIndexer(repo) | ||||||
| 	} | 	} | ||||||
| 	if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { | 	if err := stats_indexer.UpdateRepoIndexer(repo); err != nil { | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	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/log" | ||||||
| 	"code.gitea.io/gitea/modules/notification/action" | 	"code.gitea.io/gitea/modules/notification/action" | ||||||
| 	"code.gitea.io/gitea/modules/notification/base" | 	"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 | // 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 { | 	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 | // 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 { | 	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 | // 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 { | 	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 | // 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 { | 	for _, notifier := range notifiers { | ||||||
| 		notifier.NotifySyncDeleteRef(ctx, pusher, repo, refType, refFullName) | 		notifier.NotifySyncDeleteRef(ctx, pusher, repo, refFullName) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -44,7 +45,7 @@ func (g GitPushOptions) Bool(key string, def bool) bool { | |||||||
| type HookOptions struct { | type HookOptions struct { | ||||||
| 	OldCommitIDs                    []string | 	OldCommitIDs                    []string | ||||||
| 	NewCommitIDs                    []string | 	NewCommitIDs                    []string | ||||||
| 	RefFullNames                    []string | 	RefFullNames                    []git.RefName | ||||||
| 	UserID                          int64 | 	UserID                          int64 | ||||||
| 	UserName                        string | 	UserName                        string | ||||||
| 	GitObjectDirectory              string | 	GitObjectDirectory              string | ||||||
| @@ -89,7 +90,7 @@ type HookProcReceiveRefResult struct { | |||||||
| 	OldOID       string | 	OldOID       string | ||||||
| 	NewOID       string | 	NewOID       string | ||||||
| 	Ref          string | 	Ref          string | ||||||
| 	OriginalRef  string | 	OriginalRef  git.RefName | ||||||
| 	IsForcePush  bool | 	IsForcePush  bool | ||||||
| 	IsNotMatched bool | 	IsNotMatched bool | ||||||
| 	Err          string | 	Err          string | ||||||
|   | |||||||
| @@ -4,8 +4,6 @@ | |||||||
| package repository | package repository | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -15,7 +13,7 @@ type PushUpdateOptions struct { | |||||||
| 	PusherName   string | 	PusherName   string | ||||||
| 	RepoUserName string | 	RepoUserName string | ||||||
| 	RepoName     string | 	RepoName     string | ||||||
| 	RefFullName  string // branch, tag or other name to push | 	RefFullName  git.RefName // branch, tag or other name to push | ||||||
| 	OldCommitID  string | 	OldCommitID  string | ||||||
| 	NewCommitID  string | 	NewCommitID  string | ||||||
| } | } | ||||||
| @@ -35,59 +33,34 @@ func (opts *PushUpdateOptions) IsUpdateRef() bool { | |||||||
| 	return !opts.IsNewRef() && !opts.IsDelRef() | 	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 | // IsNewTag return true if it's a creation to a tag | ||||||
| func (opts *PushUpdateOptions) IsNewTag() bool { | 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 | // IsDelTag return true if it's a deletion to a tag | ||||||
| func (opts *PushUpdateOptions) IsDelTag() bool { | func (opts *PushUpdateOptions) IsDelTag() bool { | ||||||
| 	return opts.IsTag() && opts.IsDelRef() | 	return opts.RefFullName.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) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // IsNewBranch return true if it's the first-time push to a branch | // IsNewBranch return true if it's the first-time push to a branch | ||||||
| func (opts *PushUpdateOptions) IsNewBranch() bool { | 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 | // IsUpdateBranch return true if it's not the first push to a branch | ||||||
| func (opts *PushUpdateOptions) IsUpdateBranch() bool { | 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 | // IsDelBranch return true if it's a deletion to a branch | ||||||
| func (opts *PushUpdateOptions) IsDelBranch() bool { | 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):] |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BranchName returns simple branch name if it's an operation to branch |  | ||||||
| func (opts *PushUpdateOptions) BranchName() string { |  | ||||||
| 	return opts.RefFullName[len(git.BranchPrefix):] |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // RefName returns simple name for ref | // RefName returns simple name for ref | ||||||
| func (opts *PushUpdateOptions) RefName() string { | func (opts *PushUpdateOptions) RefName() string { | ||||||
| 	if strings.HasPrefix(opts.RefFullName, git.TagPrefix) { | 	return opts.RefFullName.ShortName() | ||||||
| 		return opts.RefFullName[len(git.TagPrefix):] |  | ||||||
| 	} else if strings.HasPrefix(opts.RefFullName, git.BranchPrefix) { |  | ||||||
| 		return opts.RefFullName[len(git.BranchPrefix):] |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // RepoFullName returns repo full name | // RepoFullName returns repo full name | ||||||
|   | |||||||
| @@ -200,7 +200,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, | |||||||
| 				mirrorModel.Interval = 0 | 				mirrorModel.Interval = 0 | ||||||
| 				mirrorModel.NextUpdateUnix = 0 | 				mirrorModel.NextUpdateUnix = 0 | ||||||
| 			} else if parsedInterval < setting.Mirror.MinInterval { | 			} 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) | 				log.Error("Interval: %s is too frequent", opts.MirrorInterval) | ||||||
| 				return repo, err | 				return repo, err | ||||||
| 			} else { | 			} else { | ||||||
| @@ -217,6 +217,15 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, | |||||||
| 		if err = UpdateRepository(ctx, repo, false); err != nil { | 		if err = UpdateRepository(ctx, repo, false); err != nil { | ||||||
| 			return nil, err | 			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 { | 	} else { | ||||||
| 		if err = UpdateRepoSize(ctx, repo); err != nil { | 		if err = UpdateRepoSize(ctx, repo); err != nil { | ||||||
| 			log.Error("Failed to update size for repository: %v", err) | 			log.Error("Failed to update size for repository: %v", err) | ||||||
|   | |||||||
| @@ -98,14 +98,8 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { | |||||||
| 		baseRef = pullPayload.PullRequest.Base.Ref | 		baseRef = pullPayload.PullRequest.Base.Ref | ||||||
| 		headRef = pullPayload.PullRequest.Head.Ref | 		headRef = pullPayload.PullRequest.Head.Ref | ||||||
| 	} | 	} | ||||||
| 	refPrefix, refName := git.SplitRefName(t.Job.Run.Ref) | 	refName := git.RefName(t.Job.Run.Ref) | ||||||
| 	refType := "" | 	refType := refName.RefGroup() | ||||||
| 	switch refPrefix { |  | ||||||
| 	case git.BranchPrefix: |  | ||||||
| 		refType = "branch" |  | ||||||
| 	case git.TagPrefix: |  | ||||||
| 		refType = "tag" |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	taskContext, _ := structpb.NewStruct(map[string]interface{}{ | 	taskContext, _ := structpb.NewStruct(map[string]interface{}{ | ||||||
| 		// standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context | 		// standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -47,7 +46,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 		// tags.  Updates to other refs (eg, refs/notes, refs/changes, | 		// tags.  Updates to other refs (eg, refs/notes, refs/changes, | ||||||
| 		// or other less-standard refs spaces are ignored since there | 		// or other less-standard refs spaces are ignored since there | ||||||
| 		// may be a very large number of them). | 		// 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 { | 			if repo == nil { | ||||||
| 				repo = loadRepository(ctx, ownerName, repoName) | 				repo = loadRepository(ctx, ownerName, repoName) | ||||||
| 				if ctx.Written() { | 				if ctx.Written() { | ||||||
| @@ -67,7 +66,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 				RepoName:     repoName, | 				RepoName:     repoName, | ||||||
| 			} | 			} | ||||||
| 			updates = append(updates, option) | 			updates = append(updates, option) | ||||||
| 			if repo.IsEmpty && option.IsBranch() && (option.BranchName() == "master" || option.BranchName() == "main") { | 			if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") { | ||||||
| 				// put the master/main branch first | 				// put the master/main branch first | ||||||
| 				copy(updates[1:], updates) | 				copy(updates[1:], updates) | ||||||
| 				updates[0] = option | 				updates[0] = option | ||||||
| @@ -79,7 +78,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 		if err := repo_service.PushUpdates(updates); err != nil { | 		if err := repo_service.PushUpdates(updates); err != nil { | ||||||
| 			log.Error("Failed to Update: %s/%s Total Updates: %d", ownerName, repoName, len(updates)) | 			log.Error("Failed to Update: %s/%s Total Updates: %d", ownerName, repoName, len(updates)) | ||||||
| 			for i, update := range 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) | 			log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err) | ||||||
|  |  | ||||||
| @@ -124,7 +123,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 		newCommitID := opts.NewCommitIDs[i] | 		newCommitID := opts.NewCommitIDs[i] | ||||||
|  |  | ||||||
| 		// post update for agit pull request | 		// post update for agit pull request | ||||||
| 		if git.SupportProcReceive && strings.HasPrefix(refFullName, git.PullPrefix) { | 		// FIXME: use pr.Flow to test whether it's an Agit PR or a GH PR | ||||||
|  | 		if git.SupportProcReceive && refFullName.IsPull() { | ||||||
| 			if repo == nil { | 			if repo == nil { | ||||||
| 				repo = loadRepository(ctx, ownerName, repoName) | 				repo = loadRepository(ctx, ownerName, repoName) | ||||||
| 				if ctx.Written() { | 				if ctx.Written() { | ||||||
| @@ -132,9 +132,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			pullIndexStr := strings.TrimPrefix(refFullName, git.PullPrefix) | 			pullIndex, _ := strconv.ParseInt(refFullName.PullName(), 10, 64) | ||||||
| 			pullIndexStr = strings.Split(pullIndexStr, "/")[0] |  | ||||||
| 			pullIndex, _ := strconv.ParseInt(pullIndexStr, 10, 64) |  | ||||||
| 			if pullIndex <= 0 { | 			if pullIndex <= 0 { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| @@ -160,10 +158,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		branch := git.RefEndName(opts.RefFullNames[i]) |  | ||||||
|  |  | ||||||
| 		// If we've pushed a branch (and not deleted it) | 		// 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 | 			// First ensure we have the repository loaded, we're allowed pulls requests and we can get the base repo | ||||||
| 			if repo == nil { | 			if repo == nil { | ||||||
| @@ -197,6 +193,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			branch := refFullName.BranchName() | ||||||
|  |  | ||||||
| 			// If our branch is the default branch of an unforked repo - there's no PR to create or refer to | 			// 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 { | 			if !repo.IsFork && branch == baseRepo.DefaultBranch { | ||||||
| 				results = append(results, private.HookPostReceiveBranchResult{}) | 				results = append(results, private.HookPostReceiveBranchResult{}) | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| @@ -119,12 +118,12 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 		refFullName := opts.RefFullNames[i] | 		refFullName := opts.RefFullNames[i] | ||||||
|  |  | ||||||
| 		switch { | 		switch { | ||||||
| 		case strings.HasPrefix(refFullName, git.BranchPrefix): | 		case refFullName.IsBranch(): | ||||||
| 			preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName) | 			preReceiveBranch(ourCtx, oldCommitID, newCommitID, refFullName) | ||||||
| 		case strings.HasPrefix(refFullName, git.TagPrefix): | 		case refFullName.IsTag(): | ||||||
| 			preReceiveTag(ourCtx, oldCommitID, newCommitID, refFullName) | 			preReceiveTag(ourCtx, oldCommitID, newCommitID, refFullName) | ||||||
| 		case git.SupportProcReceive && strings.HasPrefix(refFullName, git.PullRequestPrefix): | 		case git.SupportProcReceive && refFullName.IsFor(): | ||||||
| 			preReceivePullRequest(ourCtx, oldCommitID, newCommitID, refFullName) | 			preReceiveFor(ourCtx, oldCommitID, newCommitID, refFullName) | ||||||
| 		default: | 		default: | ||||||
| 			ourCtx.AssertCanWriteCode() | 			ourCtx.AssertCanWriteCode() | ||||||
| 		} | 		} | ||||||
| @@ -136,8 +135,8 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) { | |||||||
| 	ctx.PlainText(http.StatusOK, "ok") | 	ctx.PlainText(http.StatusOK, "ok") | ||||||
| } | } | ||||||
|  |  | ||||||
| func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { | func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { | ||||||
| 	branchName := strings.TrimPrefix(refFullName, git.BranchPrefix) | 	branchName := refFullName.BranchName() | ||||||
| 	ctx.branchName = branchName | 	ctx.branchName = branchName | ||||||
|  |  | ||||||
| 	if !ctx.AssertCanWriteCode() { | 	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() { | 	if !ctx.AssertCanWriteCode() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tagName := strings.TrimPrefix(refFullName, git.TagPrefix) | 	tagName := refFullName.TagName() | ||||||
|  |  | ||||||
| 	if !ctx.gotProtectedTags { | 	if !ctx.gotProtectedTags { | ||||||
| 		var err error | 		var err error | ||||||
| @@ -405,7 +404,7 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID, refFullName string) { | func preReceiveFor(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { | ||||||
| 	if !ctx.AssertCreatePullRequest() { | 	if !ctx.AssertCreatePullRequest() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -424,7 +423,7 @@ func preReceivePullRequest(ctx *preReceiveContext, oldCommitID, newCommitID, ref | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	baseBranchName := refFullName[len(git.PullRequestPrefix):] | 	baseBranchName := refFullName.ForBranchName() | ||||||
|  |  | ||||||
| 	baseBranchExist := false | 	baseBranchExist := false | ||||||
| 	if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { | 	if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { | ||||||
|   | |||||||
| @@ -146,7 +146,7 @@ func RestoreBranchPost(ctx *context.Context) { | |||||||
| 	// Don't return error below this | 	// Don't return error below this | ||||||
| 	if err := repo_service.PushUpdate( | 	if err := repo_service.PushUpdate( | ||||||
| 		&repo_module.PushUpdateOptions{ | 		&repo_module.PushUpdateOptions{ | ||||||
| 			RefFullName:  git.BranchPrefix + deletedBranch.Name, | 			RefFullName:  git.RefNameFromBranch(deletedBranch.Name), | ||||||
| 			OldCommitID:  git.EmptySHA, | 			OldCommitID:  git.EmptySHA, | ||||||
| 			NewCommitID:  deletedBranch.Commit, | 			NewCommitID:  deletedBranch.Commit, | ||||||
| 			PusherID:     ctx.Doer.ID, | 			PusherID:     ctx.Doer.ID, | ||||||
|   | |||||||
| @@ -863,7 +863,7 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles | |||||||
| 		ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0 | 		ctx.Data["HasSelectedLabel"] = len(labelIDs) > 0 | ||||||
| 		ctx.Data["label_ids"] = strings.Join(labelIDs, ",") | 		ctx.Data["label_ids"] = strings.Join(labelIDs, ",") | ||||||
| 		ctx.Data["Reference"] = template.Ref | 		ctx.Data["Reference"] = template.Ref | ||||||
| 		ctx.Data["RefEndName"] = git.RefEndName(template.Ref) | 		ctx.Data["RefEndName"] = git.RefName(template.Ref).ShortName() | ||||||
| 		return templateErrs | 		return templateErrs | ||||||
| 	} | 	} | ||||||
| 	return templateErrs | 	return templateErrs | ||||||
| @@ -1883,7 +1883,7 @@ func ViewIssue(ctx *context.Context) { | |||||||
| 	ctx.Data["HasProjectsWritePermission"] = ctx.Repo.CanWrite(unit.TypeProjects) | 	ctx.Data["HasProjectsWritePermission"] = ctx.Repo.CanWrite(unit.TypeProjects) | ||||||
| 	ctx.Data["IsRepoAdmin"] = ctx.IsSigned && (ctx.Repo.IsAdmin() || ctx.Doer.IsAdmin) | 	ctx.Data["IsRepoAdmin"] = ctx.IsSigned && (ctx.Repo.IsAdmin() || ctx.Doer.IsAdmin) | ||||||
| 	ctx.Data["LockReasons"] = setting.Repository.Issue.LockReasons | 	ctx.Data["LockReasons"] = setting.Repository.Issue.LockReasons | ||||||
| 	ctx.Data["RefEndName"] = git.RefEndName(issue.Ref) | 	ctx.Data["RefEndName"] = git.RefName(issue.Ref).ShortName() | ||||||
| 	ctx.Data["NewPinAllowed"] = pinAllowed | 	ctx.Data["NewPinAllowed"] = pinAllowed | ||||||
| 	ctx.Data["PinEnabled"] = setting.Repository.Issue.MaxPinned != 0 | 	ctx.Data["PinEnabled"] = setting.Repository.Issue.MaxPinned != 0 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -351,9 +351,9 @@ func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newNotifyInput(repo, pusher, webhook_module.HookEventPush). | 	newNotifyInput(repo, pusher, webhook_module.HookEventPush). | ||||||
| 		WithRef(opts.RefFullName). | 		WithRef(opts.RefFullName.String()). | ||||||
| 		WithPayload(&api.PushPayload{ | 		WithPayload(&api.PushPayload{ | ||||||
| 			Ref:        opts.RefFullName, | 			Ref:        opts.RefFullName.String(), | ||||||
| 			Before:     opts.OldCommitID, | 			Before:     opts.OldCommitID, | ||||||
| 			After:      opts.NewCommitID, | 			After:      opts.NewCommitID, | ||||||
| 			CompareURL: setting.AppURL + commits.CompareURL, | 			CompareURL: setting.AppURL + commits.CompareURL, | ||||||
| @@ -366,37 +366,35 @@ func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo | |||||||
| 		Notify(ctx) | 		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") | 	ctx = withMethod(ctx, "NotifyCreateRef") | ||||||
|  |  | ||||||
| 	apiPusher := convert.ToUser(ctx, pusher, nil) | 	apiPusher := convert.ToUser(ctx, pusher, nil) | ||||||
| 	apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) | 	apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) | ||||||
| 	refName := git.RefEndName(refFullName) |  | ||||||
|  |  | ||||||
| 	newNotifyInput(repo, pusher, webhook_module.HookEventCreate). | 	newNotifyInput(repo, pusher, webhook_module.HookEventCreate). | ||||||
| 		WithRef(refName). | 		WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name | ||||||
| 		WithPayload(&api.CreatePayload{ | 		WithPayload(&api.CreatePayload{ | ||||||
| 			Ref:     refName, | 			Ref:     refFullName.ShortName(), | ||||||
| 			Sha:     refID, | 			Sha:     refID, | ||||||
| 			RefType: refType, | 			RefType: refFullName.RefGroup(), | ||||||
| 			Repo:    apiRepo, | 			Repo:    apiRepo, | ||||||
| 			Sender:  apiPusher, | 			Sender:  apiPusher, | ||||||
| 		}). | 		}). | ||||||
| 		Notify(ctx) | 		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") | 	ctx = withMethod(ctx, "NotifyDeleteRef") | ||||||
|  |  | ||||||
| 	apiPusher := convert.ToUser(ctx, pusher, nil) | 	apiPusher := convert.ToUser(ctx, pusher, nil) | ||||||
| 	apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) | 	apiRepo := convert.ToRepo(ctx, repo, perm_model.AccessModeNone) | ||||||
| 	refName := git.RefEndName(refFullName) |  | ||||||
|  |  | ||||||
| 	newNotifyInput(repo, pusher, webhook_module.HookEventDelete). | 	newNotifyInput(repo, pusher, webhook_module.HookEventDelete). | ||||||
| 		WithRef(refName). | 		WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name | ||||||
| 		WithPayload(&api.DeletePayload{ | 		WithPayload(&api.DeletePayload{ | ||||||
| 			Ref:        refName, | 			Ref:        refFullName.ShortName(), | ||||||
| 			RefType:    refType, | 			RefType:    refFullName.RefGroup(), | ||||||
| 			PusherType: api.PusherTypeUser, | 			PusherType: api.PusherTypeUser, | ||||||
| 			Repo:       apiRepo, | 			Repo:       apiRepo, | ||||||
| 			Sender:     apiPusher, | 			Sender:     apiPusher, | ||||||
| @@ -415,9 +413,9 @@ func (n *actionsNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newNotifyInput(repo, pusher, webhook_module.HookEventPush). | 	newNotifyInput(repo, pusher, webhook_module.HookEventPush). | ||||||
| 		WithRef(opts.RefFullName). | 		WithRef(opts.RefFullName.String()). | ||||||
| 		WithPayload(&api.PushPayload{ | 		WithPayload(&api.PushPayload{ | ||||||
| 			Ref:          opts.RefFullName, | 			Ref:          opts.RefFullName.String(), | ||||||
| 			Before:       opts.OldCommitID, | 			Before:       opts.OldCommitID, | ||||||
| 			After:        opts.NewCommitID, | 			After:        opts.NewCommitID, | ||||||
| 			CompareURL:   setting.AppURL + commits.CompareURL, | 			CompareURL:   setting.AppURL + commits.CompareURL, | ||||||
| @@ -431,14 +429,14 @@ func (n *actionsNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use | |||||||
| 		Notify(ctx) | 		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") | 	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") | 	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) { | func (n *actionsNotifier) NotifyNewRelease(ctx context.Context, rel *repo_model.Release) { | ||||||
|   | |||||||
| @@ -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) | 	mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo) | ||||||
|  |  | ||||||
| 	newNotifyInput(rel.Repo, doer, webhook_module.HookEventRelease). | 	newNotifyInput(rel.Repo, doer, webhook_module.HookEventRelease). | ||||||
| 		WithRef(git.TagPrefix + rel.TagName). | 		WithRef(git.RefNameFromTag(rel.TagName).String()). | ||||||
| 		WithPayload(&api.ReleasePayload{ | 		WithPayload(&api.ReleasePayload{ | ||||||
| 			Action:     action, | 			Action:     action, | ||||||
| 			Release:    convert.ToRelease(ctx, rel), | 			Release:    convert.ToRelease(ctx, rel), | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !strings.HasPrefix(opts.RefFullNames[i], git.PullRequestPrefix) { | 		if !opts.RefFullNames[i].IsFor() { | ||||||
| 			results = append(results, private.HookProcReceiveRefResult{ | 			results = append(results, private.HookProcReceiveRefResult{ | ||||||
| 				IsNotMatched: true, | 				IsNotMatched: true, | ||||||
| 				OriginalRef:  opts.RefFullNames[i], | 				OriginalRef:  opts.RefFullNames[i], | ||||||
| @@ -56,7 +56,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		baseBranchName := opts.RefFullNames[i][len(git.PullRequestPrefix):] | 		baseBranchName := opts.RefFullNames[i].ForBranchName() | ||||||
| 		curentTopicBranch := "" | 		curentTopicBranch := "" | ||||||
| 		if !gitRepo.IsBranchExist(baseBranchName) { | 		if !gitRepo.IsBranchExist(baseBranchName) { | ||||||
| 			// try match refs/for/<target-branch>/<topic-branch> | 			// try match refs/for/<target-branch>/<topic-branch> | ||||||
|   | |||||||
| @@ -206,7 +206,7 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i | |||||||
| 	issueRefURLs := make(map[int64]string, len(issues)) | 	issueRefURLs := make(map[int64]string, len(issues)) | ||||||
| 	for _, issue := range issues { | 	for _, issue := range issues { | ||||||
| 		if issue.Ref != "" { | 		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) | 			issueRefURLs[issue.ID] = git.RefURL(repoLink, issue.Ref) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -78,13 +78,23 @@ 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 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. | // If the newCommitID is "0000000", it means the reference is deleted, the value of oldCommitID is empty. | ||||||
| type mirrorSyncResult struct { | type mirrorSyncResult struct { | ||||||
| 	refName     string | 	refName     git.RefName | ||||||
| 	oldCommitID string | 	oldCommitID string | ||||||
| 	newCommitID string | 	newCommitID string | ||||||
| } | } | ||||||
|  |  | ||||||
| // parseRemoteUpdateOutput detects create, update and delete operations of references from upstream. | // 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 // 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) | 	results := make([]*mirrorSyncResult, 0, 3) | ||||||
| 	lines := strings.Split(output, "\n") | 	lines := strings.Split(output, "\n") | ||||||
| 	for i := range lines { | 	for i := range lines { | ||||||
| @@ -94,22 +104,30 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		refName := lines[i][idx+3:] | 		refName := strings.TrimSpace(lines[i][idx+3:]) | ||||||
|  |  | ||||||
| 		switch { | 		switch { | ||||||
| 		case strings.HasPrefix(lines[i], " * "): // New reference | 		case strings.HasPrefix(lines[i], " * [new tag]"): // new tag | ||||||
| 			if strings.HasPrefix(lines[i], " * [new tag]") { |  | ||||||
| 				refName = git.TagPrefix + refName |  | ||||||
| 			} else if strings.HasPrefix(lines[i], " * [new branch]") { |  | ||||||
| 				refName = git.BranchPrefix + refName |  | ||||||
| 			} |  | ||||||
| 			results = append(results, &mirrorSyncResult{ | 			results = append(results, &mirrorSyncResult{ | ||||||
| 				refName:     refName, | 				refName:     git.RefNameFromTag(refName), | ||||||
|  | 				oldCommitID: gitShortEmptySha, | ||||||
|  | 			}) | ||||||
|  | 		case strings.HasPrefix(lines[i], " * [new branch]"): // new branch | ||||||
|  | 			refName = strings.TrimPrefix(refName, remoteName+"/") | ||||||
|  | 			results = append(results, &mirrorSyncResult{ | ||||||
|  | 				refName:     git.RefNameFromBranch(refName), | ||||||
| 				oldCommitID: gitShortEmptySha, | 				oldCommitID: gitShortEmptySha, | ||||||
| 			}) | 			}) | ||||||
| 		case strings.HasPrefix(lines[i], " - "): // Delete reference | 		case strings.HasPrefix(lines[i], " - "): // Delete reference | ||||||
|  | 			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{ | 			results = append(results, &mirrorSyncResult{ | ||||||
| 				refName:     refName, | 				refName:     refFullName, | ||||||
| 				newCommitID: gitShortEmptySha, | 				newCommitID: gitShortEmptySha, | ||||||
| 			}) | 			}) | ||||||
| 		case strings.HasPrefix(lines[i], " + "): // Force update | 		case strings.HasPrefix(lines[i], " + "): // Force update | ||||||
| @@ -127,7 +145,7 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { | |||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			results = append(results, &mirrorSyncResult{ | 			results = append(results, &mirrorSyncResult{ | ||||||
| 				refName:     refName, | 				refName:     git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")), | ||||||
| 				oldCommitID: shas[0], | 				oldCommitID: shas[0], | ||||||
| 				newCommitID: shas[1], | 				newCommitID: shas[1], | ||||||
| 			}) | 			}) | ||||||
| @@ -143,7 +161,7 @@ func parseRemoteUpdateOutput(output string) []*mirrorSyncResult { | |||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			results = append(results, &mirrorSyncResult{ | 			results = append(results, &mirrorSyncResult{ | ||||||
| 				refName:     refName, | 				refName:     git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")), | ||||||
| 				oldCommitID: shas[0], | 				oldCommitID: shas[0], | ||||||
| 				newCommitID: shas[1], | 				newCommitID: shas[1], | ||||||
| 			}) | 			}) | ||||||
| @@ -204,11 +222,12 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
|  |  | ||||||
| 	log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) | 	log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo) | ||||||
|  |  | ||||||
| 	cmd := git.NewCommand(ctx, "remote", "update") | 	// use fetch but not remote update because git fetch support --tags but remote update doesn't | ||||||
|  | 	cmd := git.NewCommand(ctx, "fetch") | ||||||
| 	if m.EnablePrune { | 	if m.EnablePrune { | ||||||
| 		cmd.AddArguments("--prune") | 		cmd.AddArguments("--prune") | ||||||
| 	} | 	} | ||||||
| 	cmd.AddDynamicArguments(m.GetRemoteName()) | 	cmd.AddArguments("--tags").AddDynamicArguments(m.GetRemoteName()) | ||||||
|  |  | ||||||
| 	remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName()) | 	remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName()) | ||||||
| 	if remoteErr != nil { | 	if remoteErr != nil { | ||||||
| @@ -384,7 +403,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.UpdatedUnix = timeutil.TimeStampNow() | 	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. | // SyncPullMirror starts the sync of the pull mirror and schedules the next run. | ||||||
| @@ -444,20 +463,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { | |||||||
|  |  | ||||||
| 	for _, result := range results { | 	for _, result := range results { | ||||||
| 		// Discard GitHub pull requests, i.e. refs/pull/* | 		// Discard GitHub pull requests, i.e. refs/pull/* | ||||||
| 		if strings.HasPrefix(result.refName, git.PullPrefix) { | 		if result.refName.IsPull() { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		tp, _ := git.SplitRefName(result.refName) |  | ||||||
|  |  | ||||||
| 		// Create reference | 		// Create reference | ||||||
| 		if result.oldCommitID == gitShortEmptySha { | 		if result.oldCommitID == gitShortEmptySha { | ||||||
| 			if tp == git.TagPrefix { | 			commitID, err := gitRepo.GetRefCommitID(result.refName.String()) | ||||||
| 				tp = "tag" |  | ||||||
| 			} else if tp == git.BranchPrefix { |  | ||||||
| 				tp = "branch" |  | ||||||
| 			} |  | ||||||
| 			commitID, err := gitRepo.GetRefCommitID(result.refName) |  | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err) | 				log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err) | ||||||
| 				continue | 				continue | ||||||
| @@ -467,13 +479,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { | |||||||
| 				OldCommitID: git.EmptySHA, | 				OldCommitID: git.EmptySHA, | ||||||
| 				NewCommitID: commitID, | 				NewCommitID: commitID, | ||||||
| 			}, repo_module.NewPushCommits()) | 			}, 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 | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Delete reference | 		// Delete reference | ||||||
| 		if result.newCommitID == gitShortEmptySha { | 		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 | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -547,13 +559,11 @@ func checkAndUpdateEmptyRepository(m *repo_model.Mirror, gitRepo *git.Repository | |||||||
| 	} | 	} | ||||||
| 	firstName := "" | 	firstName := "" | ||||||
| 	for _, result := range results { | 	for _, result := range results { | ||||||
| 		if strings.HasPrefix(result.refName, git.PullPrefix) { | 		if !result.refName.IsBranch() { | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		tp, name := git.SplitRefName(result.refName) |  | ||||||
| 		if len(tp) > 0 && tp != git.BranchPrefix { |  | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		name := result.refName.BranchName() | ||||||
| 		if len(firstName) == 0 { | 		if len(firstName) == 0 { | ||||||
| 			firstName = name | 			firstName = name | ||||||
| 		} | 		} | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								services/mirror/mirror_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								services/mirror/mirror_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | // 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/test1 | ||||||
|  |  - [deleted]         (none)     -> tag1 | ||||||
|  |  + f895a1e...957a993 test2      -> origin/test2  (forced update) | ||||||
|  |    957a993..a87ba5f  test3      -> origin/test3 | ||||||
|  | ` | ||||||
|  | 	results := parseRemoteUpdateOutput(output, "origin") | ||||||
|  | 	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) | ||||||
|  |  | ||||||
|  | 	assert.EqualValues(t, "refs/heads/master", results[1].refName.String()) | ||||||
|  | 	assert.EqualValues(t, gitShortEmptySha, results[1].oldCommitID) | ||||||
|  | 	assert.EqualValues(t, "", results[1].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/tags/tag1", results[3].refName.String()) | ||||||
|  | 	assert.EqualValues(t, "", results[3].oldCommitID) | ||||||
|  | 	assert.EqualValues(t, gitShortEmptySha, results[3].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) | ||||||
|  | } | ||||||
| @@ -80,14 +80,15 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel | |||||||
| 			commits.HeadCommit = repository.CommitToPushCommit(commit) | 			commits.HeadCommit = repository.CommitToPushCommit(commit) | ||||||
| 			commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String()) | 			commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String()) | ||||||
|  |  | ||||||
|  | 			refFullName := git.RefNameFromTag(rel.TagName) | ||||||
| 			notification.NotifyPushCommits( | 			notification.NotifyPushCommits( | ||||||
| 				ctx, rel.Publisher, rel.Repo, | 				ctx, rel.Publisher, rel.Repo, | ||||||
| 				&repository.PushUpdateOptions{ | 				&repository.PushUpdateOptions{ | ||||||
| 					RefFullName: git.TagPrefix + rel.TagName, | 					RefFullName: refFullName, | ||||||
| 					OldCommitID: git.EmptySHA, | 					OldCommitID: git.EmptySHA, | ||||||
| 					NewCommitID: commit.ID.String(), | 					NewCommitID: commit.ID.String(), | ||||||
| 				}, commits) | 				}, 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() | 			rel.CreatedUnix = timeutil.TimeStampNow() | ||||||
| 		} | 		} | ||||||
| 		commit, err := gitRepo.GetTagCommit(rel.TagName) | 		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) | 			return fmt.Errorf("git tag -d: %w", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		refName := git.RefNameFromTag(rel.TagName) | ||||||
| 		notification.NotifyPushCommits( | 		notification.NotifyPushCommits( | ||||||
| 			ctx, doer, repo, | 			ctx, doer, repo, | ||||||
| 			&repository.PushUpdateOptions{ | 			&repository.PushUpdateOptions{ | ||||||
| 				RefFullName: git.TagPrefix + rel.TagName, | 				RefFullName: refName, | ||||||
| 				OldCommitID: rel.Sha1, | 				OldCommitID: rel.Sha1, | ||||||
| 				NewCommitID: git.EmptySHA, | 				NewCommitID: git.EmptySHA, | ||||||
| 			}, repository.NewPushCommits()) | 			}, 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 { | 		if err := repo_model.DeleteReleaseByID(ctx, id); err != nil { | ||||||
| 			return fmt.Errorf("DeleteReleaseByID: %w", err) | 			return fmt.Errorf("DeleteReleaseByID: %w", err) | ||||||
|   | |||||||
| @@ -139,13 +139,14 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m | |||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	refID, err := gitRepo.GetRefCommitID(git.BranchPrefix + to) | 	refNameTo := git.RefNameFromBranch(to) | ||||||
|  | 	refID, err := gitRepo.GetRefCommitID(refNameTo.String()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	notification.NotifyDeleteRef(ctx, doer, repo, "branch", git.BranchPrefix+from) | 	notification.NotifyDeleteRef(ctx, doer, repo, git.RefNameFromBranch(from)) | ||||||
| 	notification.NotifyCreateRef(ctx, doer, repo, "branch", git.BranchPrefix+to, refID) | 	notification.NotifyCreateRef(ctx, doer, repo, refNameTo, refID) | ||||||
|  |  | ||||||
| 	return "", nil | 	return "", nil | ||||||
| } | } | ||||||
| @@ -187,7 +188,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R | |||||||
| 	// Don't return error below this | 	// Don't return error below this | ||||||
| 	if err := PushUpdate( | 	if err := PushUpdate( | ||||||
| 		&repo_module.PushUpdateOptions{ | 		&repo_module.PushUpdateOptions{ | ||||||
| 			RefFullName:  git.BranchPrefix + branchName, | 			RefFullName:  git.RefNameFromBranch(branchName), | ||||||
| 			OldCommitID:  commit.ID.String(), | 			OldCommitID:  commit.ID.String(), | ||||||
| 			NewCommitID:  git.EmptySHA, | 			NewCommitID:  git.EmptySHA, | ||||||
| 			PusherID:     doer.ID, | 			PusherID:     doer.ID, | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ package repository | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/cache" | 	"code.gitea.io/gitea/modules/cache" | ||||||
| @@ -13,28 +12,19 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"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 | // 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 { | 	if !setting.CacheService.LastCommit.Enabled { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	commit, err := gitRepo.GetCommit(fullRefName) | 	commit, err := gitRepo.GetCommit(fullRefName.String()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if gitRepo.LastCommitCache == nil { | 	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 { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -107,7 +107,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 		if opts.IsNewRef() && opts.IsDelRef() { | 		if opts.IsNewRef() && opts.IsDelRef() { | ||||||
| 			return fmt.Errorf("old and new revisions are both %s", git.EmptySHA) | 			return fmt.Errorf("old and new revisions are both %s", git.EmptySHA) | ||||||
| 		} | 		} | ||||||
| 		if opts.IsTag() { // If is tag reference | 		if opts.RefFullName.IsTag() { | ||||||
| 			if pusher == nil || pusher.ID != opts.PusherID { | 			if pusher == nil || pusher.ID != opts.PusherID { | ||||||
| 				if opts.PusherID == user_model.ActionsUserID { | 				if opts.PusherID == user_model.ActionsUserID { | ||||||
| 					pusher = user_model.NewActionsUser() | 					pusher = user_model.NewActionsUser() | ||||||
| @@ -118,18 +118,18 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			tagName := opts.TagName() | 			tagName := opts.RefFullName.TagName() | ||||||
| 			if opts.IsDelRef() { | 			if opts.IsDelRef() { | ||||||
| 				notification.NotifyPushCommits( | 				notification.NotifyPushCommits( | ||||||
| 					ctx, pusher, repo, | 					ctx, pusher, repo, | ||||||
| 					&repo_module.PushUpdateOptions{ | 					&repo_module.PushUpdateOptions{ | ||||||
| 						RefFullName: git.TagPrefix + tagName, | 						RefFullName: git.RefNameFromTag(tagName), | ||||||
| 						OldCommitID: opts.OldCommitID, | 						OldCommitID: opts.OldCommitID, | ||||||
| 						NewCommitID: git.EmptySHA, | 						NewCommitID: git.EmptySHA, | ||||||
| 					}, repo_module.NewPushCommits()) | 					}, repo_module.NewPushCommits()) | ||||||
|  |  | ||||||
| 				delTags = append(delTags, tagName) | 				delTags = append(delTags, tagName) | ||||||
| 				notification.NotifyDeleteRef(ctx, pusher, repo, "tag", opts.RefFullName) | 				notification.NotifyDeleteRef(ctx, pusher, repo, opts.RefFullName) | ||||||
| 			} else { // is new tag | 			} else { // is new tag | ||||||
| 				newCommit, err := gitRepo.GetCommit(opts.NewCommitID) | 				newCommit, err := gitRepo.GetCommit(opts.NewCommitID) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| @@ -143,15 +143,15 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 				notification.NotifyPushCommits( | 				notification.NotifyPushCommits( | ||||||
| 					ctx, pusher, repo, | 					ctx, pusher, repo, | ||||||
| 					&repo_module.PushUpdateOptions{ | 					&repo_module.PushUpdateOptions{ | ||||||
| 						RefFullName: git.TagPrefix + tagName, | 						RefFullName: opts.RefFullName, | ||||||
| 						OldCommitID: git.EmptySHA, | 						OldCommitID: git.EmptySHA, | ||||||
| 						NewCommitID: opts.NewCommitID, | 						NewCommitID: opts.NewCommitID, | ||||||
| 					}, commits) | 					}, commits) | ||||||
|  |  | ||||||
| 				addTags = append(addTags, tagName) | 				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 pusher == nil || pusher.ID != opts.PusherID { | 			if pusher == nil || pusher.ID != opts.PusherID { | ||||||
| 				if opts.PusherID == user_model.ActionsUserID { | 				if opts.PusherID == user_model.ActionsUserID { | ||||||
| 					pusher = user_model.NewActionsUser() | 					pusher = user_model.NewActionsUser() | ||||||
| @@ -163,7 +163,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			branch := opts.BranchName() | 			branch := opts.RefFullName.BranchName() | ||||||
| 			if !opts.IsDelRef() { | 			if !opts.IsDelRef() { | ||||||
| 				log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name) | 				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) | 				go pull_service.AddTestPullRequestTask(pusher, repo.ID, branch, true, opts.OldCommitID, opts.NewCommitID) | ||||||
| @@ -198,7 +198,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | |||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						return fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err) | 						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 { | 				} else { | ||||||
| 					l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) | 					l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) | ||||||
| 					if err != nil { | 					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) | 					log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} 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 { | 				if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil { | ||||||
| 					// close all related pulls | 					// close all related pulls | ||||||
| 					log.Error("close related pull request failed: %v", err) | 					log.Error("close related pull request failed: %v", err) | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ func (d *DingtalkPayload) JSONPayload() ([]byte, error) { | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	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 | 	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 | // Delete implements PayloadConvertor Delete method | ||||||
| func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	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 | 	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 | // Push implements PayloadConvertor Push method | ||||||
| func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -112,7 +112,7 @@ var _ PayloadConvertor = &DiscordPayload{} | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	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 | 	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 | // Delete implements PayloadConvertor Delete method | ||||||
| func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// deleted tag/branch | 	// 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) | 	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 | 	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 | // Push implements PayloadConvertor Push method | ||||||
| func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ var _ PayloadConvertor = &FeishuPayload{} | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	text := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return newFeishuTextPayload(text), nil | 	return newFeishuTextPayload(text), nil | ||||||
| @@ -57,7 +57,7 @@ func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | |||||||
| // Delete implements PayloadConvertor Delete method | // Delete implements PayloadConvertor Delete method | ||||||
| func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	text := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return newFeishuTextPayload(text), nil | 	return newFeishuTextPayload(text), nil | ||||||
| @@ -73,7 +73,7 @@ func (f *FeishuPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { | |||||||
| // Push implements PayloadConvertor Push method | // Push implements PayloadConvertor Push method | ||||||
| func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ func MatrixLinkFormatter(url, text string) string { | |||||||
|  |  | ||||||
| // MatrixLinkToRef Matrix-formatter link to a repo ref | // MatrixLinkToRef Matrix-formatter link to a repo ref | ||||||
| func MatrixLinkToRef(repoURL, ref string) string { | func MatrixLinkToRef(repoURL, ref string) string { | ||||||
| 	refName := git.RefEndName(ref) | 	refName := git.RefName(ref).ShortName() | ||||||
| 	switch { | 	switch { | ||||||
| 	case strings.HasPrefix(ref, git.BranchPrefix): | 	case strings.HasPrefix(ref, git.BranchPrefix): | ||||||
| 		return MatrixLinkFormatter(repoURL+"/src/branch/"+util.PathEscapeSegments(refName), refName) | 		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. | // Delete composes Matrix payload for delete a branch or tag. | ||||||
| func (m *MatrixPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | 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) | 	repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName) | ||||||
| 	text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) | 	text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ var _ PayloadConvertor = &MSTeamsPayload{} | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return createMSTeamsPayload( | 	return createMSTeamsPayload( | ||||||
| @@ -87,7 +87,7 @@ func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | |||||||
| // Delete implements PayloadConvertor Delete method | // Delete implements PayloadConvertor Delete method | ||||||
| func (m *MSTeamsPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (m *MSTeamsPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// deleted tag/branch | 	// 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) | 	title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return createMSTeamsPayload( | 	return createMSTeamsPayload( | ||||||
| @@ -119,7 +119,7 @@ func (m *MSTeamsPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { | |||||||
| // Push implements PayloadConvertor Push method | // Push implements PayloadConvertor Push method | ||||||
| func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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{ | 	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ | ||||||
| 		Ref:          opts.RefFullName, | 		Ref:          opts.RefFullName.String(), | ||||||
| 		Before:       opts.OldCommitID, | 		Before:       opts.OldCommitID, | ||||||
| 		After:        opts.NewCommitID, | 		After:        opts.NewCommitID, | ||||||
| 		CompareURL:   setting.AppURL + commits.CompareURL, | 		CompareURL:   setting.AppURL + commits.CompareURL, | ||||||
| @@ -747,15 +747,15 @@ func (m *webhookNotifier) NotifyPullReviewRequest(ctx context.Context, doer *use | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| 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) | 	apiPusher := convert.ToUser(ctx, pusher, nil) | ||||||
| 	apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) | 	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{ | 	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, | 		Sha:     refID, | ||||||
| 		RefType: refType, | 		RefType: refFullName.RefGroup(), | ||||||
| 		Repo:    apiRepo, | 		Repo:    apiRepo, | ||||||
| 		Sender:  apiPusher, | 		Sender:  apiPusher, | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| @@ -784,19 +784,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) | 	apiPusher := convert.ToUser(ctx, pusher, nil) | ||||||
| 	apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) | 	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{ | 	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventDelete, &api.DeletePayload{ | ||||||
| 		Ref:        refName, | 		Ref:        refName, // FIXME: should it be a full ref name? | ||||||
| 		RefType:    refType, | 		RefType:    refFullName.RefGroup(), | ||||||
| 		PusherType: api.PusherTypeUser, | 		PusherType: api.PusherTypeUser, | ||||||
| 		Repo:       apiRepo, | 		Repo:       apiRepo, | ||||||
| 		Sender:     apiPusher, | 		Sender:     apiPusher, | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		log.Error("PrepareWebhooks.(delete %s): %v", refType, err) | 		log.Error("PrepareWebhooks.(delete %s): %v", refFullName.RefGroup(), err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -838,7 +838,7 @@ func (m *webhookNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ | 	if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{ | ||||||
| 		Ref:          opts.RefFullName, | 		Ref:          opts.RefFullName.String(), | ||||||
| 		Before:       opts.OldCommitID, | 		Before:       opts.OldCommitID, | ||||||
| 		After:        opts.NewCommitID, | 		After:        opts.NewCommitID, | ||||||
| 		CompareURL:   setting.AppURL + commits.CompareURL, | 		CompareURL:   setting.AppURL + commits.CompareURL, | ||||||
| @@ -853,12 +853,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) { | 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, refType, refFullName, refID) | 	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) { | func (m *webhookNotifier) NotifySyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { | ||||||
| 	m.NotifyDeleteRef(ctx, pusher, repo, refType, refFullName) | 	m.NotifyDeleteRef(ctx, pusher, repo, refFullName) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *webhookNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { | func (m *webhookNotifier) NotifyPackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ func SlackLinkFormatter(url, text string) string { | |||||||
| // SlackLinkToRef slack-formatter link to a repo ref | // SlackLinkToRef slack-formatter link to a repo ref | ||||||
| func SlackLinkToRef(repoURL, ref string) string { | func SlackLinkToRef(repoURL, ref string) string { | ||||||
| 	url := git.RefURL(repoURL, ref) | 	url := git.RefURL(repoURL, ref) | ||||||
| 	refName := git.RefEndName(ref) | 	refName := git.RefName(ref).ShortName() | ||||||
| 	return SlackLinkFormatter(url, refName) | 	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. | // Delete composes Slack payload for delete a branch or tag. | ||||||
| func (s *SlackPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | 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) | 	repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName) | ||||||
| 	text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) | 	text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ func (t *TelegramPayload) JSONPayload() ([]byte, error) { | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// created tag/branch | ||||||
| 	refName := git.RefEndName(p.Ref) | 	refName := git.RefName(p.Ref).ShortName() | ||||||
| 	title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> created`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, | 	title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> created`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, | ||||||
| 		p.Repo.HTMLURL+"/src/"+refName, refName) | 		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 | // Delete implements PayloadConvertor Delete method | ||||||
| func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// created tag/branch | ||||||
| 	refName := git.RefEndName(p.Ref) | 	refName := git.RefName(p.Ref).ShortName() | ||||||
| 	title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> deleted`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, | 	title := fmt.Sprintf(`[<a href="%s">%s</a>] %s <a href="%s">%s</a> deleted`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType, | ||||||
| 		p.Repo.HTMLURL+"/src/"+refName, refName) | 		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 | // Push implements PayloadConvertor Push method | ||||||
| func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -56,7 +56,7 @@ var _ PayloadConvertor = &WechatworkPayload{} | |||||||
| // Create implements PayloadConvertor Create method | // Create implements PayloadConvertor Create method | ||||||
| func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return newWechatworkMarkdownPayload(title), nil | 	return newWechatworkMarkdownPayload(title), nil | ||||||
| @@ -65,7 +65,7 @@ func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) | |||||||
| // Delete implements PayloadConvertor Delete method | // Delete implements PayloadConvertor Delete method | ||||||
| func (f *WechatworkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | func (f *WechatworkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { | ||||||
| 	// created tag/branch | 	// 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) | 	title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) | ||||||
|  |  | ||||||
| 	return newWechatworkMarkdownPayload(title), nil | 	return newWechatworkMarkdownPayload(title), nil | ||||||
| @@ -81,7 +81,7 @@ func (f *WechatworkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { | |||||||
| // Push implements PayloadConvertor Push method | // Push implements PayloadConvertor Push method | ||||||
| func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) { | func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		branchName = git.RefEndName(p.Ref) | 		branchName = git.RefName(p.Ref).ShortName() | ||||||
| 		commitDesc string | 		commitDesc string | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user