mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Provide option to unlink a fork (#11858)
* Provide option to unlink a fork Fix #4566 Signed-off-by: Andrew Thornton <art27@cantab.net> * Apply suggestions from code review Co-authored-by: techknowlogick <matti@mdranta.net> * Add check that user can create repo Signed-off-by: Andrew Thornton <art27@cantab.net> * as per @cirnoT Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <matti@mdranta.net>
This commit is contained in:
		@@ -209,19 +209,9 @@ func (repo *Repository) SanitizedOriginalURL() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ColorFormat returns a colored string to represent this repo
 | 
					// ColorFormat returns a colored string to represent this repo
 | 
				
			||||||
func (repo *Repository) ColorFormat(s fmt.State) {
 | 
					func (repo *Repository) ColorFormat(s fmt.State) {
 | 
				
			||||||
	var ownerName interface{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if repo.OwnerName != "" {
 | 
					 | 
				
			||||||
		ownerName = repo.OwnerName
 | 
					 | 
				
			||||||
	} else if repo.Owner != nil {
 | 
					 | 
				
			||||||
		ownerName = repo.Owner.Name
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		ownerName = log.NewColoredIDValue(strconv.FormatInt(repo.OwnerID, 10))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log.ColorFprintf(s, "%d:%s/%s",
 | 
						log.ColorFprintf(s, "%d:%s/%s",
 | 
				
			||||||
		log.NewColoredIDValue(repo.ID),
 | 
							log.NewColoredIDValue(repo.ID),
 | 
				
			||||||
		ownerName,
 | 
							repo.OwnerName,
 | 
				
			||||||
		repo.Name)
 | 
							repo.Name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1382,6 +1382,11 @@ settings.convert_desc = You can convert this mirror into a regular repository. T
 | 
				
			|||||||
settings.convert_notices_1 = This operation will convert the mirror into a regular repository and cannot be undone.
 | 
					settings.convert_notices_1 = This operation will convert the mirror into a regular repository and cannot be undone.
 | 
				
			||||||
settings.convert_confirm = Convert Repository
 | 
					settings.convert_confirm = Convert Repository
 | 
				
			||||||
settings.convert_succeed = The mirror has been converted into a regular repository.
 | 
					settings.convert_succeed = The mirror has been converted into a regular repository.
 | 
				
			||||||
 | 
					settings.convert_fork = Convert to Regular Repository
 | 
				
			||||||
 | 
					settings.convert_fork_desc = You can convert this fork into a regular repository. This cannot be undone.
 | 
				
			||||||
 | 
					settings.convert_fork_notices_1 = This operation will convert the fork into a regular repository and cannot be undone.
 | 
				
			||||||
 | 
					settings.convert_fork_confirm = Convert Repository
 | 
				
			||||||
 | 
					settings.convert_fork_succeed = The fork has been converted into a regular repository.
 | 
				
			||||||
settings.transfer = Transfer Ownership
 | 
					settings.transfer = Transfer Ownership
 | 
				
			||||||
settings.transfer_desc = Transfer this repository to a user or to an organization for which you have administrator rights.
 | 
					settings.transfer_desc = Transfer this repository to a user or to an organization for which you have administrator rights.
 | 
				
			||||||
settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user.
 | 
					settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -356,9 +356,46 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
			ctx.ServerError("DeleteMirrorByRepoID", err)
 | 
								ctx.ServerError("DeleteMirrorByRepoID", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		log.Trace("Repository converted from mirror to regular: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
							log.Trace("Repository converted from mirror to regular: %s", repo.FullName())
 | 
				
			||||||
		ctx.Flash.Success(ctx.Tr("repo.settings.convert_succeed"))
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.convert_succeed"))
 | 
				
			||||||
		ctx.Redirect(setting.AppSubURL + "/" + ctx.Repo.Owner.Name + "/" + repo.Name)
 | 
							ctx.Redirect(repo.Link())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "convert_fork":
 | 
				
			||||||
 | 
							if !ctx.Repo.IsOwner() {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := repo.GetOwner(); err != nil {
 | 
				
			||||||
 | 
								ctx.ServerError("Convert Fork", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if repo.Name != form.RepoName {
 | 
				
			||||||
 | 
								ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), tplSettingsOptions, nil)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !repo.IsFork {
 | 
				
			||||||
 | 
								ctx.Error(404)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !ctx.Repo.Owner.CanCreateRepo() {
 | 
				
			||||||
 | 
								ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxCreationLimit()))
 | 
				
			||||||
 | 
								ctx.Redirect(repo.Link() + "/settings")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							repo.IsFork = false
 | 
				
			||||||
 | 
							repo.ForkID = 0
 | 
				
			||||||
 | 
							if err := models.UpdateRepository(repo, false); err != nil {
 | 
				
			||||||
 | 
								log.Error("Unable to update repository %-v whilst converting from fork", repo)
 | 
				
			||||||
 | 
								ctx.ServerError("Convert Fork", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log.Trace("Repository converted from fork to regular: %s", repo.FullName())
 | 
				
			||||||
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.convert_fork_succeed"))
 | 
				
			||||||
 | 
							ctx.Redirect(repo.Link())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "transfer":
 | 
						case "transfer":
 | 
				
			||||||
		if !ctx.Repo.IsOwner() {
 | 
							if !ctx.Repo.IsOwner() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -358,17 +358,28 @@
 | 
				
			|||||||
		</h4>
 | 
							</h4>
 | 
				
			||||||
		<div class="ui attached warning table danger segment">
 | 
							<div class="ui attached warning table danger segment">
 | 
				
			||||||
			{{if .Repository.IsMirror}}
 | 
								{{if .Repository.IsMirror}}
 | 
				
			||||||
			<div class="item">
 | 
									<div class="item">
 | 
				
			||||||
				<div class="ui right">
 | 
										<div class="ui right">
 | 
				
			||||||
					<button class="ui basic red show-modal button" data-modal="#convert-repo-modal">{{.i18n.Tr "repo.settings.convert"}}</button>
 | 
											<button class="ui basic red show-modal button" data-modal="#convert-mirror-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>
 | 
				
			||||||
				<div>
 | 
									<div class="ui divider"></div>
 | 
				
			||||||
					<h5>{{.i18n.Tr "repo.settings.convert"}}</h5>
 | 
								{{end}}
 | 
				
			||||||
					<p>{{.i18n.Tr "repo.settings.convert_desc"}}</p>
 | 
								{{if and .Repository.IsFork .Repository.Owner.CanCreateRepo}}
 | 
				
			||||||
 | 
									<div class="item">
 | 
				
			||||||
 | 
										<div class="ui right">
 | 
				
			||||||
 | 
											<button class="ui basic red show-modal button" data-modal="#convert-fork-repo-modal">{{.i18n.Tr "repo.settings.convert_fork"}}</button>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div>
 | 
				
			||||||
 | 
											<h5>{{.i18n.Tr "repo.settings.convert_fork"}}</h5>
 | 
				
			||||||
 | 
											<p>{{.i18n.Tr "repo.settings.convert_fork_desc"}}</p>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
									<div class="ui divider"></div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
			<div class="ui divider"></div>
 | 
					 | 
				
			||||||
			{{end}}
 | 
								{{end}}
 | 
				
			||||||
			<div class="item">
 | 
								<div class="item">
 | 
				
			||||||
				<div class="ui right">
 | 
									<div class="ui right">
 | 
				
			||||||
@@ -437,37 +448,67 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{{if .Permission.IsOwner}}
 | 
					{{if .Permission.IsOwner}}
 | 
				
			||||||
	{{if .Repository.IsMirror}}
 | 
						{{if .Repository.IsMirror}}
 | 
				
			||||||
	<div class="ui small modal" id="convert-repo-modal">
 | 
							<div class="ui small modal" id="convert-mirror-repo-modal">
 | 
				
			||||||
		<div class="header">
 | 
								<div class="header">
 | 
				
			||||||
			{{.i18n.Tr "repo.settings.convert"}}
 | 
									{{.i18n.Tr "repo.settings.convert"}}
 | 
				
			||||||
		</div>
 | 
					 | 
				
			||||||
		<div class="content">
 | 
					 | 
				
			||||||
			<div class="ui warning message text left">
 | 
					 | 
				
			||||||
				{{.i18n.Tr "repo.settings.convert_notices_1"}}
 | 
					 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<form class="ui form" action="{{.Link}}" method="post">
 | 
								<div class="content">
 | 
				
			||||||
				{{.CsrfTokenHtml}}
 | 
									<div class="ui warning message text left">
 | 
				
			||||||
				<input type="hidden" name="action" value="convert">
 | 
										{{.i18n.Tr "repo.settings.convert_notices_1"}}
 | 
				
			||||||
				<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="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="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.convert_confirm"}}</button>
 | 
											<button class="ui red button">{{.i18n.Tr "repo.settings.convert_confirm"}}</button>
 | 
				
			||||||
				</div>
 | 
										</div>
 | 
				
			||||||
			</form>
 | 
									</form>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
					 | 
				
			||||||
	{{end}}
 | 
						{{end}}
 | 
				
			||||||
 | 
						{{if and .Repository.IsFork .Repository.Owner.CanCreateRepo}}
 | 
				
			||||||
 | 
							<div class="ui small modal" id="convert-fork-repo-modal">
 | 
				
			||||||
 | 
								<div class="header">
 | 
				
			||||||
 | 
									{{.i18n.Tr "repo.settings.convert_fork"}}
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								<div class="content">
 | 
				
			||||||
 | 
									<div class="ui warning message text left">
 | 
				
			||||||
 | 
										{{.i18n.Tr "repo.settings.convert_fork_notices_1"}}
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<form class="ui form" action="{{.Link}}" method="post">
 | 
				
			||||||
 | 
										{{.CsrfTokenHtml}}
 | 
				
			||||||
 | 
										<input type="hidden" name="action" value="convert_fork">
 | 
				
			||||||
 | 
										<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.convert_fork_confirm"}}</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"}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2796,7 +2796,10 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#transfer-repo-modal,
 | 
					#transfer-repo-modal,
 | 
				
			||||||
#delete-repo-modal {
 | 
					#delete-repo-modal,
 | 
				
			||||||
 | 
					#delete-wiki-modal,
 | 
				
			||||||
 | 
					#convert-fork-repo-modal,
 | 
				
			||||||
 | 
					#convert-mirror-repo-modal {
 | 
				
			||||||
    .ui.message {
 | 
					    .ui.message {
 | 
				
			||||||
        width: 100% !important;
 | 
					        width: 100% !important;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user