diff --git a/docs/content/doc/upgrade/from-gogs.en-us.md b/docs/content/doc/upgrade/from-gogs.en-us.md
index c028c57574..2d3972608b 100644
--- a/docs/content/doc/upgrade/from-gogs.en-us.md
+++ b/docs/content/doc/upgrade/from-gogs.en-us.md
@@ -70,9 +70,14 @@ There are some basic steps to follow. On a Linux system run as the Gogs user:
 
 ## Upgrading to most recent `gitea` version
 
-After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgrade to the recent `gitea` version.
-Simply download the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea)
-and replace the binary.
+After successful migration from `gogs` to `gitea 1.0.x`, it is possible to upgrade `gitea` to a modern version
+in a two steps process.
+
+Upgrade to [`gitea 1.6.4`](https://dl.gitea.io/gitea/1.6.4/) first. Download the file matching
+the destination platform from the [downloads page](https://dl.gitea.io/gitea/1.6.4/) and replace the binary.
+Run Gitea at least once and check that everything works as expected.
+
+Then repeat the procedure, but this time using the [lastest release](https://dl.gitea.io/gitea/{{< version >}}/).
 
 ## Upgrading from a more recent version of Gogs
 
diff --git a/integrations/migration-test/gitea-v1.3.3.sqlite3.sql.gz b/integrations/migration-test/gitea-v1.3.3.sqlite3.sql.gz
deleted file mode 100644
index 8375018d9f..0000000000
Binary files a/integrations/migration-test/gitea-v1.3.3.sqlite3.sql.gz and /dev/null differ
diff --git a/integrations/migration-test/gitea-v1.5.3.mssql.sql.gz b/integrations/migration-test/gitea-v1.5.3.mssql.sql.gz
deleted file mode 100644
index d916f7eaf5..0000000000
Binary files a/integrations/migration-test/gitea-v1.5.3.mssql.sql.gz and /dev/null differ
diff --git a/integrations/migration-test/gitea-v1.5.3.mysql.sql.gz b/integrations/migration-test/gitea-v1.5.3.mysql.sql.gz
deleted file mode 100644
index 643b6bab9c..0000000000
Binary files a/integrations/migration-test/gitea-v1.5.3.mysql.sql.gz and /dev/null differ
diff --git a/integrations/migration-test/gitea-v1.5.3.postgres.sql.gz b/integrations/migration-test/gitea-v1.5.3.postgres.sql.gz
deleted file mode 100644
index 2380f8dd7f..0000000000
Binary files a/integrations/migration-test/gitea-v1.5.3.postgres.sql.gz and /dev/null differ
diff --git a/integrations/migration-test/gitea-v1.5.3.sqlite3.sql.gz b/integrations/migration-test/gitea-v1.5.3.sqlite3.sql.gz
deleted file mode 100644
index f13bc68a47..0000000000
Binary files a/integrations/migration-test/gitea-v1.5.3.sqlite3.sql.gz and /dev/null differ
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 99104906be..2de2a45568 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -6,28 +6,17 @@
 package migrations
 
 import (
-	"bytes"
-	"encoding/json"
 	"fmt"
-	"io/ioutil"
-	"os"
-	"path"
-	"path/filepath"
 	"regexp"
 	"strings"
-	"time"
 
-	"code.gitea.io/gitea/modules/generate"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	gouuid "github.com/satori/go.uuid"
-	"github.com/unknwon/com"
-	ini "gopkg.in/ini.v1"
 	"xorm.io/xorm"
 )
 
-const minDBVersion = 4
+const minDBVersion = 70 // Gitea 1.5.3
 
 // Migration describes on migration from lower version to high version
 type Migration interface {
@@ -61,151 +50,31 @@ type Version struct {
 	Version int64
 }
 
-func emptyMigration(x *xorm.Engine) error {
-	return nil
-}
-
 // This is a sequence of migrations. Add new migrations to the bottom of the list.
 // If you want to "retire" a migration, remove it from the top of the list and
 // update minDBVersion accordingly
 var migrations = []Migration{
-	// v0 -> v4: before 0.6.0 -> 0.7.33
-	NewMigration("fix locale file load panic", fixLocaleFileLoadPanic),                           // V4 -> V5:v0.6.0
-	NewMigration("trim action compare URL prefix", trimCommitActionAppURLPrefix),                 // V5 -> V6:v0.6.3
-	NewMigration("generate issue-label from issue", issueToIssueLabel),                           // V6 -> V7:v0.6.4
-	NewMigration("refactor attachment table", attachmentRefactor),                                // V7 -> V8:v0.6.4
-	NewMigration("rename pull request fields", renamePullRequestFields),                          // V8 -> V9:v0.6.16
-	NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo),                           // V9 -> V10:v0.6.20
-	NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt),           // V10 -> V11:v0.8.5
-	NewMigration("convert date to unix timestamp", convertDateToUnix),                            // V11 -> V12:v0.9.2
-	NewMigration("convert LDAP UseSSL option to SecurityProtocol", ldapUseSSLToSecurityProtocol), // V12 -> V13:v0.9.37
 
-	// v13 -> v14:v0.9.87
-	NewMigration("set comment updated with created", setCommentUpdatedWithCreated),
-	// v14 -> v15
-	NewMigration("create user column diff view style", createUserColumnDiffViewStyle),
-	// v15 -> v16
-	NewMigration("create user column allow create organization", createAllowCreateOrganizationColumn),
-	// V16 -> v17
-	NewMigration("create repo unit table and add units for all repos", addUnitsToTables),
-	// v17 -> v18
-	NewMigration("set protect branches updated with created", setProtectedBranchUpdatedWithCreated),
-	// v18 -> v19
-	NewMigration("add external login user", addExternalLoginUser),
-	// v19 -> v20
-	NewMigration("generate and migrate Git hooks", generateAndMigrateGitHooks),
-	// v20 -> v21
-	NewMigration("use new avatar path name for security reason", useNewNameAvatars),
-	// v21 -> v22
-	NewMigration("rewrite authorized_keys file via new format", useNewPublickeyFormat),
-	// v22 -> v23
-	NewMigration("generate and migrate wiki Git hooks", generateAndMigrateWikiGitHooks),
-	// v23 -> v24
-	NewMigration("add user openid table", addUserOpenID),
-	// v24 -> v25
-	NewMigration("change the key_id and primary_key_id type", changeGPGKeysColumns),
-	// v25 -> v26
-	NewMigration("add show field in user openid table", addUserOpenIDShow),
-	// v26 -> v27
-	NewMigration("generate and migrate repo and wiki Git hooks", generateAndMigrateGitHookChains),
-	// v27 -> v28
-	NewMigration("change mirror interval from hours to time.Duration", convertIntervalToDuration),
-	// v28 -> v29
-	NewMigration("add field for repo size", addRepoSize),
-	// v29 -> v30
-	NewMigration("add commit status table", addCommitStatus),
-	// v30 -> 31
-	NewMigration("add primary key to external login user", addExternalLoginUserPK),
-	// v31 -> 32
-	NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
-	// v32 -> v33
-	NewMigration("add units for team", addUnitsToRepoTeam),
-	// v33 -> v34
-	NewMigration("remove columns from action", removeActionColumns),
-	// v34 -> v35
-	NewMigration("give all units to owner teams", giveAllUnitsToOwnerTeams),
-	// v35 -> v36
-	NewMigration("adds comment to an action", addCommentIDToAction),
-	// v36 -> v37
-	NewMigration("regenerate git hooks", regenerateGitHooks36),
-	// v37 -> v38
-	NewMigration("unescape user full names", unescapeUserFullNames),
-	// v38 -> v39
-	NewMigration("remove commits and settings unit types", removeCommitsUnitType),
-	// v39 -> v40
-	NewMigration("add tags to releases and sync existing repositories", releaseAddColumnIsTagAndSyncTags),
-	// v40 -> v41
-	NewMigration("fix protected branch can push value to false", fixProtectedBranchCanPushValue),
-	// v41 -> v42
-	NewMigration("remove duplicate unit types", removeDuplicateUnitTypes),
-	// v42 -> v43
-	NewMigration("empty step", emptyMigration),
-	// v43 -> v44
-	NewMigration("empty step", emptyMigration),
-	// v44 -> v45
-	NewMigration("empty step", emptyMigration),
-	// v45 -> v46
-	NewMigration("remove index column from repo_unit table", removeIndexColumnFromRepoUnitTable),
-	// v46 -> v47
-	NewMigration("remove organization watch repositories", removeOrganizationWatchRepo),
-	// v47 -> v48
-	NewMigration("add deleted branches", addDeletedBranch),
-	// v48 -> v49
-	NewMigration("add repo indexer status", addRepoIndexerStatus),
-	// v49 -> v50
-	NewMigration("adds time tracking and stopwatches", addTimetracking),
-	// v50 -> v51
-	NewMigration("migrate protected branch struct", migrateProtectedBranchStruct),
-	// v51 -> v52
-	NewMigration("add default value to user prohibit_login", addDefaultValueToUserProhibitLogin),
-	// v52 -> v53
-	NewMigration("add lfs lock table", addLFSLock),
-	// v53 -> v54
-	NewMigration("add reactions", addReactions),
-	// v54 -> v55
-	NewMigration("add pull request options", addPullRequestOptions),
-	// v55 -> v56
-	NewMigration("add writable deploy keys", addModeToDeploKeys),
-	// v56 -> v57
-	NewMigration("remove is_owner, num_teams columns from org_user", removeIsOwnerColumnFromOrgUser),
-	// v57 -> v58
-	NewMigration("add closed_unix column for issues", addIssueClosedTime),
-	// v58 -> v59
-	NewMigration("add label descriptions", addLabelsDescriptions),
-	// v59 -> v60
-	NewMigration("add merge whitelist for protected branches", addProtectedBranchMergeWhitelist),
-	// v60 -> v61
-	NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
-	// v61 -> v62
-	NewMigration("add size column for attachments", addSizeToAttachment),
-	// v62 -> v63
-	NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
-	// v63 -> v64
-	NewMigration("add language column for user setting", addLanguageSetting),
-	// v64 -> v65
-	NewMigration("add multiple assignees", addMultipleAssignees),
-	// v65 -> v66
-	NewMigration("add u2f", addU2FReg),
-	// v66 -> v67
-	NewMigration("add login source id column for public_key table", addLoginSourceIDToPublicKeyTable),
-	// v67 -> v68
-	NewMigration("remove stale watches", removeStaleWatches),
-	// v68 -> V69
-	NewMigration("Reformat and remove incorrect topics", reformatAndRemoveIncorrectTopics),
-	// v69 -> v70
-	NewMigration("move team units to team_unit table", moveTeamUnitsToTeamUnitTable),
+	// Gitea 1.5.3 ends at v70
+
 	// v70 -> v71
 	NewMigration("add issue_dependencies", addIssueDependencies),
 	// v71 -> v72
 	NewMigration("protect each scratch token", addScratchHash),
 	// v72 -> v73
 	NewMigration("add review", addReview),
+
+	// Gitea 1.6.4 ends at v73
+
 	// v73 -> v74
 	NewMigration("add must_change_password column for users table", addMustChangePassword),
 	// v74 -> v75
 	NewMigration("add approval whitelists to protected branches", addApprovalWhitelistsToProtectedBranches),
 	// v75 -> v76
 	NewMigration("clear nonused data which not deleted when user was deleted", clearNonusedData),
+
+	// Gitea 1.7.6 ends at v76
+
 	// v76 -> v77
 	NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge),
 	// v77 -> v78
@@ -218,6 +87,9 @@ var migrations = []Migration{
 	NewMigration("add is locked to issues", addIsLockedToIssues),
 	// v81 -> v82
 	NewMigration("update U2F counter type", changeU2FCounterType),
+
+	// Gitea 1.8.3 ends at v82
+
 	// v82 -> v83
 	NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable),
 	// v83 -> v84
@@ -230,6 +102,9 @@ var migrations = []Migration{
 	NewMigration("add http method to webhook", addHTTPMethodToWebhook),
 	// v87 -> v88
 	NewMigration("add avatar field to repository", addAvatarFieldToRepository),
+
+	// Gitea 1.9.6 ends at v88
+
 	// v88 -> v89
 	NewMigration("add commit status context field to commit_status", addCommitStatusContext),
 	// v89 -> v90
@@ -252,6 +127,9 @@ var migrations = []Migration{
 	NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser),
 	// v98 -> v99
 	NewMigration("add original author name and id on migrated release", addOriginalAuthorOnMigratedReleases),
+
+	// Gitea 1.10.3 ends at v99
+
 	// v99 -> v100
 	NewMigration("add task table and status column for repository table", addTaskTable),
 	// v100 -> v101
@@ -334,7 +212,7 @@ func Migrate(x *xorm.Engine) error {
 	v := currentVersion.Version
 	if minDBVersion > v {
 		log.Fatal(`Gitea no longer supports auto-migration from your previously installed version.
-Please try to upgrade to a lower version (>= v0.6.0) first, then upgrade to current version.`)
+Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
 		return nil
 	}
 
@@ -512,591 +390,3 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
 
 	return nil
 }
-
-func fixLocaleFileLoadPanic(_ *xorm.Engine) error {
-	cfg, err := ini.Load(setting.CustomConf)
-	if err != nil {
-		return fmt.Errorf("load custom config: %v", err)
-	}
-
-	cfg.DeleteSection("i18n")
-	if err = cfg.SaveTo(setting.CustomConf); err != nil {
-		return fmt.Errorf("save custom config: %v", err)
-	}
-
-	setting.Langs = strings.Split(strings.Replace(strings.Join(setting.Langs, ","), "fr-CA", "fr-FR", 1), ",")
-	return nil
-}
-
-func trimCommitActionAppURLPrefix(x *xorm.Engine) error {
-	type PushCommit struct {
-		Sha1        string
-		Message     string
-		AuthorEmail string
-		AuthorName  string
-	}
-
-	type PushCommits struct {
-		Len        int
-		Commits    []*PushCommit
-		CompareURL string `json:"CompareUrl"`
-	}
-
-	type Action struct {
-		ID      int64  `xorm:"pk autoincr"`
-		Content string `xorm:"TEXT"`
-	}
-
-	results, err := x.Query("SELECT `id`,`content` FROM `action` WHERE `op_type`=?", 5)
-	if err != nil {
-		return fmt.Errorf("select commit actions: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	var pushCommits *PushCommits
-	for _, action := range results {
-		actID := com.StrTo(string(action["id"])).MustInt64()
-		if actID == 0 {
-			continue
-		}
-
-		pushCommits = new(PushCommits)
-		if err = json.Unmarshal(action["content"], pushCommits); err != nil {
-			return fmt.Errorf("unmarshal action content[%d]: %v", actID, err)
-		}
-
-		infos := strings.Split(pushCommits.CompareURL, "/")
-		if len(infos) <= 4 {
-			continue
-		}
-		pushCommits.CompareURL = strings.Join(infos[len(infos)-4:], "/")
-
-		p, err := json.Marshal(pushCommits)
-		if err != nil {
-			return fmt.Errorf("marshal action content[%d]: %v", actID, err)
-		}
-
-		if _, err = sess.ID(actID).Update(&Action{
-			Content: string(p),
-		}); err != nil {
-			return fmt.Errorf("update action[%d]: %v", actID, err)
-		}
-	}
-	return sess.Commit()
-}
-
-func issueToIssueLabel(x *xorm.Engine) error {
-	type IssueLabel struct {
-		ID      int64 `xorm:"pk autoincr"`
-		IssueID int64 `xorm:"UNIQUE(s)"`
-		LabelID int64 `xorm:"UNIQUE(s)"`
-	}
-
-	issueLabels := make([]*IssueLabel, 0, 50)
-	results, err := x.Query("SELECT `id`,`label_ids` FROM `issue`")
-	if err != nil {
-		if strings.Contains(err.Error(), "no such column") ||
-			strings.Contains(err.Error(), "Unknown column") {
-			return nil
-		}
-		return fmt.Errorf("select issues: %v", err)
-	}
-	for _, issue := range results {
-		issueID := com.StrTo(issue["id"]).MustInt64()
-
-		// Just in case legacy code can have duplicated IDs for same label.
-		mark := make(map[int64]bool)
-		for _, idStr := range strings.Split(string(issue["label_ids"]), "|") {
-			labelID := com.StrTo(strings.TrimPrefix(idStr, "$")).MustInt64()
-			if labelID == 0 || mark[labelID] {
-				continue
-			}
-
-			mark[labelID] = true
-			issueLabels = append(issueLabels, &IssueLabel{
-				IssueID: issueID,
-				LabelID: labelID,
-			})
-		}
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	if err = sess.Sync2(new(IssueLabel)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	} else if _, err = sess.Insert(issueLabels); err != nil {
-		return fmt.Errorf("insert issue-labels: %v", err)
-	}
-
-	return sess.Commit()
-}
-
-func attachmentRefactor(x *xorm.Engine) error {
-	type Attachment struct {
-		ID   int64  `xorm:"pk autoincr"`
-		UUID string `xorm:"uuid INDEX"`
-
-		// For rename purpose.
-		Path    string `xorm:"-"`
-		NewPath string `xorm:"-"`
-	}
-
-	results, err := x.Query("SELECT * FROM `attachment`")
-	if err != nil {
-		return fmt.Errorf("select attachments: %v", err)
-	}
-
-	attachments := make([]*Attachment, 0, len(results))
-	for _, attach := range results {
-		if !com.IsExist(string(attach["path"])) {
-			// If the attachment is already missing, there is no point to update it.
-			continue
-		}
-		attachments = append(attachments, &Attachment{
-			ID:   com.StrTo(attach["id"]).MustInt64(),
-			UUID: gouuid.NewV4().String(),
-			Path: string(attach["path"]),
-		})
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	if err = sess.Sync2(new(Attachment)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	// Note: Roll back for rename can be a dead loop,
-	// 	so produces a backup file.
-	var buf bytes.Buffer
-	buf.WriteString("# old path -> new path\n")
-
-	// Update database first because this is where error happens the most often.
-	for _, attach := range attachments {
-		if _, err = sess.ID(attach.ID).Update(attach); err != nil {
-			return err
-		}
-
-		attach.NewPath = path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID)
-		buf.WriteString(attach.Path)
-		buf.WriteString("\t")
-		buf.WriteString(attach.NewPath)
-		buf.WriteString("\n")
-	}
-
-	// Then rename attachments.
-	isSucceed := true
-	defer func() {
-		if isSucceed {
-			return
-		}
-
-		dumpPath := path.Join(setting.LogRootPath, "attachment_path.dump")
-		ioutil.WriteFile(dumpPath, buf.Bytes(), 0666)
-		log.Info("Failed to rename some attachments, old and new paths are saved into: %s", dumpPath)
-	}()
-	for _, attach := range attachments {
-		if err = os.MkdirAll(path.Dir(attach.NewPath), os.ModePerm); err != nil {
-			isSucceed = false
-			return err
-		}
-
-		if err = os.Rename(attach.Path, attach.NewPath); err != nil {
-			isSucceed = false
-			return err
-		}
-	}
-
-	return sess.Commit()
-}
-
-func renamePullRequestFields(x *xorm.Engine) (err error) {
-	type PullRequest struct {
-		ID         int64 `xorm:"pk autoincr"`
-		PullID     int64 `xorm:"INDEX"`
-		PullIndex  int64
-		HeadBarcnh string
-
-		IssueID    int64 `xorm:"INDEX"`
-		Index      int64
-		HeadBranch string
-	}
-
-	if err = x.Sync(new(PullRequest)); err != nil {
-		return fmt.Errorf("sync: %v", err)
-	}
-
-	results, err := x.Query("SELECT `id`,`pull_id`,`pull_index`,`head_barcnh` FROM `pull_request`")
-	if err != nil {
-		if strings.Contains(err.Error(), "no such column") {
-			return nil
-		}
-		return fmt.Errorf("select pull requests: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	var pull *PullRequest
-	for _, pr := range results {
-		pull = &PullRequest{
-			ID:         com.StrTo(pr["id"]).MustInt64(),
-			IssueID:    com.StrTo(pr["pull_id"]).MustInt64(),
-			Index:      com.StrTo(pr["pull_index"]).MustInt64(),
-			HeadBranch: string(pr["head_barcnh"]),
-		}
-		if pull.Index == 0 {
-			continue
-		}
-		if _, err = sess.ID(pull.ID).Update(pull); err != nil {
-			return err
-		}
-	}
-
-	return sess.Commit()
-}
-
-func cleanUpMigrateRepoInfo(x *xorm.Engine) (err error) {
-	type (
-		User struct {
-			ID        int64 `xorm:"pk autoincr"`
-			LowerName string
-		}
-		Repository struct {
-			ID        int64 `xorm:"pk autoincr"`
-			OwnerID   int64
-			LowerName string
-		}
-	)
-
-	repos := make([]*Repository, 0, 25)
-	if err = x.Where("is_mirror=?", false).Find(&repos); err != nil {
-		return fmt.Errorf("select all non-mirror repositories: %v", err)
-	}
-	var user *User
-	for _, repo := range repos {
-		user = &User{ID: repo.OwnerID}
-		has, err := x.Get(user)
-		if err != nil {
-			return fmt.Errorf("get owner of repository[%d - %d]: %v", repo.ID, repo.OwnerID, err)
-		} else if !has {
-			continue
-		}
-
-		configPath := filepath.Join(setting.RepoRootPath, user.LowerName, repo.LowerName+".git/config")
-
-		// In case repository file is somehow missing.
-		if !com.IsFile(configPath) {
-			continue
-		}
-
-		cfg, err := ini.Load(configPath)
-		if err != nil {
-			return fmt.Errorf("open config file: %v", err)
-		}
-		cfg.DeleteSection("remote \"origin\"")
-		if err = cfg.SaveToIndent(configPath, "\t"); err != nil {
-			return fmt.Errorf("save config file: %v", err)
-		}
-	}
-
-	return nil
-}
-
-func generateOrgRandsAndSalt(x *xorm.Engine) (err error) {
-	type User struct {
-		ID    int64  `xorm:"pk autoincr"`
-		Rands string `xorm:"VARCHAR(10)"`
-		Salt  string `xorm:"VARCHAR(10)"`
-	}
-
-	orgs := make([]*User, 0, 10)
-	if err = x.Where("type=1").And("rands=''").Find(&orgs); err != nil {
-		return fmt.Errorf("select all organizations: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	for _, org := range orgs {
-		if org.Rands, err = generate.GetRandomString(10); err != nil {
-			return err
-		}
-		if org.Salt, err = generate.GetRandomString(10); err != nil {
-			return err
-		}
-		if _, err = sess.ID(org.ID).Update(org); err != nil {
-			return err
-		}
-	}
-
-	return sess.Commit()
-}
-
-// TAction defines the struct for migrating table action
-type TAction struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TAction) TableName() string { return "action" }
-
-// TNotice defines the struct for migrating table notice
-type TNotice struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TNotice) TableName() string { return "notice" }
-
-// TComment defines the struct for migrating table comment
-type TComment struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TComment) TableName() string { return "comment" }
-
-// TIssue defines the struct for migrating table issue
-type TIssue struct {
-	ID           int64 `xorm:"pk autoincr"`
-	DeadlineUnix int64
-	CreatedUnix  int64
-	UpdatedUnix  int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TIssue) TableName() string { return "issue" }
-
-// TMilestone defines the struct for migrating table milestone
-type TMilestone struct {
-	ID             int64 `xorm:"pk autoincr"`
-	DeadlineUnix   int64
-	ClosedDateUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TMilestone) TableName() string { return "milestone" }
-
-// TAttachment defines the struct for migrating table attachment
-type TAttachment struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TAttachment) TableName() string { return "attachment" }
-
-// TLoginSource defines the struct for migrating table login_source
-type TLoginSource struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TLoginSource) TableName() string { return "login_source" }
-
-// TPull defines the struct for migrating table pull_request
-type TPull struct {
-	ID         int64 `xorm:"pk autoincr"`
-	MergedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TPull) TableName() string { return "pull_request" }
-
-// TRelease defines the struct for migrating table release
-type TRelease struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TRelease) TableName() string { return "release" }
-
-// TRepo defines the struct for migrating table repository
-type TRepo struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TRepo) TableName() string { return "repository" }
-
-// TMirror defines the struct for migrating table mirror
-type TMirror struct {
-	ID             int64 `xorm:"pk autoincr"`
-	UpdatedUnix    int64
-	NextUpdateUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TMirror) TableName() string { return "mirror" }
-
-// TPublicKey defines the struct for migrating table public_key
-type TPublicKey struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TPublicKey) TableName() string { return "public_key" }
-
-// TDeployKey defines the struct for migrating table deploy_key
-type TDeployKey struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TDeployKey) TableName() string { return "deploy_key" }
-
-// TAccessToken defines the struct for migrating table access_token
-type TAccessToken struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TAccessToken) TableName() string { return "access_token" }
-
-// TUser defines the struct for migrating table user
-type TUser struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TUser) TableName() string { return "user" }
-
-// TWebhook defines the struct for migrating table webhook
-type TWebhook struct {
-	ID          int64 `xorm:"pk autoincr"`
-	CreatedUnix int64
-	UpdatedUnix int64
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (t *TWebhook) TableName() string { return "webhook" }
-
-func convertDateToUnix(x *xorm.Engine) (err error) {
-	log.Info("This migration could take up to minutes, please be patient.")
-	type Bean struct {
-		ID         int64 `xorm:"pk autoincr"`
-		Created    time.Time
-		Updated    time.Time
-		Merged     time.Time
-		Deadline   time.Time
-		ClosedDate time.Time
-		NextUpdate time.Time
-	}
-
-	var tables = []struct {
-		name string
-		cols []string
-		bean interface{}
-	}{
-		{"action", []string{"created"}, new(TAction)},
-		{"notice", []string{"created"}, new(TNotice)},
-		{"comment", []string{"created"}, new(TComment)},
-		{"issue", []string{"deadline", "created", "updated"}, new(TIssue)},
-		{"milestone", []string{"deadline", "closed_date"}, new(TMilestone)},
-		{"attachment", []string{"created"}, new(TAttachment)},
-		{"login_source", []string{"created", "updated"}, new(TLoginSource)},
-		{"pull_request", []string{"merged"}, new(TPull)},
-		{"release", []string{"created"}, new(TRelease)},
-		{"repository", []string{"created", "updated"}, new(TRepo)},
-		{"mirror", []string{"updated", "next_update"}, new(TMirror)},
-		{"public_key", []string{"created", "updated"}, new(TPublicKey)},
-		{"deploy_key", []string{"created", "updated"}, new(TDeployKey)},
-		{"access_token", []string{"created", "updated"}, new(TAccessToken)},
-		{"user", []string{"created", "updated"}, new(TUser)},
-		{"webhook", []string{"created", "updated"}, new(TWebhook)},
-	}
-
-	for _, table := range tables {
-		log.Info("Converting table: %s", table.name)
-		if err = x.Sync2(table.bean); err != nil {
-			return fmt.Errorf("Sync [table: %s]: %v", table.name, err)
-		}
-
-		offset := 0
-		for {
-			beans := make([]*Bean, 0, 100)
-			if err = x.Table(table.name).Asc("id").Limit(100, offset).Find(&beans); err != nil {
-				return fmt.Errorf("select beans [table: %s, offset: %d]: %v", table.name, offset, err)
-			}
-			log.Trace("Table [%s]: offset: %d, beans: %d", table.name, offset, len(beans))
-			if len(beans) == 0 {
-				break
-			}
-			offset += 100
-
-			baseSQL := "UPDATE `" + table.name + "` SET "
-			for _, bean := range beans {
-				valSQLs := make([]string, 0, len(table.cols))
-				for _, col := range table.cols {
-					fieldSQL := ""
-					fieldSQL += col + "_unix = "
-
-					switch col {
-					case "deadline":
-						if bean.Deadline.IsZero() {
-							continue
-						}
-						fieldSQL += com.ToStr(bean.Deadline.Unix())
-					case "created":
-						fieldSQL += com.ToStr(bean.Created.Unix())
-					case "updated":
-						fieldSQL += com.ToStr(bean.Updated.Unix())
-					case "closed_date":
-						fieldSQL += com.ToStr(bean.ClosedDate.Unix())
-					case "merged":
-						fieldSQL += com.ToStr(bean.Merged.Unix())
-					case "next_update":
-						fieldSQL += com.ToStr(bean.NextUpdate.Unix())
-					}
-
-					valSQLs = append(valSQLs, fieldSQL)
-				}
-
-				if len(valSQLs) == 0 {
-					continue
-				}
-
-				if _, err = x.Exec(baseSQL + strings.Join(valSQLs, ",") + " WHERE id = " + com.ToStr(bean.ID)); err != nil {
-					return fmt.Errorf("update bean [table: %s, id: %d]: %v", table.name, bean.ID, err)
-				}
-			}
-		}
-	}
-
-	return nil
-}
diff --git a/models/migrations/v13.go b/models/migrations/v13.go
deleted file mode 100644
index 3c35b66ab9..0000000000
--- a/models/migrations/v13.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"encoding/json"
-	"fmt"
-	"strings"
-
-	"github.com/unknwon/com"
-	"xorm.io/xorm"
-)
-
-func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error {
-	results, err := x.Query("SELECT `id`,`cfg` FROM `login_source` WHERE `type` = 2 OR `type` = 5")
-	if err != nil {
-		if strings.Contains(err.Error(), "no such column") {
-			return nil
-		}
-		return fmt.Errorf("select LDAP login sources: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	for _, result := range results {
-		cfg := map[string]interface{}{}
-		if err = json.Unmarshal(result["cfg"], &cfg); err != nil {
-			return fmt.Errorf("decode JSON config: %v", err)
-		}
-		if com.ToStr(cfg["UseSSL"]) == "true" {
-			cfg["SecurityProtocol"] = 1 // LDAPS
-		}
-		delete(cfg, "UseSSL")
-
-		data, err := json.Marshal(&cfg)
-		if err != nil {
-			return fmt.Errorf("encode JSON config: %v", err)
-		}
-
-		if _, err = sess.Exec("UPDATE `login_source` SET `cfg`=? WHERE `id`=?",
-			string(data), com.StrTo(result["id"]).MustInt64()); err != nil {
-			return fmt.Errorf("update config column: %v", err)
-		}
-	}
-	return sess.Commit()
-}
diff --git a/models/migrations/v14.go b/models/migrations/v14.go
deleted file mode 100644
index 675c7459dd..0000000000
--- a/models/migrations/v14.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func setCommentUpdatedWithCreated(x *xorm.Engine) (err error) {
-	type Comment struct {
-		UpdatedUnix int64
-	}
-
-	if err = x.Sync2(new(Comment)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	} else if _, err = x.Exec("UPDATE comment SET updated_unix = created_unix"); err != nil {
-		return fmt.Errorf("set update_unix: %v", err)
-	}
-	return nil
-}
-
-// UserV14 describes the added fields for migrating from v13 -> v14
-type UserV14 struct {
-	DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
-}
-
-// TableName will be invoked by XORM to customize the table name
-func (*UserV14) TableName() string {
-	return "user"
-}
-
-func createUserColumnDiffViewStyle(x *xorm.Engine) error {
-	return x.Sync2(new(UserV14))
-}
diff --git a/models/migrations/v15.go b/models/migrations/v15.go
deleted file mode 100644
index 8872f1e946..0000000000
--- a/models/migrations/v15.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func createAllowCreateOrganizationColumn(x *xorm.Engine) error {
-	type User struct {
-		KeepEmailPrivate        bool
-		AllowCreateOrganization bool
-	}
-
-	if err := x.Sync2(new(User)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	} else if _, err = x.Where("`type` = 0").Cols("allow_create_organization").Update(&User{AllowCreateOrganization: true}); err != nil {
-		return fmt.Errorf("set allow_create_organization: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v16.go b/models/migrations/v16.go
deleted file mode 100644
index a849205b55..0000000000
--- a/models/migrations/v16.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"code.gitea.io/gitea/modules/markup"
-
-	"xorm.io/xorm"
-)
-
-// Enumerate all the unit types
-const (
-	V16UnitTypeCode            = iota + 1 // 1 code
-	V16UnitTypeIssues                     // 2 issues
-	V16UnitTypePRs                        // 3 PRs
-	V16UnitTypeCommits                    // 4 Commits
-	V16UnitTypeReleases                   // 5 Releases
-	V16UnitTypeWiki                       // 6 Wiki
-	V16UnitTypeSettings                   // 7 Settings
-	V16UnitTypeExternalWiki               // 8 ExternalWiki
-	V16UnitTypeExternalTracker            // 9 ExternalTracker
-)
-
-func addUnitsToTables(x *xorm.Engine) error {
-	// RepoUnit describes all units of a repository
-	type RepoUnit struct {
-		ID          int64
-		RepoID      int64 `xorm:"INDEX(s)"`
-		Type        int   `xorm:"INDEX(s)"`
-		Index       int
-		Config      map[string]interface{} `xorm:"JSON"`
-		CreatedUnix int64                  `xorm:"INDEX CREATED"`
-		Created     time.Time              `xorm:"-"`
-	}
-
-	// Repo describes a repository
-	type Repo struct {
-		ID                                                                               int64
-		EnableWiki, EnableExternalWiki, EnableIssues, EnableExternalTracker, EnablePulls bool
-		ExternalWikiURL, ExternalTrackerURL, ExternalTrackerFormat, ExternalTrackerStyle string
-	}
-
-	var repos []Repo
-	err := x.Table("repository").Select("*").Find(&repos)
-	if err != nil {
-		return fmt.Errorf("Query repositories: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	var repoUnit RepoUnit
-	if exist, err := sess.IsTableExist(&repoUnit); err != nil {
-		return fmt.Errorf("IsExist RepoUnit: %v", err)
-	} else if exist {
-		return nil
-	}
-
-	if err := sess.CreateTable(&repoUnit); err != nil {
-		return fmt.Errorf("CreateTable RepoUnit: %v", err)
-	}
-
-	if err := sess.CreateUniques(&repoUnit); err != nil {
-		return fmt.Errorf("CreateUniques RepoUnit: %v", err)
-	}
-
-	if err := sess.CreateIndexes(&repoUnit); err != nil {
-		return fmt.Errorf("CreateIndexes RepoUnit: %v", err)
-	}
-
-	for _, repo := range repos {
-		for i := 1; i <= 9; i++ {
-			if (i == V16UnitTypeWiki || i == V16UnitTypeExternalWiki) && !repo.EnableWiki {
-				continue
-			}
-			if i == V16UnitTypeExternalWiki && !repo.EnableExternalWiki {
-				continue
-			}
-			if i == V16UnitTypePRs && !repo.EnablePulls {
-				continue
-			}
-			if (i == V16UnitTypeIssues || i == V16UnitTypeExternalTracker) && !repo.EnableIssues {
-				continue
-			}
-			if i == V16UnitTypeExternalTracker && !repo.EnableExternalTracker {
-				continue
-			}
-
-			var config = make(map[string]interface{})
-			switch i {
-			case V16UnitTypeExternalTracker:
-				config["ExternalTrackerURL"] = repo.ExternalTrackerURL
-				config["ExternalTrackerFormat"] = repo.ExternalTrackerFormat
-				if len(repo.ExternalTrackerStyle) == 0 {
-					repo.ExternalTrackerStyle = markup.IssueNameStyleNumeric
-				}
-				config["ExternalTrackerStyle"] = repo.ExternalTrackerStyle
-			case V16UnitTypeExternalWiki:
-				config["ExternalWikiURL"] = repo.ExternalWikiURL
-			}
-
-			if _, err = sess.Insert(&RepoUnit{
-				RepoID: repo.ID,
-				Type:   i,
-				Index:  i,
-				Config: config,
-			}); err != nil {
-				return fmt.Errorf("Insert repo unit: %v", err)
-			}
-		}
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v17.go b/models/migrations/v17.go
deleted file mode 100644
index 2907b009db..0000000000
--- a/models/migrations/v17.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"xorm.io/xorm"
-)
-
-func setProtectedBranchUpdatedWithCreated(x *xorm.Engine) (err error) {
-	type ProtectedBranch struct {
-		ID          int64  `xorm:"pk autoincr"`
-		RepoID      int64  `xorm:"UNIQUE(s)"`
-		BranchName  string `xorm:"UNIQUE(s)"`
-		CanPush     bool
-		Created     time.Time `xorm:"-"`
-		CreatedUnix int64
-		Updated     time.Time `xorm:"-"`
-		UpdatedUnix int64
-	}
-	if err = x.Sync2(new(ProtectedBranch)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v18.go b/models/migrations/v18.go
deleted file mode 100644
index 66a1de3499..0000000000
--- a/models/migrations/v18.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-// ExternalLoginUser makes the connecting between some existing user and additional external login sources
-type ExternalLoginUser struct {
-	ExternalID    string `xorm:"NOT NULL"`
-	UserID        int64  `xorm:"NOT NULL"`
-	LoginSourceID int64  `xorm:"NOT NULL"`
-}
-
-func addExternalLoginUser(x *xorm.Engine) error {
-	if err := x.Sync2(new(ExternalLoginUser)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v19.go b/models/migrations/v19.go
deleted file mode 100644
index 349d5850aa..0000000000
--- a/models/migrations/v19.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"github.com/unknwon/com"
-	"xorm.io/xorm"
-)
-
-func generateAndMigrateGitHooks(x *xorm.Engine) (err error) {
-	type Repository struct {
-		ID      int64
-		OwnerID int64
-		Name    string
-	}
-	type User struct {
-		ID   int64
-		Name string
-	}
-
-	var (
-		hookNames = []string{"pre-receive", "update", "post-receive"}
-		hookTpls  = []string{
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/pre-receive.d\"`; do\n    sh \"$SHELL_FOLDER/pre-receive.d/$i\"\ndone", setting.ScriptType),
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/update.d\"`; do\n    sh \"$SHELL_FOLDER/update.d/$i\" $1 $2 $3\ndone", setting.ScriptType),
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/post-receive.d\"`; do\n    sh \"$SHELL_FOLDER/post-receive.d/$i\"\ndone", setting.ScriptType),
-		}
-		giteaHookTpls = []string{
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-		}
-	)
-
-	return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository),
-		func(idx int, bean interface{}) error {
-			repo := bean.(*Repository)
-			user := new(User)
-			has, err := x.Where("id = ?", repo.OwnerID).Get(user)
-			if err != nil {
-				return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
-			} else if !has {
-				return nil
-			}
-
-			repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
-			hookDir := filepath.Join(repoPath, "hooks")
-
-			for i, hookName := range hookNames {
-				oldHookPath := filepath.Join(hookDir, hookName)
-				newHookPath := filepath.Join(hookDir, hookName+".d", "gitea")
-
-				customHooksDir := filepath.Join(hookDir, hookName+".d")
-				// if it's exist, that means you have upgraded ever
-				if com.IsExist(customHooksDir) {
-					continue
-				}
-
-				if err = os.MkdirAll(customHooksDir, os.ModePerm); err != nil {
-					return fmt.Errorf("create hooks dir '%s': %v", customHooksDir, err)
-				}
-
-				// WARNING: Old server-side hooks will be moved to sub directory with the same name
-				if hookName != "update" && com.IsExist(oldHookPath) {
-					newPlace := filepath.Join(hookDir, hookName+".d", hookName)
-					if err = os.Rename(oldHookPath, newPlace); err != nil {
-						return fmt.Errorf("Remove old hook file '%s' to '%s': %v", oldHookPath, newPlace, err)
-					}
-				}
-
-				if err = ioutil.WriteFile(oldHookPath, []byte(hookTpls[i]), 0777); err != nil {
-					return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err)
-				}
-
-				if err = ioutil.WriteFile(newHookPath, []byte(giteaHookTpls[i]), 0777); err != nil {
-					return fmt.Errorf("write new hook file '%s': %v", oldHookPath, err)
-				}
-			}
-			return nil
-		})
-}
diff --git a/models/migrations/v20.go b/models/migrations/v20.go
deleted file mode 100644
index 0897eada74..0000000000
--- a/models/migrations/v20.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"crypto/md5"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strconv"
-
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func useNewNameAvatars(x *xorm.Engine) error {
-	d, err := os.Open(setting.AvatarUploadPath)
-	if err != nil {
-		if os.IsNotExist(err) {
-			// Nothing to do if AvatarUploadPath does not exist
-			return nil
-		}
-		return err
-	}
-	names, err := d.Readdirnames(0)
-	if err != nil {
-		return err
-	}
-
-	type User struct {
-		ID              int64 `xorm:"pk autoincr"`
-		Avatar          string
-		UseCustomAvatar bool
-	}
-
-	for _, name := range names {
-		userID, err := strconv.ParseInt(name, 10, 64)
-		if err != nil {
-			log.Warn("ignore avatar %s rename: %v", name, err)
-			continue
-		}
-
-		var user User
-		if has, err := x.ID(userID).Get(&user); err != nil {
-			return err
-		} else if !has {
-			return errors.New("Avatar user is not exist")
-		}
-
-		fPath := filepath.Join(setting.AvatarUploadPath, name)
-		bs, err := ioutil.ReadFile(fPath)
-		if err != nil {
-			return err
-		}
-
-		user.Avatar = fmt.Sprintf("%x", md5.Sum(bs))
-		err = os.Rename(fPath, filepath.Join(setting.AvatarUploadPath, user.Avatar))
-		if err != nil {
-			return err
-		}
-		_, err = x.ID(userID).Cols("avatar").Update(&user)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/models/migrations/v21.go b/models/migrations/v21.go
deleted file mode 100644
index 2750725760..0000000000
--- a/models/migrations/v21.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"github.com/unknwon/com"
-	"xorm.io/xorm"
-)
-
-const (
-	tplCommentPrefix = `# gitea public key`
-	tplPublicKey     = tplCommentPrefix + "\n" + `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
-)
-
-func useNewPublickeyFormat(x *xorm.Engine) error {
-	fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
-	if !com.IsExist(fpath) {
-		return nil
-	}
-
-	tmpPath := fpath + ".tmp"
-	f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		f.Close()
-		os.Remove(tmpPath)
-	}()
-
-	type PublicKey struct {
-		ID      int64
-		Content string
-	}
-
-	err = x.Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) {
-		key := bean.(*PublicKey)
-		_, err = f.WriteString(fmt.Sprintf(tplPublicKey, setting.AppPath, key.ID, setting.CustomConf, key.Content))
-		return err
-	})
-	if err != nil {
-		return err
-	}
-
-	f.Close()
-	return os.Rename(tmpPath, fpath)
-}
diff --git a/models/migrations/v22.go b/models/migrations/v22.go
deleted file mode 100644
index eb37aec17f..0000000000
--- a/models/migrations/v22.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"github.com/unknwon/com"
-	"xorm.io/xorm"
-)
-
-func generateAndMigrateWikiGitHooks(x *xorm.Engine) (err error) {
-	type Repository struct {
-		ID      int64
-		OwnerID int64
-		Name    string
-	}
-	type User struct {
-		ID   int64
-		Name string
-	}
-
-	var (
-		hookNames = []string{"pre-receive", "update", "post-receive"}
-		hookTpls  = []string{
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/pre-receive.d\"`; do\n    sh \"$SHELL_FOLDER/pre-receive.d/$i\"\ndone", setting.ScriptType),
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/update.d\"`; do\n    sh \"$SHELL_FOLDER/update.d/$i\" $1 $2 $3\ndone", setting.ScriptType),
-			fmt.Sprintf("#!/usr/bin/env %s\nORI_DIR=`pwd`\nSHELL_FOLDER=$(cd \"$(dirname \"$0\")\";pwd)\ncd \"$ORI_DIR\"\nfor i in `ls \"$SHELL_FOLDER/post-receive.d\"`; do\n    sh \"$SHELL_FOLDER/post-receive.d/$i\"\ndone", setting.ScriptType),
-		}
-		giteaHookTpls = []string{
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-			fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf),
-		}
-	)
-
-	return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository),
-		func(idx int, bean interface{}) error {
-			repo := bean.(*Repository)
-			user := new(User)
-			has, err := x.Where("id = ?", repo.OwnerID).Get(user)
-			if err != nil {
-				return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
-			} else if !has {
-				return nil
-			}
-
-			repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".wiki.git"
-			if !com.IsExist(repoPath) {
-				return nil
-			}
-			hookDir := filepath.Join(repoPath, "hooks")
-
-			for i, hookName := range hookNames {
-				oldHookPath := filepath.Join(hookDir, hookName)
-				newHookPath := filepath.Join(hookDir, hookName+".d", "gitea")
-
-				customHooksDir := filepath.Join(hookDir, hookName+".d")
-				// if it's exist, that means you have upgraded ever
-				if com.IsExist(customHooksDir) {
-					continue
-				}
-
-				if err = os.MkdirAll(customHooksDir, os.ModePerm); err != nil {
-					return fmt.Errorf("create hooks dir '%s': %v", customHooksDir, err)
-				}
-
-				// WARNING: Old server-side hooks will be moved to sub directory with the same name
-				if hookName != "update" && com.IsExist(oldHookPath) {
-					newPlace := filepath.Join(hookDir, hookName+".d", hookName)
-					if err = os.Rename(oldHookPath, newPlace); err != nil {
-						return fmt.Errorf("Remove old hook file '%s' to '%s': %v", oldHookPath, newPlace, err)
-					}
-				}
-
-				if err = ioutil.WriteFile(oldHookPath, []byte(hookTpls[i]), 0777); err != nil {
-					return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err)
-				}
-
-				if err = ioutil.WriteFile(newHookPath, []byte(giteaHookTpls[i]), 0777); err != nil {
-					return fmt.Errorf("write new hook file '%s': %v", oldHookPath, err)
-				}
-			}
-			return nil
-		})
-}
diff --git a/models/migrations/v23.go b/models/migrations/v23.go
deleted file mode 100644
index 50dc6cd2c7..0000000000
--- a/models/migrations/v23.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-// UserOpenID is the list of all OpenID identities of a user.
-type UserOpenID struct {
-	ID  int64  `xorm:"pk autoincr"`
-	UID int64  `xorm:"INDEX NOT NULL"`
-	URI string `xorm:"UNIQUE NOT NULL"`
-}
-
-func addUserOpenID(x *xorm.Engine) error {
-	if err := x.Sync2(new(UserOpenID)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v24.go b/models/migrations/v24.go
deleted file mode 100644
index 20791d7981..0000000000
--- a/models/migrations/v24.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"time"
-
-	"xorm.io/xorm"
-)
-
-func changeGPGKeysColumns(x *xorm.Engine) error {
-	// EmailAddress is the list of all email addresses of a user. Can contain the
-	// primary email address, but is not obligatory.
-	type EmailAddress struct {
-		ID          int64  `xorm:"pk autoincr"`
-		UID         int64  `xorm:"INDEX NOT NULL"`
-		Email       string `xorm:"UNIQUE NOT NULL"`
-		IsActivated bool
-		IsPrimary   bool `xorm:"-"`
-	}
-
-	// GPGKey represents a GPG key.
-	type GPGKey struct {
-		ID                int64     `xorm:"pk autoincr"`
-		OwnerID           int64     `xorm:"INDEX NOT NULL"`
-		KeyID             string    `xorm:"INDEX CHAR(16) NOT NULL"`
-		PrimaryKeyID      string    `xorm:"CHAR(16)"`
-		Content           string    `xorm:"TEXT NOT NULL"`
-		Created           time.Time `xorm:"-"`
-		CreatedUnix       int64
-		Expired           time.Time `xorm:"-"`
-		ExpiredUnix       int64
-		Added             time.Time `xorm:"-"`
-		AddedUnix         int64
-		SubsKey           []*GPGKey `xorm:"-"`
-		Emails            []*EmailAddress
-		CanSign           bool
-		CanEncryptComms   bool
-		CanEncryptStorage bool
-		CanCertify        bool
-	}
-
-	if err := x.DropTables(new(GPGKey)); err != nil {
-		return err
-	}
-
-	return x.Sync(new(GPGKey))
-}
diff --git a/models/migrations/v25.go b/models/migrations/v25.go
deleted file mode 100644
index da74e27c28..0000000000
--- a/models/migrations/v25.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addUserOpenIDShow(x *xorm.Engine) error {
-	if err := x.Sync2(new(UserOpenID)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v26.go b/models/migrations/v26.go
deleted file mode 100644
index 03ce2ef94b..0000000000
--- a/models/migrations/v26.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"crypto/md5"
-	"encoding/hex"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"github.com/unknwon/com"
-	"xorm.io/xorm"
-)
-
-func generateAndMigrateGitHookChains(x *xorm.Engine) (err error) {
-	type Repository struct {
-		ID      int64
-		OwnerID int64
-		Name    string
-	}
-	type User struct {
-		ID   int64
-		Name string
-	}
-
-	var (
-		hookNames = []string{"pre-receive", "update", "post-receive"}
-		hookTpl   = fmt.Sprintf("#!/usr/bin/env %s\ndata=$(cat)\nexitcodes=\"\"\nhookname=$(basename $0)\nGIT_DIR=${GIT_DIR:-$(dirname $0)}\n\nfor hook in ${GIT_DIR}/hooks/${hookname}.d/*; do\ntest -x \"${hook}\" || continue\necho \"${data}\" | \"${hook}\"\nexitcodes=\"${exitcodes} $?\"\ndone\n\nfor i in ${exitcodes}; do\n[ ${i} -eq 0 ] || exit ${i}\ndone\n", setting.ScriptType)
-	)
-
-	return x.Where("id > 0").BufferSize(setting.Database.IterateBufferSize).Iterate(new(Repository),
-		func(idx int, bean interface{}) error {
-			repo := bean.(*Repository)
-			user := new(User)
-			has, err := x.Where("id = ?", repo.OwnerID).Get(user)
-			if err != nil {
-				return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
-			} else if !has {
-				return nil
-			}
-
-			repoPaths := []string{
-				filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git",
-				filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".wiki.git",
-			}
-
-			for _, repoPath := range repoPaths {
-				if com.IsExist(repoPath) {
-					hookDir := filepath.Join(repoPath, "hooks")
-
-					for _, hookName := range hookNames {
-						oldHookPath := filepath.Join(hookDir, hookName)
-
-						// compare md5sums of hooks
-						if com.IsExist(oldHookPath) {
-
-							f, err := os.Open(oldHookPath)
-							if err != nil {
-								return fmt.Errorf("cannot open old hook file '%s': %v", oldHookPath, err)
-							}
-							defer f.Close()
-							h := md5.New()
-							if _, err := io.Copy(h, f); err != nil {
-								return fmt.Errorf("cannot read old hook file '%s': %v", oldHookPath, err)
-							}
-							if hex.EncodeToString(h.Sum(nil)) == "6718ef67d0834e0a7908259acd566e3f" {
-								return nil
-							}
-						}
-
-						if err = ioutil.WriteFile(oldHookPath, []byte(hookTpl), 0777); err != nil {
-							return fmt.Errorf("write old hook file '%s': %v", oldHookPath, err)
-						}
-					}
-				}
-			}
-			return nil
-		})
-}
diff --git a/models/migrations/v27.go b/models/migrations/v27.go
deleted file mode 100644
index 2bba0b7412..0000000000
--- a/models/migrations/v27.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func convertIntervalToDuration(x *xorm.Engine) (err error) {
-	type Repository struct {
-		ID      int64
-		OwnerID int64
-		Name    string
-	}
-	type Mirror struct {
-		ID       int64       `xorm:"pk autoincr"`
-		RepoID   int64       `xorm:"INDEX"`
-		Repo     *Repository `xorm:"-"`
-		Interval time.Duration
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	dialect := x.Dialect().DriverName()
-
-	switch dialect {
-	case "mysql":
-		_, err = sess.Exec("ALTER TABLE mirror MODIFY `interval` BIGINT")
-	case "postgres":
-		_, err = sess.Exec("ALTER TABLE mirror ALTER COLUMN \"interval\" SET DATA TYPE bigint")
-	case "mssql":
-		_, err = sess.Exec("ALTER TABLE mirror ALTER COLUMN \"interval\" BIGINT")
-	case "sqlite3":
-	}
-
-	if err != nil {
-		return fmt.Errorf("Error changing mirror interval column type: %v", err)
-	}
-
-	var mirrors []Mirror
-	err = sess.Table("mirror").Select("*").Find(&mirrors)
-	if err != nil {
-		return fmt.Errorf("Query repositories: %v", err)
-	}
-	for _, mirror := range mirrors {
-		mirror.Interval *= time.Hour
-		if mirror.Interval < setting.Mirror.MinInterval {
-			log.Info("Mirror interval less than Mirror.MinInterval, setting default interval: repo id %v", mirror.RepoID)
-			mirror.Interval = setting.Mirror.DefaultInterval
-		}
-		log.Debug("Mirror interval set to %v for repo id %v", mirror.Interval, mirror.RepoID)
-		_, err := sess.ID(mirror.ID).Cols("interval").Update(mirror)
-		if err != nil {
-			return fmt.Errorf("update mirror interval failed: %v", err)
-		}
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v28.go b/models/migrations/v28.go
deleted file mode 100644
index a849fea3c2..0000000000
--- a/models/migrations/v28.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2017 The Gogs Authors. All rights reserved.
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"path/filepath"
-	"strings"
-
-	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func addRepoSize(x *xorm.Engine) (err error) {
-	log.Info("This migration could take up to minutes, please be patient.")
-	type Repository struct {
-		ID      int64
-		OwnerID int64
-		Name    string
-		Size    int64
-	}
-	type User struct {
-		ID   int64
-		Name string
-	}
-	if err = x.Sync2(new(Repository)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	// For the sake of SQLite3, we can't use x.Iterate here.
-	offset := 0
-	for {
-		repos := make([]*Repository, 0, 10)
-		if err = x.Table("repository").Asc("id").Limit(10, offset).Find(&repos); err != nil {
-			return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
-		}
-		log.Trace("Select [offset: %d, repos: %d]", offset, len(repos))
-		if len(repos) == 0 {
-			break
-		}
-		offset += 10
-
-		for _, repo := range repos {
-			if repo.Name == "." || repo.Name == ".." {
-				continue
-			}
-
-			user := new(User)
-			has, err := x.Where("id = ?", repo.OwnerID).Get(user)
-			if err != nil {
-				return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
-			} else if !has {
-				continue
-			}
-
-			repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
-			countObject, err := git.CountObjects(repoPath)
-			if err != nil {
-				log.Warn("CountObjects: %v", err)
-				continue
-			}
-
-			repo.Size = countObject.Size + countObject.SizePack
-			if _, err = x.ID(repo.ID).Cols("size").Update(repo); err != nil {
-				return fmt.Errorf("update size: %v", err)
-			}
-		}
-	}
-	return nil
-}
diff --git a/models/migrations/v29.go b/models/migrations/v29.go
deleted file mode 100644
index ea70a2dd77..0000000000
--- a/models/migrations/v29.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-// CommitStatus see models/status.go
-type CommitStatus struct {
-	ID          int64  `xorm:"pk autoincr"`
-	Index       int64  `xorm:"INDEX UNIQUE(repo_sha_index)"`
-	RepoID      int64  `xorm:"INDEX UNIQUE(repo_sha_index)"`
-	State       string `xorm:"VARCHAR(7) NOT NULL"`
-	SHA         string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
-	TargetURL   string `xorm:"TEXT"`
-	Description string `xorm:"TEXT"`
-	Context     string `xorm:"TEXT"`
-	CreatorID   int64  `xorm:"INDEX"`
-
-	CreatedUnix int64 `xorm:"INDEX"`
-	UpdatedUnix int64 `xorm:"INDEX"`
-}
-
-func addCommitStatus(x *xorm.Engine) error {
-	if err := x.Sync2(new(CommitStatus)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v30.go b/models/migrations/v30.go
deleted file mode 100644
index 5acdc5dac7..0000000000
--- a/models/migrations/v30.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Gogs Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addExternalLoginUserPK(x *xorm.Engine) error {
-	// ExternalLoginUser see models/external_login_user.go
-	type ExternalLoginUser struct {
-		ExternalID    string `xorm:"pk NOT NULL"`
-		UserID        int64  `xorm:"INDEX NOT NULL"`
-		LoginSourceID int64  `xorm:"pk NOT NULL"`
-	}
-
-	extlogins := make([]*ExternalLoginUser, 0, 6)
-	if err := x.Find(&extlogins); err != nil {
-		return fmt.Errorf("Find: %v", err)
-	}
-
-	if err := x.DropTables(new(ExternalLoginUser)); err != nil {
-		return fmt.Errorf("DropTables: %v", err)
-	}
-
-	if err := x.Sync2(new(ExternalLoginUser)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	if _, err := x.Insert(extlogins); err != nil {
-		return fmt.Errorf("Insert: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v31.go b/models/migrations/v31.go
deleted file mode 100644
index b3aef0d665..0000000000
--- a/models/migrations/v31.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"xorm.io/core"
-	"xorm.io/xorm"
-)
-
-func addLoginSourceSyncEnabledColumn(x *xorm.Engine) error {
-	// LoginSource see models/login_source.go
-	type LoginSource struct {
-		ID            int64 `xorm:"pk autoincr"`
-		Type          int
-		Name          string          `xorm:"UNIQUE"`
-		IsActived     bool            `xorm:"INDEX NOT NULL DEFAULT false"`
-		IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"`
-		Cfg           core.Conversion `xorm:"TEXT"`
-
-		Created     time.Time `xorm:"-"`
-		CreatedUnix int64     `xorm:"INDEX"`
-		Updated     time.Time `xorm:"-"`
-		UpdatedUnix int64     `xorm:"INDEX"`
-	}
-
-	if err := x.Sync2(new(LoginSource)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v32.go b/models/migrations/v32.go
deleted file mode 100644
index f5c021cccf..0000000000
--- a/models/migrations/v32.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import "xorm.io/xorm"
-
-func addUnitsToRepoTeam(x *xorm.Engine) error {
-	type Team struct {
-		UnitTypes []int `xorm:"json"`
-	}
-
-	err := x.Sync(new(Team))
-	if err != nil {
-		return err
-	}
-
-	_, err = x.Update(&Team{
-		UnitTypes: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
-	})
-	return err
-}
diff --git a/models/migrations/v33.go b/models/migrations/v33.go
deleted file mode 100644
index 625c5f4a53..0000000000
--- a/models/migrations/v33.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func removeActionColumns(x *xorm.Engine) error {
-	switch {
-	case setting.Database.UseSQLite3:
-		log.Warn("Unable to drop columns in SQLite")
-	case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL:
-		if _, err := x.Exec("ALTER TABLE action DROP COLUMN act_user_name"); err != nil {
-			return fmt.Errorf("DROP COLUMN act_user_name: %v", err)
-		} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_user_name"); err != nil {
-			return fmt.Errorf("DROP COLUMN repo_user_name: %v", err)
-		} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_name"); err != nil {
-			return fmt.Errorf("DROP COLUMN repo_name: %v", err)
-		}
-	default:
-		log.Fatal("Unrecognized DB")
-	}
-	return nil
-}
diff --git a/models/migrations/v34.go b/models/migrations/v34.go
deleted file mode 100644
index 26f0f565f7..0000000000
--- a/models/migrations/v34.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 Gitea. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"xorm.io/xorm"
-)
-
-// Team see models/team.go
-type Team struct {
-	UnitTypes []int `xorm:"json"`
-}
-
-const ownerAccessMode = 4
-
-var allUnitTypes = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
-
-func giveAllUnitsToOwnerTeams(x *xorm.Engine) error {
-	_, err := x.Cols("unit_types").
-		Where("authorize = ?", ownerAccessMode).
-		Update(&Team{UnitTypes: allUnitTypes})
-	return err
-}
diff --git a/models/migrations/v35.go b/models/migrations/v35.go
deleted file mode 100644
index d5059c7998..0000000000
--- a/models/migrations/v35.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addCommentIDToAction(x *xorm.Engine) error {
-	// Action see models/action.go
-	type Action struct {
-		CommentID int64 `xorm:"INDEX"`
-		IsDeleted bool  `xorm:"INDEX NOT NULL DEFAULT false"`
-	}
-
-	if err := x.Sync2(new(Action)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	return nil
-}
diff --git a/models/migrations/v36.go b/models/migrations/v36.go
deleted file mode 100644
index 8027ed2103..0000000000
--- a/models/migrations/v36.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"code.gitea.io/gitea/modules/graceful"
-	repo_module "code.gitea.io/gitea/modules/repository"
-
-	"xorm.io/xorm"
-)
-
-func regenerateGitHooks36(x *xorm.Engine) (err error) {
-	return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
-}
diff --git a/models/migrations/v37.go b/models/migrations/v37.go
deleted file mode 100644
index 29e1c966f3..0000000000
--- a/models/migrations/v37.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"html"
-
-	"xorm.io/xorm"
-)
-
-func unescapeUserFullNames(x *xorm.Engine) (err error) {
-	type User struct {
-		ID       int64 `xorm:"pk autoincr"`
-		FullName string
-	}
-
-	const batchSize = 100
-	for start := 0; ; start += batchSize {
-		users := make([]*User, 0, batchSize)
-		if err := x.Limit(batchSize, start).Find(&users); err != nil {
-			return err
-		}
-		if len(users) == 0 {
-			return nil
-		}
-		for _, user := range users {
-			user.FullName = html.UnescapeString(user.FullName)
-			if _, err := x.ID(user.ID).Cols("full_name").Update(user); err != nil {
-				return err
-			}
-		}
-	}
-}
diff --git a/models/migrations/v38.go b/models/migrations/v38.go
deleted file mode 100644
index 4e4e6628d3..0000000000
--- a/models/migrations/v38.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"time"
-
-	"code.gitea.io/gitea/models"
-
-	"xorm.io/core"
-	"xorm.io/xorm"
-)
-
-func removeCommitsUnitType(x *xorm.Engine) (err error) {
-	// RepoUnit describes all units of a repository
-	type RepoUnit struct {
-		ID          int64
-		RepoID      int64 `xorm:"INDEX(s)"`
-		Type        int   `xorm:"INDEX(s)"`
-		Index       int
-		Config      core.Conversion `xorm:"TEXT"`
-		CreatedUnix int64           `xorm:"INDEX CREATED"`
-		Created     time.Time       `xorm:"-"`
-	}
-
-	type Team struct {
-		ID        int64
-		UnitTypes []int `xorm:"json"`
-	}
-
-	// Update team unit types
-	const batchSize = 100
-	for start := 0; ; start += batchSize {
-		teams := make([]*Team, 0, batchSize)
-		if err := x.Limit(batchSize, start).Find(&teams); err != nil {
-			return err
-		}
-		if len(teams) == 0 {
-			break
-		}
-		for _, team := range teams {
-			ut := make([]int, 0, len(team.UnitTypes))
-			for _, u := range team.UnitTypes {
-				if u < V16UnitTypeCommits {
-					ut = append(ut, u)
-				} else if u > V16UnitTypeSettings {
-					ut = append(ut, u-2)
-				} else if u > V16UnitTypeCommits && u != V16UnitTypeSettings {
-					ut = append(ut, u-1)
-				}
-			}
-			team.UnitTypes = ut
-			if _, err := x.ID(team.ID).Cols("unit_types").Update(team); err != nil {
-				return err
-			}
-		}
-	}
-
-	// Delete commits and settings unit types
-	if _, err = x.In("`type`", []models.UnitType{V16UnitTypeCommits, V16UnitTypeSettings}).Delete(new(RepoUnit)); err != nil {
-		return err
-	}
-	// Fix renumber unit types that where in enumeration after settings unit type
-	if _, err = x.Where("`type` > ?", V16UnitTypeSettings).Decr("type").Decr("index").Update(new(RepoUnit)); err != nil {
-		return err
-	}
-	// Fix renumber unit types that where in enumeration after commits unit type
-	if _, err = x.Where("`type` > ?", V16UnitTypeCommits).Decr("type").Decr("index").Update(new(RepoUnit)); err != nil {
-		return err
-	}
-
-	return nil
-}
diff --git a/models/migrations/v39.go b/models/migrations/v39.go
deleted file mode 100644
index e0b84b969c..0000000000
--- a/models/migrations/v39.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/models"
-	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/repository"
-
-	"xorm.io/xorm"
-)
-
-// ReleaseV39 describes the added field for Release
-type ReleaseV39 struct {
-	IsTag bool `xorm:"NOT NULL DEFAULT false"`
-}
-
-// TableName will be invoked by XORM to customrize the table name
-func (*ReleaseV39) TableName() string {
-	return "release"
-}
-
-func releaseAddColumnIsTagAndSyncTags(x *xorm.Engine) error {
-	if err := x.Sync2(new(ReleaseV39)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	// For the sake of SQLite3, we can't use x.Iterate here.
-	offset := 0
-	pageSize := models.RepositoryListDefaultPageSize
-	for {
-		repos := make([]*models.Repository, 0, pageSize)
-		if err := x.Table("repository").Cols("id", "name", "owner_id").Asc("id").Limit(pageSize, offset).Find(&repos); err != nil {
-			return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
-		}
-		for _, repo := range repos {
-			gitRepo, err := git.OpenRepository(repo.RepoPath())
-			if err != nil {
-				log.Warn("OpenRepository: %v", err)
-				continue
-			}
-
-			if err = repository.SyncReleasesWithTags(repo, gitRepo); err != nil {
-				log.Warn("SyncReleasesWithTags: %v", err)
-			}
-			gitRepo.Close()
-		}
-		if len(repos) < pageSize {
-			break
-		}
-		offset += pageSize
-	}
-	return nil
-}
diff --git a/models/migrations/v40.go b/models/migrations/v40.go
deleted file mode 100644
index 944377ce9b..0000000000
--- a/models/migrations/v40.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func fixProtectedBranchCanPushValue(x *xorm.Engine) error {
-	type ProtectedBranch struct {
-		CanPush bool `xorm:"NOT NULL DEFAULT false"`
-	}
-
-	if err := x.Sync2(new(ProtectedBranch)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	_, err := x.Cols("can_push").Update(&ProtectedBranch{
-		CanPush: false,
-	})
-	return err
-}
diff --git a/models/migrations/v41.go b/models/migrations/v41.go
deleted file mode 100644
index 928bb1cd3f..0000000000
--- a/models/migrations/v41.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func removeDuplicateUnitTypes(x *xorm.Engine) error {
-	// RepoUnit describes all units of a repository
-	type RepoUnit struct {
-		RepoID int64
-		Type   int
-	}
-
-	// Enumerate all the unit types
-	const (
-		UnitTypeCode            = iota + 1 // 1 code
-		UnitTypeIssues                     // 2 issues
-		UnitTypePullRequests               // 3 PRs
-		UnitTypeReleases                   // 4 Releases
-		UnitTypeWiki                       // 5 Wiki
-		UnitTypeExternalWiki               // 6 ExternalWiki
-		UnitTypeExternalTracker            // 7 ExternalTracker
-	)
-
-	var externalIssueRepoUnits []RepoUnit
-	err := x.Where("type = ?", UnitTypeExternalTracker).Find(&externalIssueRepoUnits)
-	if err != nil {
-		return fmt.Errorf("Query repositories: %v", err)
-	}
-
-	var externalWikiRepoUnits []RepoUnit
-	err = x.Where("type = ?", UnitTypeExternalWiki).Find(&externalWikiRepoUnits)
-	if err != nil {
-		return fmt.Errorf("Query repositories: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	for _, repoUnit := range externalIssueRepoUnits {
-		if _, err = sess.Delete(&RepoUnit{
-			RepoID: repoUnit.RepoID,
-			Type:   UnitTypeIssues,
-		}); err != nil {
-			return fmt.Errorf("Delete repo unit: %v", err)
-		}
-	}
-
-	for _, repoUnit := range externalWikiRepoUnits {
-		if _, err = sess.Delete(&RepoUnit{
-			RepoID: repoUnit.RepoID,
-			Type:   UnitTypeWiki,
-		}); err != nil {
-			return fmt.Errorf("Delete repo unit: %v", err)
-		}
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v45.go b/models/migrations/v45.go
deleted file mode 100644
index eb346d7b3a..0000000000
--- a/models/migrations/v45.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func removeIndexColumnFromRepoUnitTable(x *xorm.Engine) (err error) {
-	switch {
-	case setting.Database.UseSQLite3:
-		log.Warn("Unable to drop columns in SQLite")
-	case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL:
-		if _, err := x.Exec("ALTER TABLE repo_unit DROP COLUMN `index`"); err != nil {
-			// Ignoring this error in case we run this migration second time (after migration reordering)
-			log.Warn("DROP COLUMN index: %v", err)
-		}
-	default:
-		log.Fatal("Unrecognized DB")
-	}
-
-	return nil
-}
diff --git a/models/migrations/v46.go b/models/migrations/v46.go
deleted file mode 100644
index 3d9c1329d8..0000000000
--- a/models/migrations/v46.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"xorm.io/xorm"
-)
-
-func removeOrganizationWatchRepo(x *xorm.Engine) error {
-	// UserType defines the user type
-	type UserType int
-
-	const (
-		// UserTypeIndividual defines an individual user
-		UserTypeIndividual UserType = iota // Historic reason to make it starts at 0.
-
-		// UserTypeOrganization defines an organization
-		UserTypeOrganization
-	)
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-	if _, err := sess.Exec("DELETE FROM `watch` WHERE `user_id` IN (SELECT `id` FROM `user` WHERE `type` = ?)", UserTypeOrganization); err != nil {
-		return err
-	}
-	if _, err := sess.Exec("UPDATE `repository` SET num_watches = (SELECT count(*) FROM watch WHERE `repository`.`id` = watch.repo_id)"); err != nil {
-		return err
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v47.go b/models/migrations/v47.go
deleted file mode 100644
index 81f92e2f5a..0000000000
--- a/models/migrations/v47.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addDeletedBranch(x *xorm.Engine) (err error) {
-	// DeletedBranch contains the deleted branch information
-	type DeletedBranch struct {
-		ID          int64  `xorm:"pk autoincr"`
-		RepoID      int64  `xorm:"UNIQUE(s) INDEX NOT NULL"`
-		Name        string `xorm:"UNIQUE(s) NOT NULL"`
-		Commit      string `xorm:"UNIQUE(s) NOT NULL"`
-		DeletedByID int64  `xorm:"INDEX NOT NULL"`
-		DeletedUnix int64  `xorm:"INDEX"`
-	}
-
-	if err = x.Sync2(new(DeletedBranch)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	return nil
-}
diff --git a/models/migrations/v48.go b/models/migrations/v48.go
deleted file mode 100644
index 6365feba89..0000000000
--- a/models/migrations/v48.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addRepoIndexerStatus(x *xorm.Engine) error {
-	// RepoIndexerStatus see models/repo_indexer.go
-	type RepoIndexerStatus struct {
-		ID        int64  `xorm:"pk autoincr"`
-		RepoID    int64  `xorm:"INDEX NOT NULL"`
-		CommitSha string `xorm:"VARCHAR(40)"`
-	}
-
-	if err := x.Sync2(new(RepoIndexerStatus)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v49.go b/models/migrations/v49.go
deleted file mode 100644
index 4776125137..0000000000
--- a/models/migrations/v49.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func addTimetracking(x *xorm.Engine) error {
-	// RepoUnit describes all units of a repository
-	type RepoUnit struct {
-		ID          int64
-		RepoID      int64                  `xorm:"INDEX(s)"`
-		Type        int                    `xorm:"INDEX(s)"`
-		Config      map[string]interface{} `xorm:"JSON"`
-		CreatedUnix int64                  `xorm:"INDEX CREATED"`
-		Created     time.Time              `xorm:"-"`
-	}
-
-	// Stopwatch see models/issue_stopwatch.go
-	type Stopwatch struct {
-		ID          int64     `xorm:"pk autoincr"`
-		IssueID     int64     `xorm:"INDEX"`
-		UserID      int64     `xorm:"INDEX"`
-		Created     time.Time `xorm:"-"`
-		CreatedUnix int64
-	}
-
-	// TrackedTime see models/issue_tracked_time.go
-	type TrackedTime struct {
-		ID          int64     `xorm:"pk autoincr" json:"id"`
-		IssueID     int64     `xorm:"INDEX" json:"issue_id"`
-		UserID      int64     `xorm:"INDEX" json:"user_id"`
-		Created     time.Time `xorm:"-" json:"created"`
-		CreatedUnix int64     `json:"-"`
-		Time        int64     `json:"time"`
-	}
-
-	if err := x.Sync2(new(Stopwatch)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	if err := x.Sync2(new(TrackedTime)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	//Updating existing issue units
-	units := make([]*RepoUnit, 0, 100)
-	err := x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
-	if err != nil {
-		return fmt.Errorf("Query repo units: %v", err)
-	}
-	for _, unit := range units {
-		if unit.Config == nil {
-			unit.Config = make(map[string]interface{})
-		}
-		if _, ok := unit.Config["EnableTimetracker"]; !ok {
-			unit.Config["EnableTimetracker"] = setting.Service.DefaultEnableTimetracking
-		}
-		if _, ok := unit.Config["AllowOnlyContributorsToTrackTime"]; !ok {
-			unit.Config["AllowOnlyContributorsToTrackTime"] = setting.Service.DefaultAllowOnlyContributorsToTrackTime
-		}
-		if _, err := x.ID(unit.ID).Cols("config").Update(unit); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/models/migrations/v50.go b/models/migrations/v50.go
deleted file mode 100644
index ddc378b432..0000000000
--- a/models/migrations/v50.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"time"
-
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func migrateProtectedBranchStruct(x *xorm.Engine) error {
-	type ProtectedBranch struct {
-		ID          int64  `xorm:"pk autoincr"`
-		RepoID      int64  `xorm:"UNIQUE(s)"`
-		BranchName  string `xorm:"UNIQUE(s)"`
-		CanPush     bool
-		Created     time.Time `xorm:"-"`
-		CreatedUnix int64
-		Updated     time.Time `xorm:"-"`
-		UpdatedUnix int64
-	}
-
-	var pbs []ProtectedBranch
-	err := x.Find(&pbs)
-	if err != nil {
-		return err
-	}
-
-	for _, pb := range pbs {
-		if pb.CanPush {
-			if _, err = x.ID(pb.ID).Delete(new(ProtectedBranch)); err != nil {
-				return err
-			}
-		}
-	}
-
-	switch {
-	case setting.Database.UseSQLite3:
-		log.Warn("Unable to drop columns in SQLite")
-	case setting.Database.UseMySQL, setting.Database.UsePostgreSQL, setting.Database.UseMSSQL:
-		if _, err := x.Exec("ALTER TABLE protected_branch DROP COLUMN can_push"); err != nil {
-			// Ignoring this error in case we run this migration second time (after migration reordering)
-			log.Warn("DROP COLUMN can_push (skipping): %v", err)
-		}
-	default:
-		log.Fatal("Unrecognized DB")
-	}
-
-	return nil
-}
diff --git a/models/migrations/v51.go b/models/migrations/v51.go
deleted file mode 100644
index 8dadcf3349..0000000000
--- a/models/migrations/v51.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"code.gitea.io/gitea/models"
-	"code.gitea.io/gitea/modules/log"
-
-	"xorm.io/xorm"
-)
-
-func addDefaultValueToUserProhibitLogin(x *xorm.Engine) (err error) {
-	user := &models.User{
-		ProhibitLogin: false,
-	}
-
-	if _, err := x.Where("`prohibit_login` IS NULL").Cols("prohibit_login").Update(user); err != nil {
-		return err
-	}
-
-	dialect := x.Dialect().DriverName()
-
-	switch dialect {
-	case "mysql":
-		_, err = x.Exec("ALTER TABLE user MODIFY `prohibit_login` tinyint(1) NOT NULL DEFAULT 0")
-	case "postgres":
-		_, err = x.Exec("ALTER TABLE \"user\" ALTER COLUMN `prohibit_login` SET NOT NULL, ALTER COLUMN `prohibit_login` SET DEFAULT false")
-	case "mssql":
-		// xorm already set DEFAULT 0 for data type BIT in mssql
-		_, err = x.Exec(`ALTER TABLE [user] ALTER COLUMN "prohibit_login" BIT NOT NULL`)
-	case "sqlite3":
-	}
-
-	if err != nil {
-		// Ignoring this error in case we run this migration second time (after migration reordering)
-		log.Warn("Error changing user prohibit_login column definition (skipping): %v", err)
-	}
-
-	return nil
-}
diff --git a/models/migrations/v52.go b/models/migrations/v52.go
deleted file mode 100644
index 6547698d5b..0000000000
--- a/models/migrations/v52.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"time"
-
-	"code.gitea.io/gitea/models"
-
-	"xorm.io/xorm"
-)
-
-func addLFSLock(x *xorm.Engine) error {
-	// LFSLock see models/lfs_lock.go
-	type LFSLock struct {
-		ID      int64        `xorm:"pk autoincr"`
-		RepoID  int64        `xorm:"INDEX NOT NULL"`
-		Owner   *models.User `xorm:"-"`
-		OwnerID int64        `xorm:"INDEX NOT NULL"`
-		Path    string       `xorm:"TEXT"`
-		Created time.Time    `xorm:"created"`
-	}
-
-	if err := x.Sync2(new(LFSLock)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v53.go b/models/migrations/v53.go
deleted file mode 100644
index a3068cdb00..0000000000
--- a/models/migrations/v53.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addReactions(x *xorm.Engine) error {
-	// Reaction see models/issue_reaction.go
-	type Reaction struct {
-		ID          int64  `xorm:"pk autoincr"`
-		Type        string `xorm:"INDEX UNIQUE(s) NOT NULL"`
-		IssueID     int64  `xorm:"INDEX UNIQUE(s) NOT NULL"`
-		CommentID   int64  `xorm:"INDEX UNIQUE(s)"`
-		UserID      int64  `xorm:"INDEX UNIQUE(s) NOT NULL"`
-		CreatedUnix int64  `xorm:"INDEX created"`
-	}
-
-	if err := x.Sync2(new(Reaction)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v54.go b/models/migrations/v54.go
deleted file mode 100644
index af1e287419..0000000000
--- a/models/migrations/v54.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/modules/timeutil"
-
-	"xorm.io/xorm"
-)
-
-func addPullRequestOptions(x *xorm.Engine) error {
-	// RepoUnit describes all units of a repository
-	type RepoUnit struct {
-		ID          int64
-		RepoID      int64                  `xorm:"INDEX(s)"`
-		Type        int                    `xorm:"INDEX(s)"`
-		Config      map[string]interface{} `xorm:"JSON"`
-		CreatedUnix timeutil.TimeStamp     `xorm:"INDEX CREATED"`
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	//Updating existing issue units
-	units := make([]*RepoUnit, 0, 100)
-	if err := sess.Where("`type` = ?", V16UnitTypePRs).Find(&units); err != nil {
-		return fmt.Errorf("Query repo units: %v", err)
-	}
-	for _, unit := range units {
-		if unit.Config == nil {
-			unit.Config = make(map[string]interface{})
-		}
-		if _, ok := unit.Config["IgnoreWhitespaceConflicts"]; !ok {
-			unit.Config["IgnoreWhitespaceConflicts"] = false
-		}
-		if _, ok := unit.Config["AllowMerge"]; !ok {
-			unit.Config["AllowMerge"] = true
-		}
-		if _, ok := unit.Config["AllowRebase"]; !ok {
-			unit.Config["AllowRebase"] = true
-		}
-		if _, ok := unit.Config["AllowSquash"]; !ok {
-			unit.Config["AllowSquash"] = true
-		}
-		if _, err := sess.ID(unit.ID).Cols("config").Update(unit); err != nil {
-			return err
-		}
-	}
-	return sess.Commit()
-}
diff --git a/models/migrations/v55.go b/models/migrations/v55.go
deleted file mode 100644
index a259e4f001..0000000000
--- a/models/migrations/v55.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/models"
-
-	"xorm.io/xorm"
-)
-
-func addModeToDeploKeys(x *xorm.Engine) error {
-	type DeployKey struct {
-		Mode models.AccessMode `xorm:"NOT NULL DEFAULT 1"`
-	}
-
-	if err := x.Sync2(new(DeployKey)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v56.go b/models/migrations/v56.go
deleted file mode 100644
index 4e1cafcca2..0000000000
--- a/models/migrations/v56.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"xorm.io/xorm"
-)
-
-func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) {
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err = sess.Begin(); err != nil {
-		return err
-	}
-
-	if err := dropTableColumns(sess, "org_user", "is_owner", "num_teams"); err != nil {
-		return err
-	}
-	return sess.Commit()
-}
diff --git a/models/migrations/v57.go b/models/migrations/v57.go
deleted file mode 100644
index 6c0ab6f496..0000000000
--- a/models/migrations/v57.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/modules/timeutil"
-
-	"xorm.io/xorm"
-)
-
-func addIssueClosedTime(x *xorm.Engine) error {
-	// Issue see models/issue.go
-	type Issue struct {
-		ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
-	}
-
-	if err := x.Sync2(new(Issue)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	if _, err := x.Exec("UPDATE `issue` SET `closed_unix` = `updated_unix` WHERE `is_closed` = ?", true); err != nil {
-		return err
-	}
-
-	return nil
-}
diff --git a/models/migrations/v58.go b/models/migrations/v58.go
deleted file mode 100644
index 0fa3bcfe2d..0000000000
--- a/models/migrations/v58.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addLabelsDescriptions(x *xorm.Engine) error {
-	type Label struct {
-		Description string
-	}
-
-	if err := x.Sync2(new(Label)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v59.go b/models/migrations/v59.go
deleted file mode 100644
index d442f2569e..0000000000
--- a/models/migrations/v59.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addProtectedBranchMergeWhitelist(x *xorm.Engine) error {
-	type ProtectedBranch struct {
-		EnableMergeWhitelist  bool    `xorm:"NOT NULL DEFAULT false"`
-		MergeWhitelistUserIDs []int64 `xorm:"JSON TEXT"`
-		MergeWhitelistTeamIDs []int64 `xorm:"JSON TEXT"`
-	}
-
-	if err := x.Sync2(new(ProtectedBranch)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v60.go b/models/migrations/v60.go
deleted file mode 100644
index 6482e8e4a5..0000000000
--- a/models/migrations/v60.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addFsckEnabledToRepo(x *xorm.Engine) error {
-	type Repository struct {
-		IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
-	}
-
-	if err := x.Sync2(new(Repository)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v61.go b/models/migrations/v61.go
deleted file mode 100644
index 13affaf068..0000000000
--- a/models/migrations/v61.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"os"
-	"path"
-
-	"code.gitea.io/gitea/modules/log"
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func addSizeToAttachment(x *xorm.Engine) error {
-	type Attachment struct {
-		ID   int64  `xorm:"pk autoincr"`
-		UUID string `xorm:"uuid UNIQUE"`
-		Size int64  `xorm:"DEFAULT 0"`
-	}
-	if err := x.Sync2(new(Attachment)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	attachments := make([]Attachment, 0, 100)
-	if err := x.Find(&attachments); err != nil {
-		return fmt.Errorf("query attachments: %v", err)
-	}
-	for _, attach := range attachments {
-		localPath := path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID)
-		fi, err := os.Stat(localPath)
-		if err != nil {
-			log.Error("calculate file size of attachment[UUID: %s]: %v", attach.UUID, err)
-			continue
-		}
-		attach.Size = fi.Size()
-		if _, err := x.ID(attach.ID).Cols("size").Update(attach); err != nil {
-			return fmt.Errorf("update size column: %v", err)
-		}
-	}
-	return nil
-}
diff --git a/models/migrations/v62.go b/models/migrations/v62.go
deleted file mode 100644
index e7f6cf6890..0000000000
--- a/models/migrations/v62.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addLastUsedPasscodeTOTP(x *xorm.Engine) error {
-	type TwoFactor struct {
-		LastUsedPasscode string `xorm:"VARCHAR(10)"`
-	}
-
-	if err := x.Sync2(new(TwoFactor)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v63.go b/models/migrations/v63.go
deleted file mode 100644
index 62e8a299f6..0000000000
--- a/models/migrations/v63.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addLanguageSetting(x *xorm.Engine) error {
-	type User struct {
-		Language string `xorm:"VARCHAR(5)"`
-	}
-
-	if err := x.Sync2(new(User)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	return nil
-}
diff --git a/models/migrations/v64.go b/models/migrations/v64.go
deleted file mode 100644
index 623cceddbc..0000000000
--- a/models/migrations/v64.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"code.gitea.io/gitea/modules/timeutil"
-
-	"xorm.io/xorm"
-)
-
-func addMultipleAssignees(x *xorm.Engine) error {
-
-	// Redeclare issue struct
-	type Issue struct {
-		ID          int64  `xorm:"pk autoincr"`
-		RepoID      int64  `xorm:"INDEX UNIQUE(repo_index)"`
-		Index       int64  `xorm:"UNIQUE(repo_index)"` // Index in one repository.
-		PosterID    int64  `xorm:"INDEX"`
-		Title       string `xorm:"name"`
-		Content     string `xorm:"TEXT"`
-		MilestoneID int64  `xorm:"INDEX"`
-		Priority    int
-		AssigneeID  int64 `xorm:"INDEX"`
-		IsClosed    bool  `xorm:"INDEX"`
-		IsPull      bool  `xorm:"INDEX"` // Indicates whether is a pull request or not.
-		NumComments int
-
-		DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
-		CreatedUnix  timeutil.TimeStamp `xorm:"INDEX created"`
-		UpdatedUnix  timeutil.TimeStamp `xorm:"INDEX updated"`
-		ClosedUnix   timeutil.TimeStamp `xorm:"INDEX"`
-	}
-
-	// Updated the comment table
-	type Comment struct {
-		ID              int64 `xorm:"pk autoincr"`
-		Type            int
-		PosterID        int64 `xorm:"INDEX"`
-		IssueID         int64 `xorm:"INDEX"`
-		LabelID         int64
-		OldMilestoneID  int64
-		MilestoneID     int64
-		OldAssigneeID   int64
-		AssigneeID      int64
-		RemovedAssignee bool
-		OldTitle        string
-		NewTitle        string
-
-		CommitID        int64
-		Line            int64
-		Content         string `xorm:"TEXT"`
-		RenderedContent string `xorm:"-"`
-
-		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
-		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
-
-		// Reference issue in commit message
-		CommitSHA string `xorm:"VARCHAR(40)"`
-	}
-
-	// Create the table
-	type IssueAssignees struct {
-		ID         int64 `xorm:"pk autoincr"`
-		AssigneeID int64 `xorm:"INDEX"`
-		IssueID    int64 `xorm:"INDEX"`
-	}
-
-	if err := x.Sync2(IssueAssignees{}); err != nil {
-		return err
-	}
-
-	if err := x.Sync2(Comment{}); err != nil {
-		return err
-	}
-
-	// Range over all issues and insert a new entry for each issue/assignee
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	allIssues := []*Issue{}
-	if err := sess.Find(&allIssues); err != nil {
-		return err
-	}
-
-	for _, issue := range allIssues {
-		if issue.AssigneeID != 0 {
-			_, err := sess.Insert(IssueAssignees{IssueID: issue.ID, AssigneeID: issue.AssigneeID})
-			if err != nil {
-				sess.Rollback()
-				return err
-			}
-		}
-	}
-
-	// Migrate comments
-	// First update everything to not have nulls in db
-	if _, err := sess.Where("type = ?", 9).Cols("removed_assignee").Update(Comment{RemovedAssignee: false}); err != nil {
-		return err
-	}
-
-	allAssignementComments := []*Comment{}
-	if err := sess.Where("type = ?", 9).Find(&allAssignementComments); err != nil {
-		return err
-	}
-
-	for _, comment := range allAssignementComments {
-		// Everytime where OldAssigneeID is > 0, the assignement was removed.
-		if comment.OldAssigneeID > 0 {
-			_, err := sess.ID(comment.ID).Update(Comment{RemovedAssignee: true})
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	// Commit and begin new transaction for dropping columns
-	if err := sess.Commit(); err != nil {
-		return err
-	}
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	if err := dropTableColumns(sess, "issue", "assignee_id"); err != nil {
-		return err
-	}
-
-	if err := dropTableColumns(sess, "issue_user", "is_assigned"); err != nil {
-		return err
-	}
-	return sess.Commit()
-}
diff --git a/models/migrations/v65.go b/models/migrations/v65.go
deleted file mode 100644
index a87f8bc76c..0000000000
--- a/models/migrations/v65.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package migrations
-
-import (
-	"code.gitea.io/gitea/modules/timeutil"
-
-	"xorm.io/xorm"
-)
-
-func addU2FReg(x *xorm.Engine) error {
-	type U2FRegistration struct {
-		ID          int64 `xorm:"pk autoincr"`
-		Name        string
-		UserID      int64 `xorm:"INDEX"`
-		Raw         []byte
-		Counter     uint32
-		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
-		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
-	}
-	return x.Sync2(&U2FRegistration{})
-}
diff --git a/models/migrations/v66.go b/models/migrations/v66.go
deleted file mode 100644
index 8e9df97fea..0000000000
--- a/models/migrations/v66.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func addLoginSourceIDToPublicKeyTable(x *xorm.Engine) error {
-	type PublicKey struct {
-		LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
-	}
-
-	if err := x.Sync2(new(PublicKey)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	return nil
-}
diff --git a/models/migrations/v67.go b/models/migrations/v67.go
deleted file mode 100644
index dee744e4d3..0000000000
--- a/models/migrations/v67.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"code.gitea.io/gitea/modules/setting"
-
-	"xorm.io/xorm"
-)
-
-func removeStaleWatches(x *xorm.Engine) error {
-	type Watch struct {
-		ID     int64
-		UserID int64
-		RepoID int64
-	}
-
-	type IssueWatch struct {
-		ID         int64
-		UserID     int64
-		RepoID     int64
-		IsWatching bool
-	}
-
-	type Repository struct {
-		ID        int64
-		IsPrivate bool
-		OwnerID   int64
-	}
-
-	type Access struct {
-		UserID int64
-		RepoID int64
-		Mode   int
-	}
-
-	const (
-		// AccessModeNone no access
-		AccessModeNone int = iota // 0
-		// AccessModeRead read access
-		AccessModeRead // 1
-	)
-
-	accessLevel := func(e *xorm.Session, userID int64, repo *Repository) (int, error) {
-		mode := AccessModeNone
-		if !repo.IsPrivate {
-			mode = AccessModeRead
-		}
-
-		if userID == 0 {
-			return mode, nil
-		}
-
-		if userID == repo.OwnerID {
-			return 4, nil
-		}
-
-		a := &Access{UserID: userID, RepoID: repo.ID}
-		if has, err := e.Get(a); !has || err != nil {
-			return mode, err
-		}
-		return a.Mode, nil
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	var issueWatch IssueWatch
-	if exist, err := sess.IsTableExist(&issueWatch); err != nil {
-		return fmt.Errorf("IsExist IssueWatch: %v", err)
-	} else if !exist {
-		return nil
-	}
-
-	repoCache := make(map[int64]*Repository)
-	err := sess.BufferSize(setting.Database.IterateBufferSize).Iterate(new(Watch),
-		func(idx int, bean interface{}) error {
-			watch := bean.(*Watch)
-
-			repo := repoCache[watch.RepoID]
-			if repo == nil {
-				repo = &Repository{
-					ID: watch.RepoID,
-				}
-				if _, err := sess.Get(repo); err != nil {
-					return err
-				}
-				repoCache[watch.RepoID] = repo
-			}
-
-			// Remove watches from now unaccessible repositories
-			mode, err := accessLevel(sess, watch.UserID, repo)
-			if err != nil {
-				return err
-			}
-			has := AccessModeRead <= mode
-			if has {
-				return nil
-			}
-
-			if _, err = sess.Delete(&Watch{0, watch.UserID, repo.ID}); err != nil {
-				return err
-			}
-			_, err = sess.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repo.ID)
-
-			return err
-		})
-	if err != nil {
-		return err
-	}
-
-	repoCache = make(map[int64]*Repository)
-	err = sess.BufferSize(setting.Database.IterateBufferSize).
-		Distinct("issue_watch.user_id", "issue.repo_id").
-		Join("INNER", "issue", "issue_watch.issue_id = issue.id").
-		Where("issue_watch.is_watching = ?", true).
-		Iterate(new(IssueWatch),
-			func(idx int, bean interface{}) error {
-				watch := bean.(*IssueWatch)
-
-				repo := repoCache[watch.RepoID]
-				if repo == nil {
-					repo = &Repository{
-						ID: watch.RepoID,
-					}
-					if _, err := sess.Get(repo); err != nil {
-						return err
-					}
-					repoCache[watch.RepoID] = repo
-				}
-
-				// Remove issue watches from now unaccssible repositories
-				mode, err := accessLevel(sess, watch.UserID, repo)
-				if err != nil {
-					return err
-				}
-				has := AccessModeRead <= mode
-				if has {
-					return nil
-				}
-
-				iw := &IssueWatch{
-					IsWatching: false,
-				}
-
-				_, err = sess.
-					Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", watch.RepoID).
-					Cols("is_watching", "updated_unix").
-					Where("`issue_watch`.user_id = ?", watch.UserID).
-					Update(iw)
-
-				return err
-
-			})
-	if err != nil {
-		return err
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v68.go b/models/migrations/v68.go
deleted file mode 100644
index 41c1f8f71d..0000000000
--- a/models/migrations/v68.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-	"regexp"
-	"strings"
-
-	"code.gitea.io/gitea/modules/log"
-
-	"xorm.io/xorm"
-)
-
-var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
-
-func validateTopic(topic string) bool {
-	return len(topic) <= 35 && topicPattern.MatchString(topic)
-}
-
-func reformatAndRemoveIncorrectTopics(x *xorm.Engine) (err error) {
-	log.Info("This migration could take up to minutes, please be patient.")
-
-	type Topic struct {
-		ID          int64
-		Name        string `xorm:"UNIQUE VARCHAR(25)"`
-		RepoCount   int
-		CreatedUnix int64 `xorm:"INDEX created"`
-		UpdatedUnix int64 `xorm:"INDEX updated"`
-	}
-
-	type RepoTopic struct {
-		RepoID  int64 `xorm:"UNIQUE(s)"`
-		TopicID int64 `xorm:"UNIQUE(s)"`
-	}
-
-	type Repository struct {
-		ID     int64    `xorm:"pk autoincr"`
-		Topics []string `xorm:"TEXT JSON"`
-	}
-
-	if err := x.Sync2(new(Topic)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-	if err := x.Sync2(new(RepoTopic)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-
-	const batchSize = 100
-	touchedRepo := make(map[int64]struct{})
-	delTopicIDs := make([]int64, 0, batchSize)
-
-	log.Info("Validating existed topics...")
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-	for start := 0; ; start += batchSize {
-		topics := make([]*Topic, 0, batchSize)
-		if err := x.Cols("id", "name").Asc("id").Limit(batchSize, start).Find(&topics); err != nil {
-			return err
-		}
-		if len(topics) == 0 {
-			break
-		}
-		for _, topic := range topics {
-			if validateTopic(topic.Name) {
-				continue
-			}
-			log.Info("Incorrect topic: id = %v, name = %q", topic.ID, topic.Name)
-
-			topic.Name = strings.Replace(strings.TrimSpace(strings.ToLower(topic.Name)), " ", "-", -1)
-
-			ids := make([]int64, 0, 30)
-			if err := sess.Table("repo_topic").Cols("repo_id").
-				Where("topic_id = ?", topic.ID).Find(&ids); err != nil {
-				return err
-			}
-			log.Info("Touched repo ids: %v", ids)
-			for _, id := range ids {
-				touchedRepo[id] = struct{}{}
-			}
-
-			if validateTopic(topic.Name) {
-				unifiedTopic := Topic{Name: topic.Name}
-				exists, err := sess.Cols("id", "name").Get(&unifiedTopic)
-				log.Info("Exists topic with the name %q? %v, id = %v", topic.Name, exists, unifiedTopic.ID)
-				if err != nil {
-					return err
-				}
-				if exists {
-					log.Info("Updating repo_topic rows with topic_id = %v to topic_id = %v", topic.ID, unifiedTopic.ID)
-					if _, err := sess.Where("topic_id = ? AND repo_id NOT IN "+
-						"(SELECT rt1.repo_id FROM repo_topic rt1 INNER JOIN repo_topic rt2 "+
-						"ON rt1.repo_id = rt2.repo_id WHERE rt1.topic_id = ? AND rt2.topic_id = ?)",
-						topic.ID, topic.ID, unifiedTopic.ID).Update(&RepoTopic{TopicID: unifiedTopic.ID}); err != nil {
-						return err
-					}
-					log.Info("Updating topic `repo_count` field")
-					if _, err := sess.Exec(
-						"UPDATE topic SET repo_count = (SELECT COUNT(*) FROM repo_topic WHERE topic_id = ? GROUP BY topic_id) WHERE id = ?",
-						unifiedTopic.ID, unifiedTopic.ID); err != nil {
-						return err
-					}
-				} else {
-					log.Info("Updating topic: id = %v, name = %q", topic.ID, topic.Name)
-					if _, err := sess.Table("topic").ID(topic.ID).
-						Update(&Topic{Name: topic.Name}); err != nil {
-						return err
-					}
-					continue
-				}
-			}
-			delTopicIDs = append(delTopicIDs, topic.ID)
-		}
-	}
-	if err := sess.Commit(); err != nil {
-		return err
-	}
-
-	sess.Init()
-
-	log.Info("Deleting incorrect topics...")
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-	log.Info("Deleting 'repo_topic' rows for topics with ids = %v", delTopicIDs)
-	if _, err := sess.In("topic_id", delTopicIDs).Delete(&RepoTopic{}); err != nil {
-		return err
-	}
-	log.Info("Deleting topics with id = %v", delTopicIDs)
-	if _, err := sess.In("id", delTopicIDs).Delete(&Topic{}); err != nil {
-		return err
-	}
-	if err := sess.Commit(); err != nil {
-		return err
-	}
-
-	delRepoTopics := make([]*RepoTopic, 0, batchSize)
-
-	log.Info("Checking the number of topics in the repositories...")
-	for start := 0; ; start += batchSize {
-		repoTopics := make([]*RepoTopic, 0, batchSize)
-		if err := x.Cols("repo_id").Asc("repo_id").Limit(batchSize, start).
-			GroupBy("repo_id").Having("COUNT(*) > 25").Find(&repoTopics); err != nil {
-			return err
-		}
-		if len(repoTopics) == 0 {
-			break
-		}
-
-		log.Info("Number of repositories with more than 25 topics: %v", len(repoTopics))
-		for _, repoTopic := range repoTopics {
-			touchedRepo[repoTopic.RepoID] = struct{}{}
-
-			tmpRepoTopics := make([]*RepoTopic, 0, 30)
-			if err := x.Where("repo_id = ?", repoTopic.RepoID).Find(&tmpRepoTopics); err != nil {
-				return err
-			}
-
-			log.Info("Repository with id = %v has %v topics", repoTopic.RepoID, len(tmpRepoTopics))
-
-			for i := len(tmpRepoTopics) - 1; i > 24; i-- {
-				delRepoTopics = append(delRepoTopics, tmpRepoTopics[i])
-			}
-		}
-	}
-
-	sess.Init()
-
-	log.Info("Deleting superfluous topics for repositories (more than 25 topics)...")
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-	for _, repoTopic := range delRepoTopics {
-		log.Info("Deleting 'repo_topic' rows for 'repository' with id = %v. Topic id = %v",
-			repoTopic.RepoID, repoTopic.TopicID)
-
-		if _, err := sess.Where("repo_id = ? AND topic_id = ?", repoTopic.RepoID,
-			repoTopic.TopicID).Delete(&RepoTopic{}); err != nil {
-			return err
-		}
-		if _, err := sess.Exec(
-			"UPDATE topic SET repo_count = (SELECT repo_count FROM topic WHERE id = ?) - 1 WHERE id = ?",
-			repoTopic.TopicID, repoTopic.TopicID); err != nil {
-			return err
-		}
-	}
-
-	log.Info("Updating repositories 'topics' fields...")
-	for repoID := range touchedRepo {
-		topicNames := make([]string, 0, 30)
-		if err := sess.Table("topic").Cols("name").
-			Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
-			Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
-			return err
-		}
-		log.Info("Updating 'topics' field for repository with id = %v", repoID)
-		if _, err := sess.ID(repoID).Cols("topics").
-			Update(&Repository{Topics: topicNames}); err != nil {
-			return err
-		}
-	}
-
-	return sess.Commit()
-}
diff --git a/models/migrations/v69.go b/models/migrations/v69.go
deleted file mode 100644
index a08747edff..0000000000
--- a/models/migrations/v69.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package migrations
-
-import (
-	"fmt"
-
-	"xorm.io/xorm"
-)
-
-func moveTeamUnitsToTeamUnitTable(x *xorm.Engine) error {
-	// Team see models/team.go
-	type Team struct {
-		ID        int64
-		OrgID     int64
-		UnitTypes []int `xorm:"json"`
-	}
-
-	// TeamUnit see models/org_team.go
-	type TeamUnit struct {
-		ID     int64 `xorm:"pk autoincr"`
-		OrgID  int64 `xorm:"INDEX"`
-		TeamID int64 `xorm:"UNIQUE(s)"`
-		Type   int   `xorm:"UNIQUE(s)"`
-	}
-
-	if err := x.Sync2(new(TeamUnit)); err != nil {
-		return fmt.Errorf("Sync2: %v", err)
-	}
-
-	sess := x.NewSession()
-	defer sess.Close()
-
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	// Update team unit types
-	const batchSize = 100
-	for start := 0; ; start += batchSize {
-		teams := make([]*Team, 0, batchSize)
-		if err := x.Limit(batchSize, start).Find(&teams); err != nil {
-			return err
-		}
-		if len(teams) == 0 {
-			break
-		}
-
-		for _, team := range teams {
-			var unitTypes []int
-			if len(team.UnitTypes) == 0 {
-				unitTypes = allUnitTypes
-			} else {
-				unitTypes = team.UnitTypes
-			}
-
-			// insert units for team
-			var units = make([]TeamUnit, 0, len(unitTypes))
-			for _, tp := range unitTypes {
-				units = append(units, TeamUnit{
-					OrgID:  team.OrgID,
-					TeamID: team.ID,
-					Type:   tp,
-				})
-			}
-
-			if _, err := sess.Insert(&units); err != nil {
-				return fmt.Errorf("Insert team units: %v", err)
-			}
-
-		}
-	}
-
-	// Commit and begin new transaction for dropping columns
-	if err := sess.Commit(); err != nil {
-		return err
-	}
-	if err := sess.Begin(); err != nil {
-		return err
-	}
-
-	if err := dropTableColumns(sess, "team", "unit_types"); err != nil {
-		return err
-	}
-	return sess.Commit()
-}
diff --git a/models/migrations/v70.go b/models/migrations/v70.go
index ef8dd85d6d..ea7ead60d8 100644
--- a/models/migrations/v70.go
+++ b/models/migrations/v70.go
@@ -26,6 +26,18 @@ func addIssueDependencies(x *xorm.Engine) (err error) {
 		UpdatedUnix  int64     `xorm:"updated"`
 	}
 
+	const (
+		v16UnitTypeCode            = iota + 1 // 1 code
+		v16UnitTypeIssues                     // 2 issues
+		v16UnitTypePRs                        // 3 PRs
+		v16UnitTypeCommits                    // 4 Commits
+		v16UnitTypeReleases                   // 5 Releases
+		v16UnitTypeWiki                       // 6 Wiki
+		v16UnitTypeSettings                   // 7 Settings
+		v16UnitTypeExternalWiki               // 8 ExternalWiki
+		v16UnitTypeExternalTracker            // 9 ExternalTracker
+	)
+
 	if err = x.Sync(new(IssueDependency)); err != nil {
 		return fmt.Errorf("Error creating issue_dependency_table column definition: %v", err)
 	}
@@ -80,7 +92,7 @@ func addIssueDependencies(x *xorm.Engine) (err error) {
 
 	//Updating existing issue units
 	units := make([]*RepoUnit, 0, 100)
-	err = x.Where("`type` = ?", V16UnitTypeIssues).Find(&units)
+	err = x.Where("`type` = ?", v16UnitTypeIssues).Find(&units)
 	if err != nil {
 		return fmt.Errorf("Query repo units: %v", err)
 	}
diff --git a/models/migrations/v76.go b/models/migrations/v76.go
index 545bff64c5..6bfe0c2d98 100644
--- a/models/migrations/v76.go
+++ b/models/migrations/v76.go
@@ -22,6 +22,18 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error {
 		CreatedUnix timeutil.TimeStamp     `xorm:"INDEX CREATED"`
 	}
 
+	const (
+		v16UnitTypeCode            = iota + 1 // 1 code
+		v16UnitTypeIssues                     // 2 issues
+		v16UnitTypePRs                        // 3 PRs
+		v16UnitTypeCommits                    // 4 Commits
+		v16UnitTypeReleases                   // 5 Releases
+		v16UnitTypeWiki                       // 6 Wiki
+		v16UnitTypeSettings                   // 7 Settings
+		v16UnitTypeExternalWiki               // 8 ExternalWiki
+		v16UnitTypeExternalTracker            // 9 ExternalTracker
+	)
+
 	sess := x.NewSession()
 	defer sess.Close()
 	if err := sess.Begin(); err != nil {
@@ -30,7 +42,7 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error {
 
 	//Updating existing issue units
 	units := make([]*RepoUnit, 0, 100)
-	if err := sess.Where("`type` = ?", V16UnitTypePRs).Find(&units); err != nil {
+	if err := sess.Where("`type` = ?", v16UnitTypePRs).Find(&units); err != nil {
 		return fmt.Errorf("Query repo units: %v", err)
 	}
 	for _, unit := range units {