diff --git a/models/unit/unit.go b/models/unit/unit.go
index b216712d37..e37adf995e 100644
--- a/models/unit/unit.go
+++ b/models/unit/unit.go
@@ -108,6 +108,10 @@ var (
 
 	// DisabledRepoUnits contains the units that have been globally disabled
 	DisabledRepoUnits = []Type{}
+
+	// AllowedRepoUnitGroups contains the units that have been globally enabled,
+	// with mutually exclusive units grouped together.
+	AllowedRepoUnitGroups = [][]Type{}
 )
 
 // Get valid set of default repository units from settings
@@ -162,6 +166,45 @@ func LoadUnitConfig() error {
 	if len(DefaultForkRepoUnits) == 0 {
 		return errors.New("no default fork repository units found")
 	}
+
+	// Collect the allowed repo unit groups. Mutually exclusive units are
+	// grouped together.
+	AllowedRepoUnitGroups = [][]Type{}
+	for _, unit := range []Type{
+		TypeCode,
+		TypePullRequests,
+		TypeProjects,
+		TypePackages,
+		TypeActions,
+	} {
+		// If unit is globally disabled, ignore it.
+		if unit.UnitGlobalDisabled() {
+			continue
+		}
+
+		// If it is allowed, add it to the group list.
+		AllowedRepoUnitGroups = append(AllowedRepoUnitGroups, []Type{unit})
+	}
+
+	addMutuallyExclusiveGroup := func(unit1, unit2 Type) {
+		var list []Type
+
+		if !unit1.UnitGlobalDisabled() {
+			list = append(list, unit1)
+		}
+
+		if !unit2.UnitGlobalDisabled() {
+			list = append(list, unit2)
+		}
+
+		if len(list) > 0 {
+			AllowedRepoUnitGroups = append(AllowedRepoUnitGroups, list)
+		}
+	}
+
+	addMutuallyExclusiveGroup(TypeIssues, TypeExternalTracker)
+	addMutuallyExclusiveGroup(TypeWiki, TypeExternalWiki)
+
 	return nil
 }
 
diff --git a/modules/context/repo.go b/modules/context/repo.go
index b48f6ded26..727c18cad6 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -81,6 +81,31 @@ func (r *Repository) CanCreateBranch() bool {
 	return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
 }
 
