mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Merge pull request #2624 from mhartkorn/convert-mirror-to-repo
Convert mirrors to regular repositories
This commit is contained in:
		@@ -584,14 +584,19 @@ settings.tracker_url_format = External Issue Tracker URL Format
 | 
				
			|||||||
settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
 | 
					settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
 | 
				
			||||||
settings.pulls_desc = Enable pull requests to accept public contributions
 | 
					settings.pulls_desc = Enable pull requests to accept public contributions
 | 
				
			||||||
settings.danger_zone = Danger Zone
 | 
					settings.danger_zone = Danger Zone
 | 
				
			||||||
 | 
					settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
 | 
				
			||||||
 | 
					settings.convert = Convert To Regular Repository
 | 
				
			||||||
 | 
					settings.convert_desc = You can convert this mirror to a regular repository. This cannot be reversed.
 | 
				
			||||||
 | 
					settings.convert_notices_1 = - This operation will convert this repository mirror into a regular repository and cannot be undone.
 | 
				
			||||||
 | 
					settings.convert_succeed = Repository successfully converted.
 | 
				
			||||||
 | 
					settings.convert_failed = Unable to convert repository.
 | 
				
			||||||
settings.transfer = Transfer Ownership
 | 
					settings.transfer = Transfer Ownership
 | 
				
			||||||
settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
 | 
					settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
 | 
				
			||||||
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
 | 
					 | 
				
			||||||
settings.delete = Delete This Repository
 | 
					 | 
				
			||||||
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
 | 
					 | 
				
			||||||
settings.transfer_notices_1 = - You will lose access if new owner is a individual user.
 | 
					settings.transfer_notices_1 = - You will lose access if new owner is a individual user.
 | 
				
			||||||
settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
 | 
					settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
 | 
				
			||||||
settings.transfer_form_title = Please enter following information to confirm your operation:
 | 
					settings.transfer_form_title = Please enter following information to confirm your operation:
 | 
				
			||||||
 | 
					settings.delete = Delete This Repository
 | 
				
			||||||
 | 
					settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
 | 
				
			||||||
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
 | 
					settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
 | 
				
			||||||
settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
 | 
					settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
 | 
				
			||||||
