mirror of
				https://github.com/go-gitea/gitea
				synced 2025-09-28 03:28:13 +00:00 
			
		
		
		
	Add migration from GitBucket (#16767)
This PR adds [GitBucket](https://gitbucket.github.io/) as migration source. Supported: - Milestones - Issues - Pull Requests - Comments - Reviews - Labels There is no public usable instance so no integration tests added.
This commit is contained in:
		| @@ -35,6 +35,8 @@ func ToGitServiceType(value string) structs.GitServiceType { | ||||
| 		return structs.GogsService | ||||
| 	case "onedev": | ||||
| 		return structs.OneDevService | ||||
| 	case "gitbucket": | ||||
| 		return structs.GitBucketService | ||||
| 	default: | ||||
| 		return structs.PlainGitService | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										72
									
								
								modules/migrations/gitbucket.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								modules/migrations/gitbucket.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // Copyright 2021 The Gitea Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package migrations | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/migrations/base" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	_ base.Downloader        = &GitBucketDownloader{} | ||||
| 	_ base.DownloaderFactory = &GitBucketDownloaderFactory{} | ||||
| ) | ||||
|  | ||||
| func init() { | ||||
| 	RegisterDownloaderFactory(&GitBucketDownloaderFactory{}) | ||||
| } | ||||
|  | ||||
| // GitBucketDownloaderFactory defines a GitBucket downloader factory | ||||
| type GitBucketDownloaderFactory struct { | ||||
| } | ||||
|  | ||||
| // New returns a Downloader related to this factory according MigrateOptions | ||||
| func (f *GitBucketDownloaderFactory) New(ctx context.Context, opts base.MigrateOptions) (base.Downloader, error) { | ||||
| 	u, err := url.Parse(opts.CloneAddr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	baseURL := u.Scheme + "://" + u.Host | ||||
| 	fields := strings.Split(u.Path, "/") | ||||
| 	oldOwner := fields[1] | ||||
| 	oldName := strings.TrimSuffix(fields[2], ".git") | ||||
|  | ||||
| 	return NewGitBucketDownloader(ctx, baseURL, opts.AuthUsername, opts.AuthPassword, opts.AuthToken, oldOwner, oldName), nil | ||||
| } | ||||
|  | ||||
| // GitServiceType returns the type of git service | ||||
| func (f *GitBucketDownloaderFactory) GitServiceType() structs.GitServiceType { | ||||
| 	return structs.GitBucketService | ||||
| } | ||||
|  | ||||
| // GitBucketDownloader implements a Downloader interface to get repository information | ||||
| // from GitBucket via GithubDownloader | ||||
| type GitBucketDownloader struct { | ||||
| 	*GithubDownloaderV3 | ||||
| } | ||||
|  | ||||
| // NewGitBucketDownloader creates a GitBucket downloader | ||||
| func NewGitBucketDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GitBucketDownloader { | ||||
| 	githubDownloader := NewGithubDownloaderV3(ctx, baseURL, userName, password, token, repoOwner, repoName) | ||||
| 	githubDownloader.SkipReactions = true | ||||
| 	return &GitBucketDownloader{ | ||||
| 		githubDownloader, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SupportGetRepoComments return true if it supports get repo comments | ||||
| func (g *GitBucketDownloader) SupportGetRepoComments() bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // GetReviews is not supported | ||||
| func (g *GitBucketDownloader) GetReviews(context base.IssueContext) ([]*base.Review, error) { | ||||
| 	return nil, &base.ErrNotSupported{Entity: "Reviews"} | ||||
| } | ||||
| @@ -68,15 +68,16 @@ func (f *GithubDownloaderV3Factory) GitServiceType() structs.GitServiceType { | ||||
| // from github via APIv3 | ||||
| type GithubDownloaderV3 struct { | ||||
| 	base.NullDownloader | ||||
| 	ctx          context.Context | ||||
| 	clients      []*github.Client | ||||
| 	repoOwner    string | ||||
| 	repoName     string | ||||
| 	userName     string | ||||
| 	password     string | ||||
| 	rates        []*github.Rate | ||||
| 	curClientIdx int | ||||
| 	maxPerPage   int | ||||
| 	ctx           context.Context | ||||
| 	clients       []*github.Client | ||||
| 	repoOwner     string | ||||
| 	repoName      string | ||||
| 	userName      string | ||||
| 	password      string | ||||
| 	rates         []*github.Rate | ||||
| 	curClientIdx  int | ||||
| 	maxPerPage    int | ||||
| 	SkipReactions bool | ||||
| } | ||||
|  | ||||
| // NewGithubDownloaderV3 creates a github Downloader via github v3 API | ||||
| @@ -428,25 +429,27 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool, | ||||
|  | ||||
| 		// get reactions | ||||
| 		var reactions []*base.Reaction | ||||
| 		for i := 1; ; i++ { | ||||
| 			g.waitAndPickClient() | ||||
| 			res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{ | ||||
| 				Page:    i, | ||||
| 				PerPage: perPage, | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				return nil, false, err | ||||
| 			} | ||||
| 			g.setRate(&resp.Rate) | ||||
| 			if len(res) == 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			for _, reaction := range res { | ||||
| 				reactions = append(reactions, &base.Reaction{ | ||||
| 					UserID:   reaction.User.GetID(), | ||||
| 					UserName: reaction.User.GetLogin(), | ||||
| 					Content:  reaction.GetContent(), | ||||
| 		if !g.SkipReactions { | ||||
| 			for i := 1; ; i++ { | ||||
| 				g.waitAndPickClient() | ||||
| 				res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{ | ||||
| 					Page:    i, | ||||
| 					PerPage: perPage, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					return nil, false, err | ||||
| 				} | ||||
| 				g.setRate(&resp.Rate) | ||||
| 				if len(res) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				for _, reaction := range res { | ||||
| 					reactions = append(reactions, &base.Reaction{ | ||||
| 						UserID:   reaction.User.GetID(), | ||||
| 						UserName: reaction.User.GetLogin(), | ||||
| 						Content:  reaction.GetContent(), | ||||
| 					}) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -516,25 +519,27 @@ func (g *GithubDownloaderV3) getComments(issueContext base.IssueContext) ([]*bas | ||||
| 		for _, comment := range comments { | ||||
| 			// get reactions | ||||
| 			var reactions []*base.Reaction | ||||
| 			for i := 1; ; i++ { | ||||
| 				g.waitAndPickClient() | ||||
| 				res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ | ||||
| 					Page:    i, | ||||
| 					PerPage: g.maxPerPage, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				g.setRate(&resp.Rate) | ||||
| 				if len(res) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				for _, reaction := range res { | ||||
| 					reactions = append(reactions, &base.Reaction{ | ||||
| 						UserID:   reaction.User.GetID(), | ||||
| 						UserName: reaction.User.GetLogin(), | ||||
| 						Content:  reaction.GetContent(), | ||||
| 			if !g.SkipReactions { | ||||
| 				for i := 1; ; i++ { | ||||
| 					g.waitAndPickClient() | ||||
| 					res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ | ||||
| 						Page:    i, | ||||
| 						PerPage: g.maxPerPage, | ||||
| 					}) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					g.setRate(&resp.Rate) | ||||
| 					if len(res) == 0 { | ||||
| 						break | ||||
| 					} | ||||
| 					for _, reaction := range res { | ||||
| 						reactions = append(reactions, &base.Reaction{ | ||||
| 							UserID:   reaction.User.GetID(), | ||||
| 							UserName: reaction.User.GetLogin(), | ||||
| 							Content:  reaction.GetContent(), | ||||
| 						}) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -588,25 +593,27 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, | ||||
| 	for _, comment := range comments { | ||||
| 		// get reactions | ||||
| 		var reactions []*base.Reaction | ||||
| 		for i := 1; ; i++ { | ||||
| 			g.waitAndPickClient() | ||||
| 			res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ | ||||
| 				Page:    i, | ||||
| 				PerPage: g.maxPerPage, | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				return nil, false, err | ||||
| 			} | ||||
| 			g.setRate(&resp.Rate) | ||||
| 			if len(res) == 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			for _, reaction := range res { | ||||
| 				reactions = append(reactions, &base.Reaction{ | ||||
| 					UserID:   reaction.User.GetID(), | ||||
| 					UserName: reaction.User.GetLogin(), | ||||
| 					Content:  reaction.GetContent(), | ||||
| 		if !g.SkipReactions { | ||||
| 			for i := 1; ; i++ { | ||||
| 				g.waitAndPickClient() | ||||
| 				res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ | ||||
| 					Page:    i, | ||||
| 					PerPage: g.maxPerPage, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					return nil, false, err | ||||
| 				} | ||||
| 				g.setRate(&resp.Rate) | ||||
| 				if len(res) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				for _, reaction := range res { | ||||
| 					reactions = append(reactions, &base.Reaction{ | ||||
| 						UserID:   reaction.User.GetID(), | ||||
| 						UserName: reaction.User.GetLogin(), | ||||
| 						Content:  reaction.GetContent(), | ||||
| 					}) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		idx := strings.LastIndex(*comment.IssueURL, "/") | ||||
| @@ -656,25 +663,27 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq | ||||
|  | ||||
| 		// get reactions | ||||
| 		var reactions []*base.Reaction | ||||
| 		for i := 1; ; i++ { | ||||
| 			g.waitAndPickClient() | ||||
| 			res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{ | ||||
| 				Page:    i, | ||||
| 				PerPage: perPage, | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				return nil, false, err | ||||
| 			} | ||||
| 			g.setRate(&resp.Rate) | ||||
| 			if len(res) == 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			for _, reaction := range res { | ||||
| 				reactions = append(reactions, &base.Reaction{ | ||||
| 					UserID:   reaction.User.GetID(), | ||||
| 					UserName: reaction.User.GetLogin(), | ||||
| 					Content:  reaction.GetContent(), | ||||
| 		if !g.SkipReactions { | ||||
| 			for i := 1; ; i++ { | ||||
| 				g.waitAndPickClient() | ||||
| 				res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{ | ||||
| 					Page:    i, | ||||
| 					PerPage: perPage, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					return nil, false, err | ||||
| 				} | ||||
| 				g.setRate(&resp.Rate) | ||||
| 				if len(res) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				for _, reaction := range res { | ||||
| 					reactions = append(reactions, &base.Reaction{ | ||||
| 						UserID:   reaction.User.GetID(), | ||||
| 						UserName: reaction.User.GetLogin(), | ||||
| 						Content:  reaction.GetContent(), | ||||
| 					}) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -737,25 +746,27 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques | ||||
| 	for _, c := range cs { | ||||
| 		// get reactions | ||||
| 		var reactions []*base.Reaction | ||||
| 		for i := 1; ; i++ { | ||||
| 			g.waitAndPickClient() | ||||
| 			res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{ | ||||
| 				Page:    i, | ||||
| 				PerPage: g.maxPerPage, | ||||
| 			}) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			g.setRate(&resp.Rate) | ||||
| 			if len(res) == 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			for _, reaction := range res { | ||||
| 				reactions = append(reactions, &base.Reaction{ | ||||
| 					UserID:   reaction.User.GetID(), | ||||
| 					UserName: reaction.User.GetLogin(), | ||||
| 					Content:  reaction.GetContent(), | ||||
| 		if !g.SkipReactions { | ||||
| 			for i := 1; ; i++ { | ||||
| 				g.waitAndPickClient() | ||||
| 				res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{ | ||||
| 					Page:    i, | ||||
| 					PerPage: g.maxPerPage, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				g.setRate(&resp.Rate) | ||||
| 				if len(res) == 0 { | ||||
| 					break | ||||
| 				} | ||||
| 				for _, reaction := range res { | ||||
| 					reactions = append(reactions, &base.Reaction{ | ||||
| 						UserID:   reaction.User.GetID(), | ||||
| 						UserName: reaction.User.GetLogin(), | ||||
| 						Content:  reaction.GetContent(), | ||||
| 					}) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -242,13 +242,14 @@ type GitServiceType int | ||||
|  | ||||
| // enumerate all GitServiceType | ||||
| const ( | ||||
| 	NotMigrated     GitServiceType = iota // 0 not migrated from external sites | ||||
| 	PlainGitService                       // 1 plain git service | ||||
| 	GithubService                         // 2 github.com | ||||
| 	GiteaService                          // 3 gitea service | ||||
| 	GitlabService                         // 4 gitlab service | ||||
| 	GogsService                           // 5 gogs service | ||||
| 	OneDevService                         // 6 onedev service | ||||
| 	NotMigrated      GitServiceType = iota // 0 not migrated from external sites | ||||
| 	PlainGitService                        // 1 plain git service | ||||
| 	GithubService                          // 2 github.com | ||||
| 	GiteaService                           // 3 gitea service | ||||
| 	GitlabService                          // 4 gitlab service | ||||
| 	GogsService                            // 5 gogs service | ||||
| 	OneDevService                          // 6 onedev service | ||||
| 	GitBucketService                       // 7 gitbucket service | ||||
| ) | ||||
|  | ||||
| // Name represents the service type's name | ||||
| @@ -270,6 +271,8 @@ func (gt GitServiceType) Title() string { | ||||
| 		return "Gogs" | ||||
| 	case OneDevService: | ||||
| 		return "OneDev" | ||||
| 	case GitBucketService: | ||||
| 		return "GitBucket" | ||||
| 	case PlainGitService: | ||||
| 		return "Git" | ||||
| 	} | ||||
| @@ -326,5 +329,6 @@ var ( | ||||
| 		GiteaService, | ||||
| 		GogsService, | ||||
| 		OneDevService, | ||||
| 		GitBucketService, | ||||
| 	} | ||||
| ) | ||||
|   | ||||
| @@ -911,6 +911,7 @@ migrate.gitlab.description = Migrate data from gitlab.com or other GitLab instan | ||||
| migrate.gitea.description = Migrate data from gitea.com or other Gitea instances. | ||||
| migrate.gogs.description = Migrate data from notabug.org or other Gogs instances. | ||||
| migrate.onedev.description = Migrate data from code.onedev.io or other OneDev instances. | ||||
| migrate.gitbucket.description = Migrating data from GitBucket instances. | ||||
| migrate.migrating_git = Migrating Git Data | ||||
| migrate.migrating_topics = Migrating Topics | ||||
| migrate.migrating_milestones = Migrating Milestones | ||||
|   | ||||
							
								
								
									
										1
									
								
								public/img/svg/gitea-gitbucket.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/img/svg/gitea-gitbucket.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <svg version="1.0" viewBox="0 0 316 329" class="svg gitea-gitbucket" width="16" height="16" aria-hidden="true"><g fill="#303030"><path d="M123 21.1c-44.8 2.8-84 12.8-97.1 24.6-5 4.5-5 7.1 0 11.6C41.7 71.5 96.6 82.9 150 83h10.6l5.4-5.6c11.8-12.1 21.3-12.4 32.6-1.2l5.2 5 13.3-1.7c33.8-4.2 61.5-12.7 71.8-22 5.3-4.8 5.3-7.2 0-12-10.1-9.1-39.1-18.1-70.4-21.9-28.3-3.4-65.6-4.4-95.5-2.5zM23.2 80.6c.4 1.6 7 42.9 14.8 91.9 7.9 49 14.7 89.5 15.2 90.2 1.7 2.1 25.8 11.4 41.6 15.9 13 3.7 35.1 8.4 40 8.4.6 0 1.2-.6 1.2-1.3 0-.6-17.4-18.5-38.6-39.7C57.9 206.6 55 203.2 55 196c0-7.2 3-10.7 38.3-45.9 30.1-30 34.8-34.3 36.6-33.5 1.1.5 8.7 7.4 17 15.2l15.1 14.4v5.9c0 7.3 2.4 12.4 7.7 16.7l3.8 3v61.8l-3.8 3.4c-10.2 8.9-10.2 22.9-.1 30.7 3.1 2.3 4.9 2.8 10.8 3.1 8.2.4 11.5-1.1 16.2-7.3 2.2-3 2.9-5.1 3.2-10 .4-6.5-.2-8.3-5.3-15.4l-2.5-3.4v-26.6c0-26.7.3-31.1 2.3-31.1.5 0 5.4 4.4 10.9 9.7 9.6 9.5 9.9 10 10.8 15.7 1.7 10.3 8.9 16.6 19 16.6 7.6 0 13.5-3.9 17.4-11.7 3.2-6.4 1.6-14.3-4.3-20.6-4.1-4.4-7.3-5.7-14.9-5.7h-6.8l-12.7-12.1c-10.7-10.1-12.7-12.6-13.2-15.7-1.2-7.2-1.6-8.2-4.7-11.7-3.9-4.5-7.7-6.5-12.2-6.5-1.9 0-4.5-.4-5.8-.9-1.3-.5-9.9-8.2-19.3-17l-17-16-7.1-.1c-10.6 0-36-2.7-52.4-5.5-22.8-4-38.5-8.6-57.9-17.2-1.1-.5-1.3 0-.9 2.3zM278.5 83.6c-8.6 3.6-28 8.8-42.5 11.4-6.9 1.2-12.9 2.6-13.5 3.1-.6.6 9.3 11.2 27.5 29.4 15.6 15.6 28.5 28.3 28.7 28.1.2-.2 1.9-15.8 3.8-34.7 1.9-18.9 3.7-35.6 4-37.2.6-3.4-.2-3.4-8-.1zM255.2 259.3c-7.8 7.8-14.2 14.6-14.2 15 0 .4.7.7 1.6.7 2.2 0 23-8.9 24.2-10.3.9-1.1 3.5-18.7 2.9-19.3-.2-.2-6.7 6.1-14.5 13.9zM56 283.5c0 3.4 4 9.5 8.4 12.9 6.1 4.6 19.7 10.4 31.7 13.5 16.9 4.3 32.1 6.2 53.4 6.8l19 .5-7-7.1c-6.8-6.9-7.1-7.1-12-7.1-18.9 0-55.1-7.9-80.6-17.6C62.5 283 57 281 56.6 281c-.3 0-.6 1.1-.6 2.5zM262 283.4c-5.3 2.8-25 9.7-36 12.6l-11.4 2.9-7.8 7.8c-4.2 4.2-7.6 7.9-7.4 8.1.9.8 24.4-4.1 33.4-6.9 16.4-5.3 26.7-11.4 30.8-18.5 2.4-4 3.1-7.4 1.7-7.4-.5.1-1.9.7-3.3 1.4z"/></g></svg> | ||||
| After Width: | Height: | Size: 1.9 KiB | 
							
								
								
									
										129
									
								
								templates/repo/migrate/gitbucket.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								templates/repo/migrate/gitbucket.tmpl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| {{template "base/head" .}} | ||||
| <div class="page-content repository new migrate"> | ||||
| 	<div class="ui middle very relaxed page grid"> | ||||
| 		<div class="column"> | ||||
| 			<form class="ui form" action="{{.Link}}" method="post"> | ||||
| 				{{.CsrfTokenHtml}} | ||||
| 				<h3 class="ui top attached header"> | ||||
| 					{{.i18n.Tr "repo.migrate.migrate" .service.Title}} | ||||
| 					<input id="service_type" type="hidden" name="service" value="{{.service}}"> | ||||
| 				</h3> | ||||
| 				<div class="ui attached segment"> | ||||
| 					{{template "base/alert" .}} | ||||
| 					<div class="inline required field {{if .Err_CloneAddr}}error{{end}}"> | ||||
| 						<label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label> | ||||
| 						<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required> | ||||
| 						<span class="help"> | ||||
| 						{{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}} | ||||
| 						</span> | ||||
| 					</div> | ||||
|  | ||||
| 					<div class="inline field {{if .Err_Auth}}error{{end}}"> | ||||
| 						<label for="auth_username">{{.i18n.Tr "username"}}</label> | ||||
| 						<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}> | ||||
| 					</div> | ||||
| 					<input class="fake" type="password"> | ||||
| 					<div class="inline field {{if .Err_Auth}}error{{end}}"> | ||||
| 						<label for="auth_password">{{.i18n.Tr "password"}}</label> | ||||
| 						<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}"> | ||||
| 					</div> | ||||
|  | ||||
| 					{{template "repo/migrate/options" .}} | ||||
|  | ||||
| 					<span class="help">{{.i18n.Tr "repo.migrate.migrate_items_options"}}</span> | ||||
| 					<div id="migrate_items"> | ||||
| 						<div class="inline field"> | ||||
| 							<label>{{.i18n.Tr "repo.migrate_items"}}</label> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_wiki" | Safe}}</label> | ||||
| 							</div> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_milestones" | Safe}}</label> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="inline field"> | ||||
| 							<label></label> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="labels" type="checkbox" {{if .labels}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_labels" | Safe}}</label> | ||||
| 							</div> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="issues" type="checkbox" {{if .issues}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_issues" | Safe}}</label> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="inline field"> | ||||
| 							<label></label> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_pullrequests" | Safe}}</label> | ||||
| 							</div> | ||||
| 							<div class="ui checkbox"> | ||||
| 								<input name="releases" type="checkbox" {{if .releases}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.migrate_items_releases" | Safe}}</label> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
|  | ||||
| 					<div class="ui divider"></div> | ||||
|  | ||||
| 					<div class="inline required field {{if .Err_Owner}}error{{end}}"> | ||||
| 						<label>{{.i18n.Tr "repo.owner"}}</label> | ||||
| 						<div class="ui selection owner dropdown"> | ||||
| 							<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required> | ||||
| 							<span class="text truncated-item-container" title="{{.ContextUser.Name}}"> | ||||
| 								{{avatar .ContextUser 28 "mini"}} | ||||
| 								<span class="truncated-item-name">{{.ContextUser.ShortName 40}}</span> | ||||
| 							</span> | ||||
| 							{{svg "octicon-triangle-down" 14 "dropdown icon"}} | ||||
| 							<div class="menu" title="{{.SignedUser.Name}}"> | ||||
| 								<div class="item truncated-item-container" data-value="{{.SignedUser.ID}}"> | ||||
| 									{{avatar .SignedUser 28 "mini"}} | ||||
| 									<span class="truncated-item-name">{{.SignedUser.ShortName 40}}</span> | ||||
| 								</div> | ||||
| 								{{range .Orgs}} | ||||
| 									<div class="item truncated-item-container" data-value="{{.ID}}" title="{{.Name}}"> | ||||
| 										{{avatar . 28 "mini"}} | ||||
| 										<span class="truncated-item-name">{{.ShortName 40}}</span> | ||||
| 									</div> | ||||
| 								{{end}} | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
|  | ||||
| 					<div class="inline required field {{if .Err_RepoName}}error{{end}}"> | ||||
| 						<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label> | ||||
| 						<input id="repo_name" name="repo_name" value="{{.repo_name}}" required> | ||||
| 					</div> | ||||
| 					<div class="inline field"> | ||||
| 						<label>{{.i18n.Tr "repo.visibility"}}</label> | ||||
| 						<div class="ui checkbox"> | ||||
| 							{{if .IsForcedPrivate}} | ||||
| 								<input name="private" type="checkbox" checked readonly> | ||||
| 								<label>{{.i18n.Tr "repo.visibility_helper_forced" | Safe}}</label> | ||||
| 							{{else}} | ||||
| 								<input name="private" type="checkbox" {{if .private}}checked{{end}}> | ||||
| 								<label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label> | ||||
| 							{{end}} | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="inline field {{if .Err_Description}}error{{end}}"> | ||||
| 						<label for="description">{{.i18n.Tr "repo.repo_desc"}}</label> | ||||
| 						<textarea id="description" name="description">{{.description}}</textarea> | ||||
| 					</div> | ||||
|  | ||||
| 					<div class="inline field"> | ||||
| 						<label></label> | ||||
| 						<button class="ui green button"> | ||||
| 							{{.i18n.Tr "repo.migrate_repo"}} | ||||
| 						</button> | ||||
| 						<a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</form> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
							
								
								
									
										39
									
								
								web_src/svg/gitea-gitbucket.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								web_src/svg/gitea-gitbucket.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <?xml version="1.0" standalone="no"?> | ||||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" | ||||
|  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> | ||||
| <svg version="1.0" xmlns="http://www.w3.org/2000/svg" | ||||
|  width="316.000000pt" height="329.000000pt" viewBox="0 0 316.000000 329.000000" | ||||
|  preserveAspectRatio="xMidYMid meet"> | ||||
| <metadata> | ||||
| Created by potrace 1.14, written by Peter Selinger 2001-2017 | ||||
| </metadata> | ||||
| <g transform="translate(0.000000,329.000000) scale(0.100000,-0.100000)" | ||||
| fill="#303030" stroke="none"> | ||||
| <path d="M1230 3079 c-448 -28 -840 -128 -971 -246 -50 -45 -50 -71 0 -116 | ||||
| 158 -142 707 -256 1241 -257 l106 0 54 56 c118 121 213 124 326 12 l52 -50 | ||||
| 133 17 c338 42 615 127 718 220 53 48 53 72 0 120 -101 91 -391 181 -704 219 | ||||
| -283 34 -656 44 -955 25z"/> | ||||
| <path d="M232 2484 c4 -16 70 -429 148 -919 79 -490 147 -895 152 -902 17 -21 | ||||
| 258 -114 416 -159 130 -37 351 -84 400 -84 6 0 12 6 12 13 0 6 -174 185 -386 | ||||
| 397 -395 394 -424 428 -424 500 0 72 30 107 383 459 301 300 348 343 366 335 | ||||
| 11 -5 87 -74 170 -152 l151 -144 0 -59 c0 -73 24 -124 77 -167 l38 -30 0 -309 | ||||
| 0 -309 -38 -34 c-102 -89 -102 -229 -1 -307 31 -23 49 -28 108 -31 82 -4 115 | ||||
| 11 162 73 22 30 29 51 32 100 4 65 -2 83 -53 154 l-25 34 0 266 c0 267 3 311 | ||||
| 23 311 5 0 54 -44 109 -97 96 -95 99 -100 108 -157 17 -103 89 -166 190 -166 | ||||
| 76 0 135 39 174 117 32 64 16 143 -43 206 -41 44 -73 57 -149 57 l-68 0 -127 | ||||
| 121 c-107 101 -127 126 -132 157 -12 72 -16 82 -47 117 -39 45 -77 65 -122 65 | ||||
| -19 0 -45 4 -58 9 -13 5 -99 82 -193 170 l-170 160 -71 1 c-106 0 -360 27 | ||||
| -524 55 -228 40 -385 86 -579 172 -11 5 -13 0 -9 -23z"/> | ||||
| <path d="M2785 2454 c-86 -36 -280 -88 -425 -114 -69 -12 -129 -26 -135 -31 | ||||
| -6 -6 93 -112 275 -294 156 -156 285 -283 287 -281 2 2 19 158 38 347 19 189 | ||||
| 37 356 40 372 6 34 -2 34 -80 1z"/> | ||||
| <path d="M2552 697 c-78 -78 -142 -146 -142 -150 0 -4 7 -7 16 -7 22 0 230 89 | ||||
| 242 103 9 11 35 187 29 193 -2 2 -67 -61 -145 -139z"/> | ||||
| <path d="M560 455 c0 -34 40 -95 84 -129 61 -46 197 -104 317 -135 169 -43 | ||||
| 321 -62 534 -68 l190 -5 -70 71 c-68 69 -71 71 -120 71 -189 0 -551 79 -806 | ||||
| 176 -64 24 -119 44 -123 44 -3 0 -6 -11 -6 -25z"/> | ||||
| <path d="M2620 456 c-53 -28 -250 -97 -360 -126 l-114 -29 -78 -78 c-42 -42 | ||||
| -76 -79 -74 -81 9 -8 244 41 334 69 164 53 267 114 308 185 24 40 31 74 17 74 | ||||
| -5 -1 -19 -7 -33 -14z"/> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.2 KiB | 
		Reference in New Issue
	
	Block a user