+// AllUnitsEnabled returns true if all units are enabled for the repo.
+func (r *Repository) AllUnitsEnabled(ctx context.Context) bool {
+	hasAnyUnitEnabled := func(unitGroup []unit_model.Type) bool {
+		// Loop over the group of units
+		for _, unit := range unitGroup {
+			// If *any* of them is enabled, return true.
+			if r.Repository.UnitEnabled(ctx, unit) {
+				return true
+			}
+		}
+
+		// If none are enabled, return false.
+		return false
+	}
+
+	for _, unitGroup := range unit_model.AllowedRepoUnitGroups {
+		// If any disabled unit is found, return false immediately.
+		if !hasAnyUnitEnabled(unitGroup) {
+			return false
+		}
+	}
+
+	return true
+}
+
 // RepoMustNotBeArchived checks if a repo is archived
 func RepoMustNotBeArchived() func(ctx *Context) {
 	return func(ctx *Context) {
@@ -1053,6 +1078,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
 		ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
 		ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
 		ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch()
+		ctx.Data["AllUnitsEnabled"] = ctx.Repo.AllUnitsEnabled(ctx)
 
 		ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
 		if err != nil {
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 95ce92e882..9c8b3fc541 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -2066,6 +2066,10 @@ settings.mirror_settings.push_mirror.remote_url = Git Remote Repository URL
 settings.mirror_settings.push_mirror.add = Add Push Mirror
 settings.mirror_settings.push_mirror.edit_sync_time = Edit mirror sync interval
 
+settings.units.units = Repository Units
+settings.units.overview = Overview
+settings.units.add_more = Add more...
+
 settings.sync_mirror = Synchronize Now
 settings.pull_mirror_sync_in_progress = Pulling changes from the remote %s at the moment.
 settings.push_mirror_sync_in_progress = Pushing changes to the remote %s at the moment.
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 552507e57c..8a429c359c 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -41,6 +41,7 @@ import (
 
 const (
 	tplSettingsOptions base.TplName = "repo/settings/options"
+	tplSettingsUnits   base.TplName = "repo/settings/units"
 	tplCollaboration   base.TplName = "repo/settings/collaboration"
 	tplBranches        base.TplName = "repo/settings/branches"
 	tplGithooks        base.TplName = "repo/settings/githooks"
@@ -89,6 +90,201 @@ func SettingsCtxData(ctx *context.Context) {
 	ctx.Data["PushMirrors"] = pushMirrors
 }
 
+// Units show a repositorys unit settings page
+func Units(ctx *context.Context) {
+	ctx.Data["Title"] = ctx.Tr("repo.settings.units.units")
+	ctx.Data["PageIsRepoSettingsUnits"] = true
+
+	ctx.HTML(http.StatusOK, tplSettingsUnits)
+}
+
+func UnitsPost(ctx *context.Context) {
+	form := web.GetForm(ctx).(*forms.RepoUnitSettingForm)
+
+	repo := ctx.Repo.Repository
+
+	var repoChanged bool
+	var units []repo_model.RepoUnit
+	var deleteUnitTypes []unit_model.Type
+
+	// This section doesn't require repo_name/RepoName to be set in the form, don't show it
+	// as an error on the UI for this action
+	ctx.Data["Err_RepoName"] = nil
+
+	if repo.CloseIssuesViaCommitInAnyBranch != form.EnableCloseIssuesViaCommitInAnyBranch {
+		repo.CloseIssuesViaCommitInAnyBranch = form.EnableCloseIssuesViaCommitInAnyBranch
+		repoChanged = true
+	}
+
+	if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeCode,
+		})
+	} else if !unit_model.TypeCode.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode)
+	}
+
+	if form.EnableWiki && form.EnableExternalWiki && !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
+		if !validation.IsValidExternalURL(form.ExternalWikiURL) {
+			ctx.Flash.Error(ctx.Tr("repo.settings.external_wiki_url_error"))
+			ctx.Redirect(repo.Link() + "/settings/units")
+			return
+		}
+
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeExternalWiki,
+			Config: &repo_model.ExternalWikiConfig{
+				ExternalWikiURL: form.ExternalWikiURL,
+			},
+		})
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
+	} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
+		var wikiPermissions repo_model.UnitAccessMode
+		if form.GloballyWriteableWiki {
+			wikiPermissions = repo_model.UnitAccessModeWrite
+		} else {
+			wikiPermissions = repo_model.UnitAccessModeRead
+		}
+		units = append(units, repo_model.RepoUnit{
+			RepoID:             repo.ID,
+			Type:               unit_model.TypeWiki,
+			Config:             new(repo_model.UnitConfig),
+			DefaultPermissions: wikiPermissions,
+		})
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
+	} else {
+		if !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
+			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
+		}
+		if !unit_model.TypeWiki.UnitGlobalDisabled() {
+			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
+		}
+	}
+
+	if form.EnableIssues && form.EnableExternalTracker && !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
+		if !validation.IsValidExternalURL(form.ExternalTrackerURL) {
+			ctx.Flash.Error(ctx.Tr("repo.settings.external_tracker_url_error"))
+			ctx.Redirect(repo.Link() + "/settings/units")
+			return
+		}
+		if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(form.TrackerURLFormat) {
+			ctx.Flash.Error(ctx.Tr("repo.settings.tracker_url_format_error"))
+			ctx.Redirect(repo.Link() + "/settings/units")
+			return
+		}
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeExternalTracker,
+			Config: &repo_model.ExternalTrackerConfig{
+				ExternalTrackerURL:           form.ExternalTrackerURL,
+				ExternalTrackerFormat:        form.TrackerURLFormat,
+				ExternalTrackerStyle:         form.TrackerIssueStyle,
+				ExternalTrackerRegexpPattern: form.ExternalTrackerRegexpPattern,
+			},
+		})
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
+	} else if form.EnableIssues && !form.EnableExternalTracker && !unit_model.TypeIssues.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeIssues,
+			Config: &repo_model.IssuesConfig{
+				EnableTimetracker:                form.EnableTimetracker,
+				AllowOnlyContributorsToTrackTime: form.AllowOnlyContributorsToTrackTime,
+				EnableDependencies:               form.EnableIssueDependencies,
+			},
+		})
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
+	} else {
+		if !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
+			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
+		}
+		if !unit_model.TypeIssues.UnitGlobalDisabled() {
+			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
+		}
+	}
+
+	if form.EnableProjects && !unit_model.TypeProjects.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeProjects,
+		})
+	} else if !unit_model.TypeProjects.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
+	}
+
+	if form.EnableReleases && !unit_model.TypeReleases.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeReleases,
+		})
+	} else if !unit_model.TypeReleases.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeReleases)
+	}
+
+	if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypePackages,
+		})
+	} else if !unit_model.TypePackages.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages)
+	}
+
+	if form.EnableActions && !unit_model.TypeActions.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypeActions,
+		})
+	} else if !unit_model.TypeActions.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeActions)
+	}
+
+	if form.EnablePulls && !unit_model.TypePullRequests.UnitGlobalDisabled() {
+		units = append(units, repo_model.RepoUnit{
+			RepoID: repo.ID,
+			Type:   unit_model.TypePullRequests,
+			Config: &repo_model.PullRequestsConfig{
+				IgnoreWhitespaceConflicts:     form.PullsIgnoreWhitespace,
+				AllowMerge:                    form.PullsAllowMerge,
+				AllowRebase:                   form.PullsAllowRebase,
+				AllowRebaseMerge:              form.PullsAllowRebaseMerge,
+				AllowSquash:                   form.PullsAllowSquash,
+				AllowManualMerge:              form.PullsAllowManualMerge,
+				AutodetectManualMerge:         form.EnableAutodetectManualMerge,
+				AllowRebaseUpdate:             form.PullsAllowRebaseUpdate,
+				DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
+				DefaultMergeStyle:             repo_model.MergeStyle(form.PullsDefaultMergeStyle),
+				DefaultAllowMaintainerEdit:    form.DefaultAllowMaintainerEdit,
+			},
+		})
+	} else if !unit_model.TypePullRequests.UnitGlobalDisabled() {
+		deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests)
+	}
+
+	if len(units) == 0 {
+		ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit"))
+		ctx.Redirect(ctx.Repo.RepoLink + "/settings/units")
+		return
+	}
+
+	if err := repo_model.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
+		ctx.ServerError("UpdateRepositoryUnits", err)
+		return
+	}
+	if repoChanged {
+		if err := repo_service.UpdateRepository(ctx, repo, false); err != nil {
+			ctx.ServerError("UpdateRepository", err)
+			return
+		}
+	}
+	log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
+
+	ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
+	ctx.Redirect(ctx.Repo.RepoLink + "/settings/units")
+}
+
 // Settings show a repository's settings page
 func Settings(ctx *context.Context) {
 	ctx.HTML(http.StatusOK, tplSettingsOptions)
@@ -435,188 +631,6 @@ func SettingsPost(ctx *context.Context) {
 		ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 		ctx.Redirect(repo.Link() + "/settings")
 
-	case "advanced":
-		var repoChanged bool
-		var units []repo_model.RepoUnit
-		var deleteUnitTypes []unit_model.Type
-
-		// This section doesn't require repo_name/RepoName to be set in the form, don't show it
-		// as an error on the UI for this action
-		ctx.Data["Err_RepoName"] = nil
-
-		if repo.CloseIssuesViaCommitInAnyBranch != form.EnableCloseIssuesViaCommitInAnyBranch {
-			repo.CloseIssuesViaCommitInAnyBranch = form.EnableCloseIssuesViaCommitInAnyBranch
-			repoChanged = true
-		}
-
-		if form.EnableCode && !unit_model.TypeCode.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeCode,
-			})
-		} else if !unit_model.TypeCode.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeCode)
-		}
-
-		if form.EnableWiki && form.EnableExternalWiki && !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
-			if !validation.IsValidExternalURL(form.ExternalWikiURL) {
-				ctx.Flash.Error(ctx.Tr("repo.settings.external_wiki_url_error"))
-				ctx.Redirect(repo.Link() + "/settings")
-				return
-			}
-
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeExternalWiki,
-				Config: &repo_model.ExternalWikiConfig{
-					ExternalWikiURL: form.ExternalWikiURL,
-				},
-			})
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
-		} else if form.EnableWiki && !form.EnableExternalWiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
-			var wikiPermissions repo_model.UnitAccessMode
-			if form.GloballyWriteableWiki {
-				wikiPermissions = repo_model.UnitAccessModeWrite
-			} else {
-				wikiPermissions = repo_model.UnitAccessModeRead
-			}
-			units = append(units, repo_model.RepoUnit{
-				RepoID:             repo.ID,
-				Type:               unit_model.TypeWiki,
-				Config:             new(repo_model.UnitConfig),
-				DefaultPermissions: wikiPermissions,
-			})
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
-		} else {
-			if !unit_model.TypeExternalWiki.UnitGlobalDisabled() {
-				deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki)
-			}
-			if !unit_model.TypeWiki.UnitGlobalDisabled() {
-				deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki)
-			}
-		}
-
-		if form.EnableIssues && form.EnableExternalTracker && !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
-			if !validation.IsValidExternalURL(form.ExternalTrackerURL) {
-				ctx.Flash.Error(ctx.Tr("repo.settings.external_tracker_url_error"))
-				ctx.Redirect(repo.Link() + "/settings")
-				return
-			}
-			if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(form.TrackerURLFormat) {
-				ctx.Flash.Error(ctx.Tr("repo.settings.tracker_url_format_error"))
-				ctx.Redirect(repo.Link() + "/settings")
-				return
-			}
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeExternalTracker,
-				Config: &repo_model.ExternalTrackerConfig{
-					ExternalTrackerURL:           form.ExternalTrackerURL,
-					ExternalTrackerFormat:        form.TrackerURLFormat,
-					ExternalTrackerStyle:         form.TrackerIssueStyle,
-					ExternalTrackerRegexpPattern: form.ExternalTrackerRegexpPattern,
-				},
-			})
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
-		} else if form.EnableIssues && !form.EnableExternalTracker && !unit_model.TypeIssues.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeIssues,
-				Config: &repo_model.IssuesConfig{
-					EnableTimetracker:                form.EnableTimetracker,
-					AllowOnlyContributorsToTrackTime: form.AllowOnlyContributorsToTrackTime,
-					EnableDependencies:               form.EnableIssueDependencies,
-				},
-			})
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
-		} else {
-			if !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
-				deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker)
-			}
-			if !unit_model.TypeIssues.UnitGlobalDisabled() {
-				deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues)
-			}
-		}
-
-		if form.EnableProjects && !unit_model.TypeProjects.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeProjects,
-			})
-		} else if !unit_model.TypeProjects.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeProjects)
-		}
-
-		if form.EnableReleases && !unit_model.TypeReleases.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeReleases,
-			})
-		} else if !unit_model.TypeReleases.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeReleases)
-		}
-
-		if form.EnablePackages && !unit_model.TypePackages.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypePackages,
-			})
-		} else if !unit_model.TypePackages.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePackages)
-		}
-
-		if form.EnableActions && !unit_model.TypeActions.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypeActions,
-			})
-		} else if !unit_model.TypeActions.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeActions)
-		}
-
-		if form.EnablePulls && !unit_model.TypePullRequests.UnitGlobalDisabled() {
-			units = append(units, repo_model.RepoUnit{
-				RepoID: repo.ID,
-				Type:   unit_model.TypePullRequests,
-				Config: &repo_model.PullRequestsConfig{
-					IgnoreWhitespaceConflicts:     form.PullsIgnoreWhitespace,
-					AllowMerge:                    form.PullsAllowMerge,
-					AllowRebase:                   form.PullsAllowRebase,
-					AllowRebaseMerge:              form.PullsAllowRebaseMerge,
-					AllowSquash:                   form.PullsAllowSquash,
-					AllowManualMerge:              form.PullsAllowManualMerge,
-					AutodetectManualMerge:         form.EnableAutodetectManualMerge,
-					AllowRebaseUpdate:             form.PullsAllowRebaseUpdate,
-					DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
-					DefaultMergeStyle:             repo_model.MergeStyle(form.PullsDefaultMergeStyle),
-					DefaultAllowMaintainerEdit:    form.DefaultAllowMaintainerEdit,
-				},
-			})
-		} else if !unit_model.TypePullRequests.UnitGlobalDisabled() {
-			deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests)
-		}
-
-		if len(units) == 0 {
-			ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit"))
-			ctx.Redirect(ctx.Repo.RepoLink + "/settings")
-			return
-		}
-
-		if err := repo_model.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
-			ctx.ServerError("UpdateRepositoryUnits", err)
-			return
-		}
-		if repoChanged {
-			if err := repo_service.UpdateRepository(ctx, repo, false); err != nil {
-				ctx.ServerError("UpdateRepository", err)
-				return
-			}
-		}
-		log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
-
-		ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
-		ctx.Redirect(ctx.Repo.RepoLink + "/settings")
-
 	case "signing":
 		changed := false
 		trustModel := repo_model.ToTrustModel(form.TrustModel)