settings.delete_notices_fork_1 = - If this repository is public, all forks will become independent after deletion.
 | 
					settings.delete_notices_fork_1 = - If this repository is public, all forks will become independent after deletion.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -655,7 +655,12 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
 | 
				
			|||||||
		return repo, UpdateRepository(repo, false)
 | 
							return repo, UpdateRepository(repo, false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err = createUpdateHook(repoPath); err != nil {
 | 
						return CleanUpMigrateInfo(repo, repoPath)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Finish migrating repository with things that don't need to be done for mirrors.
 | 
				
			||||||
 | 
					func CleanUpMigrateInfo(repo *Repository, repoPath string) (*Repository, error) {
 | 
				
			||||||
 | 
						if err := createUpdateHook(repoPath); err != nil {
 | 
				
			||||||
		return repo, fmt.Errorf("createUpdateHook: %v", err)
 | 
							return repo, fmt.Errorf("createUpdateHook: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1615,6 +1620,11 @@ func MirrorUpdate() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeleteMirrorByRepoID(repoId int64) error {
 | 
				
			||||||
 | 
						_, err := x.Delete(&Mirror{RepoID: repoId})
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GitFsck calls 'git fsck' to check repository health.
 | 
					// GitFsck calls 'git fsck' to check repository health.
 | 
				
			||||||
func GitFsck() {
 | 
					func GitFsck() {
 | 
				
			||||||
	if taskStatusPool.IsRunning(_GIT_FSCK) {
 | 
						if taskStatusPool.IsRunning(_GIT_FSCK) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,6 +141,38 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
		ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 | 
				
			||||||
		ctx.Redirect(ctx.Repo.RepoLink + "/settings")
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/settings")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "convert":
 | 
				
			||||||
 | 
							if repo.Name != form.RepoName {
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ctx.Repo.Owner.IsOrganization() {
 | 
				
			||||||
 | 
								if !ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
				
			||||||
 | 
									ctx.Error(404)
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !repo.IsMirror {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							repo.IsMirror = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if _, err := models.CleanUpMigrateInfo(repo, models.RepoPath(ctx.Repo.Owner.Name, repo.Name)); err != nil {
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("settings.convert.failed"), SETTINGS_OPTIONS, &form)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := models.DeleteMirrorByRepoID(ctx.Repo.Repository.ID); err != nil {
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("settings.convert.failed"), SETTINGS_OPTIONS, &form)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Trace("Repository converted from mirror to regular: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
				
			||||||
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.convert_succeed"))
 | 
				
			||||||
 | 
							ctx.Redirect(setting.AppSubUrl + "/" + ctx.Repo.Owner.Name + "/" + repo.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "transfer":
 | 
						case "transfer":
 | 
				
			||||||
		if repo.Name != form.RepoName {
 | 
							if repo.Name != form.RepoName {
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
 | 
								ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,6 +138,19 @@
 | 
				
			|||||||
					{{.i18n.Tr "repo.settings.danger_zone"}}
 | 
										{{.i18n.Tr "repo.settings.danger_zone"}}
 | 
				
			||||||
				</h4>
 | 
									</h4>
 | 
				
			||||||
				<div class="ui attached warning table danger segment">
 | 
									<div class="ui attached warning table danger segment">
 | 
				
			||||||
 | 
										{{if .Repository.IsMirror}}
 | 
				
			||||||
 | 
										<div class="item">
 | 
				
			||||||
 | 
											<div class="ui right">
 | 
				
			||||||
 | 
												<button class="ui basic red show-modal button" data-modal="#convert-repo-modal">{{.i18n.Tr "repo.settings.convert"}}</button>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<div>
 | 
				
			||||||
 | 
												<h5>{{.i18n.Tr "repo.settings.convert"}}</h5>
 | 
				
			||||||
 | 
												<p>{{.i18n.Tr "repo.settings.convert_desc"}}</p>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										<div class="ui divider"></div>
 | 
				
			||||||
 | 
										{{end}}
 | 
				
			||||||
					<div class="item">
 | 
										<div class="item">
 | 
				
			||||||
						<div class="ui right">
 | 
											<div class="ui right">
 | 
				
			||||||
							<button class="ui basic red show-modal button" data-modal="#transfer-repo-modal">{{.i18n.Tr "repo.settings.transfer"}}</button>
 | 
												<button class="ui basic red show-modal button" data-modal="#transfer-repo-modal">{{.i18n.Tr "repo.settings.transfer"}}</button>
 | 
				
			||||||
@@ -165,6 +178,38 @@
 | 
				
			|||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{if .Repository.IsMirror}}
 | 
				
			||||||
 | 
					<div class="ui small modal" id="convert-repo-modal">
 | 
				
			||||||
 | 
						<div class="header">
 | 
				
			||||||
 | 
							{{.i18n.Tr "repo.settings.convert"}}
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="content">
 | 
				
			||||||
 | 
							<div class="ui warning message text left">
 | 
				
			||||||
 | 
								{{.i18n.Tr "repo.settings.convert_notices_1" | Safe}}
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<form class="ui form" action="{{.Link}}" method="post">
 | 
				
			||||||
 | 
								{{.CsrfTokenHtml}}
 | 
				
			||||||
 | 
								<input type="hidden" name="action" value="convert">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<label>
 | 
				
			||||||
 | 
										{{.i18n.Tr "repo.settings.transfer_form_title"}}
 | 
				
			||||||
 | 
										<span class="text red">{{.Repository.Name}}</span>
 | 
				
			||||||
 | 
									</label>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="required field">
 | 
				
			||||||
 | 
									<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
 | 
				
			||||||
 | 
									<input id="repo_name" name="repo_name" required>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								<div class="text right actions">
 | 
				
			||||||
 | 
									<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
 | 
				
			||||||
 | 
									<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_convert"}}</button>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
							</form>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="ui small modal" id="transfer-repo-modal">
 | 
					<div class="ui small modal" id="transfer-repo-modal">
 | 
				
			||||||
	<div class="header">
 | 
						<div class="header">
 | 
				
			||||||
		{{.i18n.Tr "repo.settings.transfer"}}
 | 
							{{.i18n.Tr "repo.settings.transfer"}}
 | 
				
			||||||
@@ -212,27 +257,27 @@
 | 
				
			|||||||
			{{.i18n.Tr "repo.settings.delete_notices_fork_1" | Safe}} <br>
 | 
								{{.i18n.Tr "repo.settings.delete_notices_fork_1" | Safe}} <br>
 | 
				
			||||||
			{{.i18n.Tr "repo.settings.delete_notices_fork_2" | Safe}} <br>
 | 
								{{.i18n.Tr "repo.settings.delete_notices_fork_2" | Safe}} <br>
 | 
				
			||||||
			{{.i18n.Tr "repo.settings.delete_notices_fork_3" | Safe}}
 | 
								{{.i18n.Tr "repo.settings.delete_notices_fork_3" | Safe}}
 | 
				
			||||||
		{{end}}
 | 
								{{end}}
 | 
				
			||||||
	</div>
 | 
					 | 
				
			||||||
	<form class="ui form" action="{{.Link}}" method="post">
 | 
					 | 
				
			||||||
		{{.CsrfTokenHtml}}
 | 
					 | 
				
			||||||
		<input type="hidden" name="action" value="delete">
 | 
					 | 
				
			||||||
		<div class="field">
 | 
					 | 
				
			||||||
			<label>
 | 
					 | 
				
			||||||
				{{.i18n.Tr "repo.settings.transfer_form_title"}}
 | 
					 | 
				
			||||||
				<span class="text red">{{.Repository.Name}}</span>
 | 
					 | 
				
			||||||
			</label>
 | 
					 | 
				
			||||||
		</div>
 | 
					 | 
				
			||||||
		<div class="required field">
 | 
					 | 
				
			||||||
			<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
 | 
					 | 
				
			||||||
			<input id="repo_name" name="repo_name" required>
 | 
					 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							<form class="ui form" action="{{.Link}}" method="post">
 | 
				
			||||||
 | 
								{{.CsrfTokenHtml}}
 | 
				
			||||||
 | 
								<input type="hidden" name="action" value="delete">
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
									<label>
 | 
				
			||||||
 | 
										{{.i18n.Tr "repo.settings.transfer_form_title"}}
 | 
				
			||||||
 | 
										<span class="text red">{{.Repository.Name}}</span>
 | 
				
			||||||
 | 
									</label>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="required field">
 | 
				
			||||||
 | 
									<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
 | 
				
			||||||
 | 
									<input id="repo_name" name="repo_name" required>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div class="text right actions">
 | 
								<div class="text right actions">
 | 
				
			||||||
			<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
 | 
									<div class="ui cancel button">{{.i18n.Tr "settings.cancel"}}</div>
 | 
				
			||||||
			<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_delete"}}</button>
 | 
									<button class="ui red button">{{.i18n.Tr "repo.settings.confirm_delete"}}</button>
 | 
				
			||||||
		</div>
 | 
								</div>
 | 
				
			||||||
	</form>
 | 
							</form>
 | 
				
			||||||
</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
{{template "base/footer" .}}
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user