diff --git a/routers/web/web.go b/routers/web/web.go
index 1a83b86fa1..23980d522d 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1034,6 +1034,8 @@ func registerRoutes(m *web.Route) {
 				m.Combo("").Get(repo_setting.Settings).
 					Post(web.Bind(forms.RepoSettingForm{}), repo_setting.SettingsPost)
 			}, repo_setting.SettingsCtxData)
+			m.Combo("/units").Get(repo_setting.Units).
+				Post(web.Bind(forms.RepoUnitSettingForm{}), repo_setting.UnitsPost)
 			m.Post("/avatar", web.Bind(forms.AvatarForm{}), repo_setting.SettingsAvatar)
 			m.Post("/avatar/delete", repo_setting.SettingsDeleteAvatar)
 
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 7cc07532ef..9527916ae0 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -130,6 +130,24 @@ type RepoSettingForm struct {
 	EnablePrune            bool
 
 	// Advanced settings
+	IsArchived bool
+
+	// Signing Settings
+	TrustModel string
+
+	// Admin settings
+	EnableHealthCheck  bool
+	RequestReindexType string
+}
+
+// Validate validates the fields
+func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
+	ctx := context.GetValidateContext(req)
+	return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
+}
+
+// RepoUnitSettingForm form for changing repository unit settings
+type RepoUnitSettingForm struct {
 	EnableCode                            bool
 	EnableWiki                            bool
 	GloballyWriteableWiki                 bool
@@ -161,18 +179,10 @@ type RepoSettingForm struct {
 	EnableTimetracker                     bool
 	AllowOnlyContributorsToTrackTime      bool
 	EnableIssueDependencies               bool
-	IsArchived                            bool
-
-	// Signing Settings
-	TrustModel string
-
-	// Admin settings
-	EnableHealthCheck  bool
-	RequestReindexType string
 }
 
 // Validate validates the fields
-func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
+func (f *RepoUnitSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
 	ctx := context.GetValidateContext(req)
 	return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
 }
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index 3e29f1f29e..6fe0b39b52 100644
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -219,6 +219,11 @@
 				{{end}}
 
 				{{if .Permission.IsAdmin}}
+					{{if not .AllUnitsEnabled}}
+						<a class="{{if .PageIsRepoSettingsUnits}}active {{end}}item" href="{{.RepoLink}}/settings/units">
+							{{svg "octicon-diff-added"}} {{ctx.Locale.Tr "repo.settings.units.add_more"}}
+						</a>
+					{{end}}
 					<a class="{{if .PageIsRepoSettings}}active {{end}} item" href="{{.RepoLink}}/settings">
 						{{svg "octicon-tools"}} {{ctx.Locale.Tr "repo.settings"}}
 					</a>
diff --git a/templates/repo/settings/navbar.tmpl b/templates/repo/settings/navbar.tmpl
index 3bef0fa4c1..62f81a901e 100644
--- a/templates/repo/settings/navbar.tmpl
+++ b/templates/repo/settings/navbar.tmpl
@@ -4,6 +4,23 @@
 		<a class="{{if .PageIsSettingsOptions}}active {{end}}item" href="{{.RepoLink}}/settings">
 			{{ctx.Locale.Tr "repo.settings.options"}}
 		</a>
+		<details class="item toggleable-item" {{if .PageIsRepoSettingsUnits}}open{{end}}>
+			<summary class="item{{if .PageIsRepoSettingsUnits}} active{{end}}">{{ctx.Locale.Tr "repo.settings.units.units"}}</summary>
+			<div class="menu">
+				<a class="item" href="{{.RepoLink}}/settings/units#overview">
+					{{ctx.Locale.Tr "repo.settings.units.overview"}}
+				</a>
+				<a class="item" href="{{.RepoLink}}/settings/units#issues">
+					{{ctx.Locale.Tr "repo.issues"}}
+				</a>
+				<a class="item" href="{{.RepoLink}}/settings/units#pulls">
+					{{ctx.Locale.Tr "repo.pulls"}}
+				</a>
+				<a class="item" href="{{.RepoLink}}/settings/units#wiki">
+					{{ctx.Locale.Tr "repo.wiki"}}
+				</a>
+			</div>
+		</details>
 		<a class="{{if .PageIsSettingsCollaboration}}active {{end}}item" href="{{.RepoLink}}/settings/collaboration">
 			{{ctx.Locale.Tr "repo.settings.collaboration"}}
 		</a>
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index 191ac53967..6cfef31060 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -299,325 +299,6 @@
 			</div>
 		{{end}}
 
-		<h4 class="ui top attached header">
-			{{ctx.Locale.Tr "repo.settings.advanced_settings"}}
-		</h4>
-		<div class="ui attached segment">
-			<form class="ui form" method="post">
-				{{.CsrfTokenHtml}}
-				<input type="hidden" name="action" value="advanced">
-
-				{{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}}
-				{{$isCodeGlobalDisabled := .UnitTypeCode.UnitGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.code"}}</label>
-					<div class="ui checkbox{{if $isCodeGlobalDisabled}} disabled{{end}}"{{if $isCodeGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_code" type="checkbox"{{if $isCodeEnabled}} checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.code.desc"}}</label>
-					</div>
-				</div>
-
-				{{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
-				{{$isWikiGlobalDisabled := .UnitTypeWiki.UnitGlobalDisabled}}
-				{{$isExternalWikiGlobalDisabled := .UnitTypeExternalWiki.UnitGlobalDisabled}}
-				{{$isBothWikiGlobalDisabled := and $isWikiGlobalDisabled $isExternalWikiGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.wiki"}}</label>
-					<div class="ui checkbox{{if $isBothWikiGlobalDisabled}} disabled{{end}}"{{if $isBothWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_wiki" type="checkbox" data-target="#wiki_box" {{if $isWikiEnabled}}checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.settings.wiki_desc"}}</label>
-					</div>
-				</div>
-				<div class="field{{if not $isWikiEnabled}} disabled{{end}}" id="wiki_box">
-					<div class="field">
-						<div class="ui radio checkbox{{if $isWikiGlobalDisabled}} disabled{{end}}"{{if $isWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
-						</div>
-					</div>
-					{{if (not .Repository.IsPrivate)}}
-					<div class="field {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}">
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="globally_writeable_wiki" type="checkbox" {{if .Permission.IsGloballyWriteable $.UnitTypeWiki}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.wiki_globally_editable"}}</label>
-							</div>
-						</div>
-					</div>
-					{{end}}
-					<div class="field">
-						<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.use_external_wiki"}}</label>
-						</div>
-					</div>
-					<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}" id="external_wiki_box">
-						<label for="external_wiki_url">{{ctx.Locale.Tr "repo.settings.external_wiki_url"}}</label>
-						<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
-						<p class="help">{{ctx.Locale.Tr "repo.settings.external_wiki_url_desc"}}</p>
-					</div>
-				</div>
-
-				<div class="divider"></div>
-
-				{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeIssues) (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}
-				{{$isIssuesGlobalDisabled := .UnitTypeIssues.UnitGlobalDisabled}}
-				{{$isExternalTrackerGlobalDisabled := .UnitTypeExternalTracker.UnitGlobalDisabled}}
-				{{$isIssuesAndExternalGlobalDisabled := and $isIssuesGlobalDisabled $isExternalTrackerGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.issues"}}</label>
-					<div class="ui checkbox{{if $isIssuesAndExternalGlobalDisabled}} disabled{{end}}"{{if $isIssuesAndExternalGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_issues" type="checkbox" data-target="#issue_box" {{if $isIssuesEnabled}}checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.settings.issues_desc"}}</label>
-					</div>
-				</div>
-				<div class="field {{if not $isIssuesEnabled}}disabled{{end}}" id="issue_box">
-					<div class="field">
-						<div class="ui radio checkbox{{if $isIssuesGlobalDisabled}} disabled{{end}}"{{if $isIssuesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.use_internal_issue_tracker"}}</label>
-						</div>
-					</div>
-					<div class="field gt-pl-4 {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
-						{{if .Repository.CanEnableTimetracker}}
-							<div class="field">
-								<div class="ui checkbox">
-									<input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled $.Context}}checked{{end}}>
-									<label>{{ctx.Locale.Tr "repo.settings.enable_timetracker"}}</label>
-								</div>
-							</div>
-							<div class="field {{if not (.Repository.IsTimetrackerEnabled $.Context)}}disabled{{end}}" id="only_contributors">
-								<div class="ui checkbox">
-									<input name="allow_only_contributors_to_track_time" type="checkbox" {{if .Repository.AllowOnlyContributorsToTrackTime $.Context}}checked{{end}}>
-									<label>{{ctx.Locale.Tr "repo.settings.allow_only_contributors_to_track_time"}}</label>
-								</div>
-							</div>
-						{{end}}
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="enable_issue_dependencies" type="checkbox" {{if (.Repository.IsDependenciesEnabled $.Context)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.issues.dependency.setting"}}</label>
-							</div>
-						</div>
-						<div class="ui checkbox">
-							<input name="enable_close_issues_via_commit_in_any_branch" type="checkbox" {{if .Repository.CloseIssuesViaCommitInAnyBranch}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.admin_enable_close_issues_via_commit_in_any_branch"}}</label>
-						</div>
-					</div>
-					<div class="field">
-						<div class="ui radio checkbox{{if $isExternalTrackerGlobalDisabled}} disabled{{end}}"{{if $isExternalTrackerGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalTracker}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.use_external_issue_tracker"}}</label>
-						</div>
-					</div>
-					<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
-						<div class="field">
-							<label for="external_tracker_url">{{ctx.Locale.Tr "repo.settings.external_tracker_url"}}</label>
-							<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
-							<p class="help">{{ctx.Locale.Tr "repo.settings.external_tracker_url_desc"}}</p>
-						</div>
-						<div class="field">
-							<label for="tracker_url_format">{{ctx.Locale.Tr "repo.settings.tracker_url_format"}}</label>
-							<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
-							<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
-						</div>
-						<div class="inline fields">
-							<label for="issue_style">{{ctx.Locale.Tr "repo.settings.tracker_issue_style"}}</label>
-							<div class="field">
-								<div class="ui radio checkbox">
-								{{$externalTracker := (.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker)}}
-								{{$externalTrackerStyle := $externalTracker.ExternalTrackerConfig.ExternalTrackerStyle}}
-									<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="numeric" {{if eq $externalTrackerStyle "numeric"}}checked{{end}}>
-									<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.numeric"}} <span class="ui light grey text">#1234</span></label>
-								</div>
-							</div>
-							<div class="field">
-								<div class="ui radio checkbox">
-									<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="alphanumeric" {{if eq $externalTrackerStyle "alphanumeric"}}checked{{end}}>
-									<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.alphanumeric"}} <span class="ui light grey text">ABC-123 , DEFG-234</span></label>
-								</div>
-							</div>
-							<div class="field">
-								<div class="ui radio checkbox">
-									<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="regexp" {{if eq $externalTrackerStyle "regexp"}}checked{{end}}>
-									<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp"}} <span class="ui light grey text">(ISSUE-\d+) , ISSUE-(\d+)</span></label>
-								</div>
-							</div>
-						</div>
-						<div class="field {{if ne $externalTrackerStyle "regexp"}}disabled{{end}}" id="tracker-issue-style-regex-box">
-							<label for="external_tracker_regexp_pattern">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern"}}</label>
-							<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
-							<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern_desc" | Str2html}}</p>
-						</div>
-					</div>
-				</div>
-
-				<div class="divider"></div>
-
-				{{$isProjectsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeProjects}}
-				{{$isProjectsGlobalDisabled := .UnitTypeProjects.UnitGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.project_board"}}</label>
-					<div class="ui checkbox{{if $isProjectsGlobalDisabled}} disabled{{end}}"{{if $isProjectsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_projects" type="checkbox" {{if $isProjectsEnabled}}checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.settings.projects_desc"}}</label>
-					</div>
-				</div>
-
-				{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
-				{{$isReleasesGlobalDisabled := .UnitTypeReleases.UnitGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.releases"}}</label>
-					<div class="ui checkbox{{if $isReleasesGlobalDisabled}} disabled{{end}}"{{if $isReleasesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_releases" type="checkbox" {{if $isReleasesEnabled}}checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.settings.releases_desc"}}</label>
-					</div>
-				</div>
-
-				{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
-				{{$isPackagesGlobalDisabled := .UnitTypePackages.UnitGlobalDisabled}}
-				<div class="inline field">
-					<label>{{ctx.Locale.Tr "repo.packages"}}</label>
-					<div class="ui checkbox{{if $isPackagesGlobalDisabled}} disabled{{end}}"{{if $isPackagesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-						<input class="enable-system" name="enable_packages" type="checkbox" {{if $isPackagesEnabled}}checked{{end}}>
-						<label>{{ctx.Locale.Tr "repo.settings.packages_desc"}}</label>
-					</div>
-				</div>
-
-				{{if .EnableActions}}
-					{{$isActionsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeActions}}
-					{{$isActionsGlobalDisabled := .UnitTypeActions.UnitGlobalDisabled}}
-					<div class="inline field">
-						<label>{{ctx.Locale.Tr "actions.actions"}}</label>
-							<div class="ui checkbox{{if $isActionsGlobalDisabled}} disabled{{end}}"{{if $isActionsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system" name="enable_actions" type="checkbox" {{if $isActionsEnabled}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.actions_desc"}}</label>
-						</div>
-					</div>
-				{{end}}
-
-				{{if not .IsMirror}}
-					<div class="divider"></div>
-					{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
-					{{$pullRequestGlobalDisabled := .UnitTypePullRequests.UnitGlobalDisabled}}
-					{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
-					<div class="inline field">
-						<label>{{ctx.Locale.Tr "repo.pulls"}}</label>
-						<div class="ui checkbox{{if $pullRequestGlobalDisabled}} disabled{{end}}"{{if $pullRequestGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
-							<input class="enable-system" name="enable_pulls" type="checkbox" data-target="#pull_box" {{if $pullRequestEnabled}}checked{{end}}>
-							<label>{{ctx.Locale.Tr "repo.settings.pulls_desc"}}</label>
-						</div>
-					</div>
-					<div class="field{{if not $pullRequestEnabled}} disabled{{end}}" id="pull_box">
-						<div class="field">
-							<p>
-								{{ctx.Locale.Tr "repo.settings.merge_style_desc"}}
-							</p>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowMerge)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_rebase" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebase)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_rebase_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseMerge)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_squash" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowSquash)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowManualMerge)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.pulls.merge_manually"}}</label>
-							</div>
-						</div>
-
-						<div class="field">
-							<p>
-								{{ctx.Locale.Tr "repo.settings.default_merge_style_desc"}}
-							</p>
-							<div class="ui dropdown selection">
-								<select name="pulls_default_merge_style">
-									<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</option>
-									<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</option>
-									<option value="rebase-merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</option>
-									<option value="squash" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</option>
-								</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
-								<div class="default text">
-									{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}
-										{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}
-									{{end}}
-									{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}
-										{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}
-									{{end}}
-									{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}
-										{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
-									{{end}}
-									{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}
-										{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}
-									{{end}}
-								</div>
-								<div class="menu">
-									<div class="item" data-value="merge">{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</div>
-									<div class="item" data-value="rebase">{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
-									<div class="item" data-value="rebase-merge">{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
-									<div class="item" data-value="squash">{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</div>
-								</div>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="default_allow_maintainer_edit" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultAllowMaintainerEdit)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.pulls.default_allow_edits_from_maintainers"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_allow_rebase_update" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseUpdate)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.pulls.default_delete_branch_after_merge"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="enable_autodetect_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AutodetectManualMerge)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
-							</div>
-						</div>
-						<div class="field">
-							<div class="ui checkbox">
-								<input name="pulls_ignore_whitespace" type="checkbox" {{if and $pullRequestEnabled ($prUnit.PullRequestsConfig.IgnoreWhitespaceConflicts)}}checked{{end}}>
-								<label>{{ctx.Locale.Tr "repo.settings.pulls.ignore_whitespace"}}</label>
-							</div>
-						</div>
-					</div>
-				{{end}}
-
-				<div class="divider"></div>
-				<div class="field">
-					<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
-				</div>
-			</form>
-		</div>
-
 		<h4 class="ui top attached header">
 			{{ctx.Locale.Tr "repo.settings.signing_settings"}}
 		</h4>
diff --git a/templates/repo/settings/units.tmpl b/templates/repo/settings/units.tmpl
new file mode 100644
index 0000000000..66ed035964
--- /dev/null
+++ b/templates/repo/settings/units.tmpl
@@ -0,0 +1,13 @@
+{{template "repo/settings/layout_head" (dict "ctxData" . "pageClass" "repository settings options")}}
+<div class="user-main-content twelve wide column">
+	<form class="ui form" method="post" action="{{.RepoLink}}/settings/units">
+		{{.CsrfTokenHtml}}
+		{{template "repo/settings/units/overview" .}}
+		{{template "repo/settings/units/issues" .}}
+		{{if not .IsMirror}}
+			{{template "repo/settings/units/pulls" .}}
+		{{end}}
+		{{template "repo/settings/units/wiki" .}}
+	</form>
+</div>
+{{template "repo/settings/layout_footer" .}}
diff --git a/templates/repo/settings/units/issues.tmpl b/templates/repo/settings/units/issues.tmpl
new file mode 100644
index 0000000000..a09b8edb2e
--- /dev/null
+++ b/templates/repo/settings/units/issues.tmpl
@@ -0,0 +1,102 @@
+<h4 class="ui top attached header" id="issues">
+	{{ctx.Locale.Tr "repo.issues"}}
+</h4>
+<div class="ui attached segment">
+	{{$isIssuesEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeIssues) (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}
+	{{$isIssuesGlobalDisabled := .UnitTypeIssues.UnitGlobalDisabled}}
+	{{$isExternalTrackerGlobalDisabled := .UnitTypeExternalTracker.UnitGlobalDisabled}}
+	{{$isIssuesAndExternalGlobalDisabled := and $isIssuesGlobalDisabled $isExternalTrackerGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.issues"}}</label>
+		<div class="ui checkbox{{if $isIssuesAndExternalGlobalDisabled}} disabled{{end}}"{{if $isIssuesAndExternalGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_issues" type="checkbox" data-target="#issue_box" {{if $isIssuesEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.issues_desc"}}</label>
+		</div>
+	</div>
+	<div class="field {{if not $isIssuesEnabled}}disabled{{end}}" id="issue_box">
+		<div class="field">
+			<div class="ui radio checkbox{{if $isIssuesGlobalDisabled}} disabled{{end}}"{{if $isIssuesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+				<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="false" data-context="#internal_issue_box" data-target="#external_issue_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.use_internal_issue_tracker"}}</label>
+			</div>
+		</div>
+		<div class="field gt-pl-4 {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="internal_issue_box">
+			{{if .Repository.CanEnableTimetracker}}
+				<div class="field">
+					<div class="ui checkbox">
+						<input name="enable_timetracker" class="enable-system" data-target="#only_contributors" type="checkbox" {{if .Repository.IsTimetrackerEnabled $.Context}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.enable_timetracker"}}</label>
+					</div>
+				</div>
+				<div class="field {{if not (.Repository.IsTimetrackerEnabled $.Context)}}disabled{{end}}" id="only_contributors">
+					<div class="ui checkbox">
+						<input name="allow_only_contributors_to_track_time" type="checkbox" {{if .Repository.AllowOnlyContributorsToTrackTime $.Context}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.allow_only_contributors_to_track_time"}}</label>
+					</div>
+				</div>
+			{{end}}
+			<div class="field">
+				<div class="ui checkbox">
+					<input name="enable_issue_dependencies" type="checkbox" {{if (.Repository.IsDependenciesEnabled $.Context)}}checked{{end}}>
+					<label>{{ctx.Locale.Tr "repo.issues.dependency.setting"}}</label>
+				</div>
+			</div>
+			<div class="ui checkbox">
+				<input name="enable_close_issues_via_commit_in_any_branch" type="checkbox" {{if .Repository.CloseIssuesViaCommitInAnyBranch}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.admin_enable_close_issues_via_commit_in_any_branch"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui radio checkbox{{if $isExternalTrackerGlobalDisabled}} disabled{{end}}"{{if $isExternalTrackerGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+				<input class="enable-system-radio" name="enable_external_tracker" type="radio" value="true" data-context="#internal_issue_box" data-target="#external_issue_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalTracker}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.use_external_issue_tracker"}}</label>
+			</div>
+		</div>
+		<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalTracker)}}disabled{{end}}" id="external_issue_box">
+			<div class="field">
+				<label for="external_tracker_url">{{ctx.Locale.Tr "repo.settings.external_tracker_url"}}</label>
+				<input id="external_tracker_url" name="external_tracker_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerURL}}">
+				<p class="help">{{ctx.Locale.Tr "repo.settings.external_tracker_url_desc"}}</p>
+			</div>
+			<div class="field">
+				<label for="tracker_url_format">{{ctx.Locale.Tr "repo.settings.tracker_url_format"}}</label>
+				<input id="tracker_url_format" name="tracker_url_format" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerFormat}}" placeholder="https://github.com/{user}/{repo}/issues/{index}">
+				<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
+			</div>
+			<div class="inline fields">
+				<label for="issue_style">{{ctx.Locale.Tr "repo.settings.tracker_issue_style"}}</label>
+				<div class="field">
+					<div class="ui radio checkbox">
+						{{$externalTracker := (.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker)}}
+						{{$externalTrackerStyle := $externalTracker.ExternalTrackerConfig.ExternalTrackerStyle}}
+						<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="numeric" {{if eq $externalTrackerStyle "numeric"}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.numeric"}} <span class="ui light grey text">#1234</span></label>
+					</div>
+				</div>
+				<div class="field">
+					<div class="ui radio checkbox">
+						<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="alphanumeric" {{if eq $externalTrackerStyle "alphanumeric"}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.alphanumeric"}} <span class="ui light grey text">ABC-123 , DEFG-234</span></label>
+					</div>
+				</div>
+				<div class="field">
+					<div class="ui radio checkbox">
+						<input class="js-tracker-issue-style" name="tracker_issue_style" type="radio" value="regexp" {{if eq $externalTrackerStyle "regexp"}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp"}} <span class="ui light grey text">(ISSUE-\d+) , ISSUE-(\d+)</span></label>
+					</div>
+				</div>
+			</div>
+			<div class="field {{if ne $externalTrackerStyle "regexp"}}disabled{{end}}" id="tracker-issue-style-regex-box">
+				<label for="external_tracker_regexp_pattern">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern"}}</label>
+				<input id="external_tracker_regexp_pattern" name="external_tracker_regexp_pattern" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalTracker).ExternalTrackerConfig.ExternalTrackerRegexpPattern}}">
+				<p class="help">{{ctx.Locale.Tr "repo.settings.tracker_issue_style.regexp_pattern_desc" | Str2html}}</p>
+			</div>
+		</div>
+	</div>
+
+	<div class="divider"></div>
+
+	<div class="field">
+		<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
+	</div>
+</div>
diff --git a/templates/repo/settings/units/overview.tmpl b/templates/repo/settings/units/overview.tmpl
new file mode 100644
index 0000000000..816b45ce1d
--- /dev/null
+++ b/templates/repo/settings/units/overview.tmpl
@@ -0,0 +1,62 @@
+<h4 class="ui top attached header" id="overview">
+	{{ctx.Locale.Tr "repo.settings.units.overview"}}
+</h4>
+<div class="ui attached segment">
+	{{$isCodeEnabled := .Repository.UnitEnabled $.Context $.UnitTypeCode}}
+	{{$isCodeGlobalDisabled := .UnitTypeCode.UnitGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.code"}}</label>
+		<div class="ui checkbox{{if $isCodeGlobalDisabled}} disabled{{end}}"{{if $isCodeGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_code" type="checkbox"{{if $isCodeEnabled}} checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.code.desc"}}</label>
+		</div>
+	</div>
+
+	{{$isProjectsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeProjects}}
+	{{$isProjectsGlobalDisabled := .UnitTypeProjects.UnitGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.project_board"}}</label>
+		<div class="ui checkbox{{if $isProjectsGlobalDisabled}} disabled{{end}}"{{if $isProjectsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_projects" type="checkbox" {{if $isProjectsEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.projects_desc"}}</label>
+		</div>
+	</div>
+
+	{{$isReleasesEnabled := .Repository.UnitEnabled $.Context $.UnitTypeReleases}}
+	{{$isReleasesGlobalDisabled := .UnitTypeReleases.UnitGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.releases"}}</label>
+		<div class="ui checkbox{{if $isReleasesGlobalDisabled}} disabled{{end}}"{{if $isReleasesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_releases" type="checkbox" {{if $isReleasesEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.releases_desc"}}</label>
+		</div>
+	</div>
+
+	{{$isPackagesEnabled := .Repository.UnitEnabled $.Context $.UnitTypePackages}}
+	{{$isPackagesGlobalDisabled := .UnitTypePackages.UnitGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.packages"}}</label>
+		<div class="ui checkbox{{if $isPackagesGlobalDisabled}} disabled{{end}}"{{if $isPackagesGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_packages" type="checkbox" {{if $isPackagesEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.packages_desc"}}</label>
+		</div>
+	</div>
+
+	{{if .EnableActions}}
+		{{$isActionsEnabled := .Repository.UnitEnabled $.Context $.UnitTypeActions}}
+		{{$isActionsGlobalDisabled := .UnitTypeActions.UnitGlobalDisabled}}
+		<div class="inline field">
+			<label>{{ctx.Locale.Tr "actions.actions"}}</label>
+			<div class="ui checkbox{{if $isActionsGlobalDisabled}} disabled{{end}}"{{if $isActionsGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+				<input class="enable-system" name="enable_actions" type="checkbox" {{if $isActionsEnabled}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.actions_desc"}}</label>
+			</div>
+		</div>
+	{{end}}
+
+	<div class="divider"></div>
+
+	<div class="field">
+		<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
+	</div>
+</div>
diff --git a/templates/repo/settings/units/pulls.tmpl b/templates/repo/settings/units/pulls.tmpl
new file mode 100644
index 0000000000..e735fe974c
--- /dev/null
+++ b/templates/repo/settings/units/pulls.tmpl
@@ -0,0 +1,121 @@
+<h4 class="ui top attached header" id="pulls">
+	{{ctx.Locale.Tr "repo.pulls"}}
+</h4>
+<div class="ui attached segment">
+	{{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}}
+	{{$pullRequestGlobalDisabled := .UnitTypePullRequests.UnitGlobalDisabled}}
+	{{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.pulls"}}</label>
+		<div class="ui checkbox{{if $pullRequestGlobalDisabled}} disabled{{end}}"{{if $pullRequestGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_pulls" type="checkbox" data-target="#pull_box" {{if $pullRequestEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.pulls_desc"}}</label>
+		</div>
+	</div>
+	<div class="field{{if not $pullRequestEnabled}} disabled{{end}}" id="pull_box">
+		<div class="field">
+			<p>
+				{{ctx.Locale.Tr "repo.settings.merge_style_desc"}}
+			</p>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowMerge)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_rebase" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebase)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_rebase_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseMerge)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_squash" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowSquash)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowManualMerge)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.pulls.merge_manually"}}</label>
+			</div>
+		</div>
+
+		<div class="field">
+			<p>
+				{{ctx.Locale.Tr "repo.settings.default_merge_style_desc"}}
+			</p>
+			<div class="ui dropdown selection">
+				<select name="pulls_default_merge_style">
+					<option value="merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</option>
+					<option value="rebase" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</option>
+					<option value="rebase-merge" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</option>
+					<option value="squash" {{if or (not $pullRequestEnabled) (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}selected{{end}}>{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</option>
+				</select>{{svg "octicon-triangle-down" 14 "dropdown icon"}}
+				<div class="default text">
+					{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "merge")}}
+						{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}
+					{{end}}
+					{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase")}}
+						{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}
+					{{end}}
+					{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "rebase-merge")}}
+						{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}
+					{{end}}
+					{{if (eq $prUnit.PullRequestsConfig.DefaultMergeStyle "squash")}}
+						{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}
+					{{end}}
+				</div>
+				<div class="menu">
+					<div class="item" data-value="merge">{{ctx.Locale.Tr "repo.pulls.merge_pull_request"}}</div>
+					<div class="item" data-value="rebase">{{ctx.Locale.Tr "repo.pulls.rebase_merge_pull_request"}}</div>
+					<div class="item" data-value="rebase-merge">{{ctx.Locale.Tr "repo.pulls.rebase_merge_commit_pull_request"}}</div>
+					<div class="item" data-value="squash">{{ctx.Locale.Tr "repo.pulls.squash_merge_pull_request"}}</div>
+				</div>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="default_allow_maintainer_edit" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultAllowMaintainerEdit)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.pulls.default_allow_edits_from_maintainers"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_allow_rebase_update" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseUpdate)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.pulls.default_delete_branch_after_merge"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="enable_autodetect_manual_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AutodetectManualMerge)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
+			</div>
+		</div>
+		<div class="field">
+			<div class="ui checkbox">
+				<input name="pulls_ignore_whitespace" type="checkbox" {{if and $pullRequestEnabled ($prUnit.PullRequestsConfig.IgnoreWhitespaceConflicts)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.pulls.ignore_whitespace"}}</label>
+			</div>
+		</div>
+	</div>
+
+	<div class="divider"></div>
+	<div class="field">
+		<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
+	</div>
+</div>
diff --git a/templates/repo/settings/units/wiki.tmpl b/templates/repo/settings/units/wiki.tmpl
new file mode 100644
index 0000000000..c3be39f1cc
--- /dev/null
+++ b/templates/repo/settings/units/wiki.tmpl
@@ -0,0 +1,51 @@
+<h4 class="ui top attached header" id="wiki">
+	{{ctx.Locale.Tr "repo.wiki"}}
+</h4>
+<div class="ui attached segment">
+	{{$isWikiEnabled := or (.Repository.UnitEnabled $.Context $.UnitTypeWiki) (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}
+	{{$isWikiGlobalDisabled := .UnitTypeWiki.UnitGlobalDisabled}}
+	{{$isExternalWikiGlobalDisabled := .UnitTypeExternalWiki.UnitGlobalDisabled}}
+	{{$isBothWikiGlobalDisabled := and $isWikiGlobalDisabled $isExternalWikiGlobalDisabled}}
+	<div class="inline field">
+		<label>{{ctx.Locale.Tr "repo.wiki"}}</label>
+		<div class="ui checkbox{{if $isBothWikiGlobalDisabled}} disabled{{end}}"{{if $isBothWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+			<input class="enable-system" name="enable_wiki" type="checkbox" data-target="#wiki_box" {{if $isWikiEnabled}}checked{{end}}>
+			<label>{{ctx.Locale.Tr "repo.settings.wiki_desc"}}</label>
+		</div>
+	</div>
+	<div class="field{{if not $isWikiEnabled}} disabled{{end}}" id="wiki_box">
+		<div class="field">
+			<div class="ui radio checkbox{{if $isWikiGlobalDisabled}} disabled{{end}}"{{if $isWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+				<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="false" data-target="#external_wiki_box" {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
+			</div>
+		</div>
+		{{if (not .Repository.IsPrivate)}}
+			<div class="field {{if (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}">
+				<div class="field">
+					<div class="ui checkbox">
+						<input name="globally_writeable_wiki" type="checkbox" {{if .Permission.IsGloballyWriteable $.UnitTypeWiki}}checked{{end}}>
+						<label>{{ctx.Locale.Tr "repo.settings.wiki_globally_editable"}}</label>
+					</div>
+				</div>
+			</div>
+		{{end}}
+		<div class="field">
+			<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
+				<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
+				<label>{{ctx.Locale.Tr "repo.settings.use_external_wiki"}}</label>
+			</div>
+		</div>
+		<div class="field gt-pl-4 {{if not (.Repository.UnitEnabled $.Context $.UnitTypeExternalWiki)}}disabled{{end}}" id="external_wiki_box">
+			<label for="external_wiki_url">{{ctx.Locale.Tr "repo.settings.external_wiki_url"}}</label>
+			<input id="external_wiki_url" name="external_wiki_url" type="url" value="{{(.Repository.MustGetUnit $.Context $.UnitTypeExternalWiki).ExternalWikiConfig.ExternalWikiURL}}">
+			<p class="help">{{ctx.Locale.Tr "repo.settings.external_wiki_url_desc"}}</p>
+		</div>
+	</div>
+
+	<div class="divider"></div>
+
+	<div class="field">
+		<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.update_settings"}}</button>
+	</div>
+</div>
diff --git a/tests/integration/repo_settings_test.go b/tests/integration/repo_settings_test.go
new file mode 100644
index 0000000000..16e0bb3d7d
--- /dev/null
+++ b/tests/integration/repo_settings_test.go
@@ -0,0 +1,130 @@
+// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"code.gitea.io/gitea/models/db"
+	repo_model "code.gitea.io/gitea/models/repo"
+	unit_model "code.gitea.io/gitea/models/unit"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
+	"code.gitea.io/gitea/modules/setting"
+	repo_service "code.gitea.io/gitea/services/repository"
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRepoSettingsUnits(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
+	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: "repo1"})
+	session := loginUser(t, user.Name)
+
+	req := NewRequest(t, "GET", fmt.Sprintf("%s/settings/units", repo.Link()))
+	session.MakeRequest(t, req, http.StatusOK)
+}
+
+func TestRepoAddMoreUnits(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
+	session := loginUser(t, user.Name)
+
+	// Make sure there are no disabled repos in the settings!
+	setting.Repository.DisabledRepoUnits = []string{}
+	unit_model.LoadUnitConfig()
+
+	// Create a known-good repo, with all units enabled.
+	repo, _, f := CreateDeclarativeRepo(t, user, "", []unit_model.Type{
+		unit_model.TypeCode,
+		unit_model.TypePullRequests,
+		unit_model.TypeProjects,
+		unit_model.TypePackages,
+		unit_model.TypeActions,
+		unit_model.TypeIssues,
+		unit_model.TypeWiki,
+	}, nil, nil)
+	defer f()
+
+	assertAddMore := func(t *testing.T, present bool) {
+		t.Helper()
+
+		req := NewRequest(t, "GET", repo.Link())
+		resp := session.MakeRequest(t, req, http.StatusOK)
+		htmlDoc := NewHTMLParser(t, resp.Body)
+		htmlDoc.AssertElement(t, fmt.Sprintf("a[href='%s/settings/units']", repo.Link()), present)
+	}
+
+	t.Run("no add more with all units enabled", func(t *testing.T) {
+		defer tests.PrintCurrentTest(t)()
+
+		assertAddMore(t, false)
+	})
+
+	t.Run("add more if units can be enabled", func(t *testing.T) {
+		defer tests.PrintCurrentTest(t)()
+		defer func() {
+			repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
+				RepoID: repo.ID,
+				Type:   unit_model.TypePackages,
+			}}, nil)
+		}()
+
+		// Disable the Packages unit
+		err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypePackages})
+		assert.NoError(t, err)
+
+		assertAddMore(t, true)
+	})
+
+	t.Run("no add more if unit is globally disabled", func(t *testing.T) {
+		defer tests.PrintCurrentTest(t)()
+		defer func() {
+			repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
+				RepoID: repo.ID,
+				Type:   unit_model.TypePackages,
+			}}, nil)
+			setting.Repository.DisabledRepoUnits = []string{}
+			unit_model.LoadUnitConfig()
+		}()
+
+		// Disable the Packages unit globally
+		setting.Repository.DisabledRepoUnits = []string{"repo.packages"}
+		unit_model.LoadUnitConfig()
+
+		// Disable the Packages unit
+		err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypePackages})
+		assert.NoError(t, err)
+
+		// The "Add more" link appears no more
+		assertAddMore(t, false)
+	})
+
+	t.Run("issues & ext tracker globally disabled", func(t *testing.T) {
+		defer tests.PrintCurrentTest(t)()
+		defer func() {
+			repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, []repo_model.RepoUnit{{
+				RepoID: repo.ID,
+				Type:   unit_model.TypeIssues,
+			}}, nil)
+			setting.Repository.DisabledRepoUnits = []string{}
+			unit_model.LoadUnitConfig()
+		}()
+
+		// Disable both Issues and ExternalTracker units globally
+		setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.ext_issues"}
+		unit_model.LoadUnitConfig()
+
+		// Disable the Issues unit
+		err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, []unit_model.Type{unit_model.TypeIssues})
+		assert.NoError(t, err)
+
+		// The "Add more" link appears no more
+		assertAddMore(t, false)
+	})
+}