aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-03-06 14:26:32 +0800
committerGitHub <noreply@github.com>2024-03-06 14:26:32 +0800
commit5cddab4f74bbb307ddf13e458c7ac22f93b9283a (patch)
tree2eee924ffdbc2e1bedb6b63020e7b7fdd86417c3
parentda15d6127c8d430dfc069f9815ce783dd9ca35f7 (diff)
downloadgitea-5cddab4f74bbb307ddf13e458c7ac22f93b9283a.tar.gz
gitea-5cddab4f74bbb307ddf13e458c7ac22f93b9283a.zip
Make wiki default branch name changable (#29603)
Fix #29000 Fix #28685 Fix #18568 Related: #27497 And by the way fix #24036, add a Cancel button there (one line)
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v1_22/v289.go18
-rw-r--r--models/repo/repo.go4
-rw-r--r--modules/git/repo_base_gogit.go4
-rw-r--r--modules/git/repo_base_nogogit.go4
-rw-r--r--options/locale/locale_en-US.ini2
-rw-r--r--routers/web/repo/setting/setting.go7
-rw-r--r--routers/web/repo/wiki.go60
-rw-r--r--routers/web/repo/wiki_test.go30
-rw-r--r--services/forms/repo_form.go1
-rw-r--r--services/repository/create.go2
-rw-r--r--services/repository/migrate.go88
-rw-r--r--services/wiki/wiki.go79
-rw-r--r--services/wiki/wiki_test.go10
-rw-r--r--templates/repo/settings/options.tmpl4
-rw-r--r--templates/repo/wiki/new.tmpl5
-rw-r--r--templates/repo/wiki/pages.tmpl1
17 files changed, 232 insertions, 89 deletions
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 9d288ec2bd..d40866f3e9 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -562,6 +562,8 @@ var migrations = []Migration{
NewMigration("Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges),
// v288 -> v289
NewMigration("Add user_blocking table", v1_22.AddUserBlockingTable),
+ // v289 -> v290
+ NewMigration("Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_22/v289.go b/models/migrations/v1_22/v289.go
new file mode 100644
index 0000000000..e2dfc48715
--- /dev/null
+++ b/models/migrations/v1_22/v289.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_22 //nolint
+
+import "xorm.io/xorm"
+
+func AddDefaultWikiBranch(x *xorm.Engine) error {
+ type Repository struct {
+ ID int64
+ DefaultWikiBranch string
+ }
+ if err := x.Sync(&Repository{}); err != nil {
+ return err
+ }
+ _, err := x.Exec("UPDATE `repository` SET default_wiki_branch = 'master' WHERE (default_wiki_branch IS NULL) OR (default_wiki_branch = '')")
+ return err
+}
diff --git a/models/repo/repo.go b/models/repo/repo.go
index f6758f1591..1d17e565ae 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -136,6 +136,7 @@ type Repository struct {
OriginalServiceType api.GitServiceType `xorm:"index"`
OriginalURL string `xorm:"VARCHAR(2048)"`
DefaultBranch string
+ DefaultWikiBranch string
NumWatches int
NumStars int
@@ -285,6 +286,9 @@ func (repo *Repository) AfterLoad() {
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
+ if repo.DefaultWikiBranch == "" {
+ repo.DefaultWikiBranch = setting.Repository.DefaultBranch
+ }
}
// LoadAttributes loads attributes of the repository.
diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go
index 3ca5eb36c6..0cd07dcdc8 100644
--- a/modules/git/repo_base_gogit.go
+++ b/modules/git/repo_base_gogit.go
@@ -8,11 +8,11 @@ package git
import (
"context"
- "errors"
"path/filepath"
gitealog "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs"
@@ -52,7 +52,7 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
if err != nil {
return nil, err
} else if !isDir(repoPath) {
- return nil, errors.New("no such file or directory")
+ return nil, util.NewNotExistErrorf("no such file or directory")
}
fs := osfs.New(repoPath)
diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go
index 86b6a93567..7f6512200b 100644
--- a/modules/git/repo_base_nogogit.go
+++ b/modules/git/repo_base_nogogit.go
@@ -9,10 +9,10 @@ package git
import (
"bufio"
"context"
- "errors"
"path/filepath"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
)
func init() {
@@ -54,7 +54,7 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
if err != nil {
return nil, err
} else if !isDir(repoPath) {
- return nil, errors.New("no such file or directory")
+ return nil, util.NewNotExistErrorf("no such file or directory")
}
// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 3fc74959ca..59aae68cae 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -2092,6 +2092,8 @@ settings.branches.add_new_rule = Add New Rule
settings.advanced_settings = Advanced Settings
settings.wiki_desc = Enable Repository Wiki
settings.use_internal_wiki = Use Built-In Wiki
+settings.default_wiki_branch_name = Default Wiki Branch Name
+settings.failed_to_change_default_wiki_branch = Failed to change the default wiki branch.
settings.use_external_wiki = Use External Wiki
settings.external_wiki_url = External Wiki URL
settings.external_wiki_url_error = The external wiki URL is not a valid URL.
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 992a980d9e..e045e3b8dc 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -488,6 +488,13 @@ func SettingsPost(ctx *context.Context) {
}
}
+ if form.DefaultWikiBranch != "" {
+ if err := wiki_service.ChangeDefaultWikiBranch(ctx, repo, form.DefaultWikiBranch); err != nil {
+ log.Error("ChangeDefaultWikiBranch failed, err: %v", err)
+ ctx.Flash.Warning(ctx.Tr("repo.settings.failed_to_change_default_wiki_branch"))
+ }
+ }
+
if form.EnableIssues && form.EnableExternalTracker && !unit_model.TypeExternalTracker.UnitGlobalDisabled() {
if !validation.IsValidExternalURL(form.ExternalTrackerURL) {
ctx.Flash.Error(ctx.Tr("repo.settings.external_tracker_url_error"))
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index 91cf727e2c..88b63da88d 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -93,17 +93,32 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
}
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
- wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
- if err != nil {
- ctx.ServerError("OpenRepository", err)
- return nil, nil, err
+ wikiGitRepo, errGitRepo := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
+ if errGitRepo != nil {
+ ctx.ServerError("OpenRepository", errGitRepo)
+ return nil, nil, errGitRepo
}
- commit, err := wikiRepo.GetBranchCommit(wiki_service.DefaultBranch)
- if err != nil {
- return wikiRepo, nil, err
+ commit, errCommit := wikiGitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultWikiBranch)
+ if git.IsErrNotExist(errCommit) {
+ // if the default branch recorded in database is out of sync, then re-sync it
+ gitRepoDefaultBranch, errBranch := wikiGitRepo.GetDefaultBranch()
+ if errBranch != nil {
+ return wikiGitRepo, nil, errBranch
+ }
+ // update the default branch in the database
+ errDb := repo_model.UpdateRepositoryCols(ctx, &repo_model.Repository{ID: ctx.Repo.Repository.ID, DefaultWikiBranch: gitRepoDefaultBranch}, "default_wiki_branch")
+ if errDb != nil {
+ return wikiGitRepo, nil, errDb
+ }
+ ctx.Repo.Repository.DefaultWikiBranch = gitRepoDefaultBranch
+ // retry to get the commit from the correct default branch
+ commit, errCommit = wikiGitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultWikiBranch)
}
- return wikiRepo, commit, nil
+ if errCommit != nil {
+ return wikiGitRepo, nil, errCommit
+ }
+ return wikiGitRepo, commit, nil
}
// wikiContentsByEntry returns the contents of the wiki page referenced by the
@@ -316,7 +331,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
// get commit count - wiki revisions
- commitsCount, _ := wikiRepo.FileCommitsCount(wiki_service.DefaultBranch, pageFilename)
+ commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
ctx.Data["CommitCount"] = commitsCount
return wikiRepo, entry
@@ -368,7 +383,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.Data["footerContent"] = ""
// get commit count - wiki revisions
- commitsCount, _ := wikiRepo.FileCommitsCount(wiki_service.DefaultBranch, pageFilename)
+ commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
ctx.Data["CommitCount"] = commitsCount
// get page
@@ -380,7 +395,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
// get Commit Count
commitsHistory, err := wikiRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
- Revision: wiki_service.DefaultBranch,
+ Revision: ctx.Repo.Repository.DefaultWikiBranch,
File: pageFilename,
Page: page,
})
@@ -402,20 +417,17 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
func renderEditPage(ctx *context.Context) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
- if err != nil {
+ defer func() {
if wikiRepo != nil {
- wikiRepo.Close()
+ _ = wikiRepo.Close()
}
+ }()
+ if err != nil {
if !git.IsErrNotExist(err) {
ctx.ServerError("GetBranchCommit", err)
}
return
}
- defer func() {
- if wikiRepo != nil {
- wikiRepo.Close()
- }
- }()
// get requested pagename
pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
@@ -584,17 +596,15 @@ func WikiPages(ctx *context.Context) {
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
wikiRepo, commit, err := findWikiRepoCommit(ctx)
- if err != nil {
- if wikiRepo != nil {
- wikiRepo.Close()
- }
- return
- }
defer func() {
if wikiRepo != nil {
- wikiRepo.Close()
+ _ = wikiRepo.Close()
}
}()
+ if err != nil {
+ ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
+ return
+ }
entries, err := commit.ListEntries()
if err != nil {
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 719cca3049..52e216e6a0 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -9,6 +9,7 @@ import (
"net/url"
"testing"
+ "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
@@ -221,3 +222,32 @@ func TestWikiRaw(t *testing.T) {
}
}
}
+
+func TestDefaultWikiBranch(t *testing.T) {
+ unittest.PrepareTestEnv(t)
+
+ assert.NoError(t, repo_model.UpdateRepositoryCols(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"}))
+
+ ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
+ ctx.SetParams("*", "Home")
+ contexttest.LoadRepo(t, ctx, 1)
+ assert.Equal(t, "wrong-branch", ctx.Repo.Repository.DefaultWikiBranch)
+ Wiki(ctx) // after the visiting, the out-of-sync database record will update the branch name to "master"
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ assert.Equal(t, "master", ctx.Repo.Repository.DefaultWikiBranch)
+
+ // invalid branch name should fail
+ assert.Error(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "the bad name"))
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ assert.Equal(t, "master", repo.DefaultWikiBranch)
+
+ // the same branch name, should succeed (actually a no-op)
+ assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "master"))
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ assert.Equal(t, "master", repo.DefaultWikiBranch)
+
+ // change to another name
+ assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "main"))
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ assert.Equal(t, "main", repo.DefaultWikiBranch)
+}
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 8c3e458d2f..e45a2a1695 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -133,6 +133,7 @@ type RepoSettingForm struct {
EnableCode bool
EnableWiki bool
EnableExternalWiki bool
+ DefaultWikiBranch string
ExternalWikiURL string
EnableIssues bool
EnableExternalTracker bool
diff --git a/services/repository/create.go b/services/repository/create.go
index c47ce9c413..8d8c39197d 100644
--- a/services/repository/create.go
+++ b/services/repository/create.go
@@ -173,6 +173,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re
}
repo.DefaultBranch = setting.Repository.DefaultBranch
+ repo.DefaultWikiBranch = setting.Repository.DefaultBranch
if len(opts.DefaultBranch) > 0 {
repo.DefaultBranch = opts.DefaultBranch
@@ -240,6 +241,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt
TrustModel: opts.TrustModel,
IsMirror: opts.IsMirror,
DefaultBranch: opts.DefaultBranch,
+ DefaultWikiBranch: setting.Repository.DefaultBranch,
ObjectFormatName: opts.ObjectFormatName,
}
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 51fdd90f54..aae2ddc120 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -25,6 +25,54 @@ import (
"code.gitea.io/gitea/modules/util"
)
+func cloneWiki(ctx context.Context, u *user_model.User, opts migration.MigrateOptions, migrateTimeout time.Duration) (string, error) {
+ wikiPath := repo_model.WikiPath(u.Name, opts.RepoName)
+ wikiRemotePath := repo_module.WikiRemoteURL(ctx, opts.CloneAddr)
+ if wikiRemotePath == "" {
+ return "", nil
+ }
+
+ if err := util.RemoveAll(wikiPath); err != nil {
+ return "", fmt.Errorf("failed to remove existing wiki dir %q, err: %w", wikiPath, err)
+ }
+
+ cleanIncompleteWikiPath := func() {
+ if err := util.RemoveAll(wikiPath); err != nil {
+ log.Error("Failed to remove incomplete wiki dir %q, err: %v", wikiPath, err)
+ }
+ }
+ if err := git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{
+ Mirror: true,
+ Quiet: true,
+ Timeout: migrateTimeout,
+ SkipTLSVerify: setting.Migrations.SkipTLSVerify,
+ }); err != nil {
+ log.Error("Clone wiki failed, err: %v", err)
+ cleanIncompleteWikiPath()
+ return "", err
+ }
+
+ if err := git.WriteCommitGraph(ctx, wikiPath); err != nil {
+ cleanIncompleteWikiPath()
+ return "", err
+ }
+
+ wikiRepo, err := git.OpenRepository(ctx, wikiPath)
+ if err != nil {
+ cleanIncompleteWikiPath()
+ return "", fmt.Errorf("failed to open wiki repo %q, err: %w", wikiPath, err)
+ }
+ defer wikiRepo.Close()
+
+ defaultBranch, err := wikiRepo.GetDefaultBranch()
+ if err != nil {
+ cleanIncompleteWikiPath()
+ return "", fmt.Errorf("failed to get wiki repo default branch for %q, err: %w", wikiPath, err)
+ }
+
+ return defaultBranch, nil
+}
+
// MigrateRepositoryGitData starts migrating git related data after created migrating repository
func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
repo *repo_model.Repository, opts migration.MigrateOptions,
@@ -44,21 +92,20 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
migrateTimeout := time.Duration(setting.Git.Timeout.Migrate) * time.Second
- var err error
- if err = util.RemoveAll(repoPath); err != nil {
- return repo, fmt.Errorf("Failed to remove %s: %w", repoPath, err)
+ if err := util.RemoveAll(repoPath); err != nil {
+ return repo, fmt.Errorf("failed to remove existing repo dir %q, err: %w", repoPath, err)
}
- if err = git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{
+ if err := git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
Timeout: migrateTimeout,
SkipTLSVerify: setting.Migrations.SkipTLSVerify,
}); err != nil {
if errors.Is(err, context.DeadlineExceeded) {
- return repo, fmt.Errorf("Clone timed out. Consider increasing [git.timeout] MIGRATE in app.ini. Underlying Error: %w", err)
+ return repo, fmt.Errorf("clone timed out, consider increasing [git.timeout] MIGRATE in app.ini, underlying err: %w", err)
}
- return repo, fmt.Errorf("Clone: %w", err)
+ return repo, fmt.Errorf("clone error: %w", err)
}
if err := git.WriteCommitGraph(ctx, repoPath); err != nil {
@@ -66,37 +113,18 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
}
if opts.Wiki {
- wikiPath := repo_model.WikiPath(u.Name, opts.RepoName)
- wikiRemotePath := repo_module.WikiRemoteURL(ctx, opts.CloneAddr)
- if len(wikiRemotePath) > 0 {
- if err := util.RemoveAll(wikiPath); err != nil {
- return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err)
- }
-
- if err := git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{
- Mirror: true,
- Quiet: true,
- Timeout: migrateTimeout,
- Branch: "master",
- SkipTLSVerify: setting.Migrations.SkipTLSVerify,
- }); err != nil {
- log.Warn("Clone wiki: %v", err)
- if err := util.RemoveAll(wikiPath); err != nil {
- return repo, fmt.Errorf("Failed to remove %s: %w", wikiPath, err)
- }
- } else {
- if err := git.WriteCommitGraph(ctx, wikiPath); err != nil {
- return repo, err
- }
- }
+ defaultWikiBranch, err := cloneWiki(ctx, u, opts, migrateTimeout)
+ if err != nil {
+ return repo, fmt.Errorf("clone wiki error: %w", err)
}
+ repo.DefaultWikiBranch = defaultWikiBranch
}
if repo.OwnerID == u.ID {
repo.Owner = u
}
- if err = repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
+ if err := repo_module.CheckDaemonExportOK(ctx, repo); err != nil {
return repo, fmt.Errorf("checkDaemonExportOK: %w", err)
}
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index 50d52d3140..6f1ca120b0 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -6,18 +6,22 @@ package wiki
import (
"context"
+ "errors"
"fmt"
"os"
"strings"
+ "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/sync"
+ "code.gitea.io/gitea/modules/util"
asymkey_service "code.gitea.io/gitea/services/asymkey"
repo_service "code.gitea.io/gitea/services/repository"
)
@@ -25,10 +29,7 @@ import (
// TODO: use clustered lock (unique queue? or *abuse* cache)
var wikiWorkingPool = sync.NewExclusivePool()
-const (
- DefaultRemote = "origin"
- DefaultBranch = "master"
-)
+const DefaultRemote = "origin"
// InitWiki initializes a wiki for repository,
// it does nothing when repository already has wiki.
@@ -41,25 +42,25 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error {
return fmt.Errorf("InitRepository: %w", err)
} else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil {
return fmt.Errorf("createDelegateHooks: %w", err)
- } else if _, _, err = git.NewCommand(ctx, "symbolic-ref", "HEAD", git.BranchPrefix+DefaultBranch).RunStdString(&git.RunOpts{Dir: repo.WikiPath()}); err != nil {
- return fmt.Errorf("unable to set default wiki branch to master: %w", err)
+ } else if _, _, err = git.NewCommand(ctx, "symbolic-ref", "HEAD").AddDynamicArguments(git.BranchPrefix + repo.DefaultWikiBranch).RunStdString(&git.RunOpts{Dir: repo.WikiPath()}); err != nil {
+ return fmt.Errorf("unable to set default wiki branch to %q: %w", repo.DefaultWikiBranch, err)
}
return nil
}
// prepareGitPath try to find a suitable file path with file name by the given raw wiki name.
// return: existence, prepared file path with name, error
-func prepareGitPath(gitRepo *git.Repository, wikiPath WebPath) (bool, string, error) {
+func prepareGitPath(gitRepo *git.Repository, defaultWikiBranch string, wikiPath WebPath) (bool, string, error) {
unescaped := string(wikiPath) + ".md"
gitPath := WebPathToGitPath(wikiPath)
// Look for both files
- filesInIndex, err := gitRepo.LsTree(DefaultBranch, unescaped, gitPath)
+ filesInIndex, err := gitRepo.LsTree(defaultWikiBranch, unescaped, gitPath)
if err != nil {
- if strings.Contains(err.Error(), "Not a valid object name master") {
- return false, gitPath, nil
+ if strings.Contains(err.Error(), "Not a valid object name") {
+ return false, gitPath, nil // branch doesn't exist
}
- log.Error("%v", err)
+ log.Error("Wiki LsTree failed, err: %v", err)
return false, gitPath, err
}
@@ -95,7 +96,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return fmt.Errorf("InitWiki: %w", err)
}
- hasMasterBranch := git.IsBranchExist(ctx, repo.WikiPath(), DefaultBranch)
+ hasDefaultBranch := git.IsBranchExist(ctx, repo.WikiPath(), repo.DefaultWikiBranch)
basePath, err := repo_module.CreateTemporaryPath("update-wiki")
if err != nil {
@@ -112,8 +113,8 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
Shared: true,
}
- if hasMasterBranch {
- cloneOpts.Branch = DefaultBranch
+ if hasDefaultBranch {
+ cloneOpts.Branch = repo.DefaultWikiBranch
}
if err := git.Clone(ctx, repo.WikiPath(), basePath, cloneOpts); err != nil {
@@ -128,14 +129,14 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
}
defer gitRepo.Close()
- if hasMasterBranch {
+ if hasDefaultBranch {
if err := gitRepo.ReadTreeToIndex("HEAD"); err != nil {
log.Error("Unable to read HEAD tree to index in: %s %v", basePath, err)
return fmt.Errorf("fnable to read HEAD tree to index in: %s %w", basePath, err)
}
}
- isWikiExist, newWikiPath, err := prepareGitPath(gitRepo, newWikiName)
+ isWikiExist, newWikiPath, err := prepareGitPath(gitRepo, repo.DefaultWikiBranch, newWikiName)
if err != nil {
return err
}
@@ -151,7 +152,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
isOldWikiExist := true
oldWikiPath := newWikiPath
if oldWikiName != newWikiName {
- isOldWikiExist, oldWikiPath, err = prepareGitPath(gitRepo, oldWikiName)
+ isOldWikiExist, oldWikiPath, err = prepareGitPath(gitRepo, repo.DefaultWikiBranch, oldWikiName)
if err != nil {
return err
}
@@ -200,7 +201,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
} else {
commitTreeOpts.NoGPGSign = true
}
- if hasMasterBranch {
+ if hasDefaultBranch {
commitTreeOpts.Parents = []string{"HEAD"}
}
@@ -212,7 +213,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
if err := git.Push(gitRepo.Ctx, basePath, git.PushOptions{
Remote: DefaultRemote,
- Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, DefaultBranch),
+ Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, repo.DefaultWikiBranch),
Env: repo_module.FullPushingEnvironment(
doer,
doer,
@@ -269,7 +270,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
if err := git.Clone(ctx, repo.WikiPath(), basePath, git.CloneRepoOptions{
Bare: true,
Shared: true,
- Branch: DefaultBranch,
+ Branch: repo.DefaultWikiBranch,
}); err != nil {
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
return fmt.Errorf("failed to clone repository: %s (%w)", repo.FullName(), err)
@@ -287,7 +288,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return fmt.Errorf("unable to read HEAD tree to index in: %s %w", basePath, err)
}
- found, wikiPath, err := prepareGitPath(gitRepo, wikiName)
+ found, wikiPath, err := prepareGitPath(gitRepo, repo.DefaultWikiBranch, wikiName)
if err != nil {
return err
}
@@ -331,7 +332,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
if err := git.Push(gitRepo.Ctx, basePath, git.PushOptions{
Remote: DefaultRemote,
- Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, DefaultBranch),
+ Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, repo.DefaultWikiBranch),
Env: repo_module.FullPushingEnvironment(
doer,
doer,
@@ -358,3 +359,37 @@ func DeleteWiki(ctx context.Context, repo *repo_model.Repository) error {
system_model.RemoveAllWithNotice(ctx, "Delete repository wiki", repo.WikiPath())
return nil
}
+
+func ChangeDefaultWikiBranch(ctx context.Context, repo *repo_model.Repository, newBranch string) error {
+ if !git.IsValidRefPattern(newBranch) {
+ return fmt.Errorf("invalid branch name: %s", newBranch)
+ }
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ repo.DefaultWikiBranch = newBranch
+ if err := repo_model.UpdateRepositoryCols(ctx, repo, "default_wiki_branch"); err != nil {
+ return fmt.Errorf("unable to update database: %w", err)
+ }
+
+ gitRepo, err := gitrepo.OpenWikiRepository(ctx, repo)
+ if errors.Is(err, util.ErrNotExist) {
+ return nil // no git repo on storage, no need to do anything else
+ } else if err != nil {
+ return fmt.Errorf("unable to open repository: %w", err)
+ }
+ defer gitRepo.Close()
+
+ oldDefBranch, err := gitRepo.GetDefaultBranch()
+ if err != nil {
+ return fmt.Errorf("unable to get default branch: %w", err)
+ }
+ if oldDefBranch == newBranch {
+ return nil
+ }
+
+ err = gitRepo.RenameBranch(oldDefBranch, newBranch)
+ if err != nil {
+ return fmt.Errorf("unable to rename default branch: %w", err)
+ }
+ return nil
+ })
+}
diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go
index 59c77060f2..0a18cffa25 100644
--- a/services/wiki/wiki_test.go
+++ b/services/wiki/wiki_test.go
@@ -170,7 +170,7 @@ func TestRepository_AddWikiPage(t *testing.T) {
return
}
defer gitRepo.Close()
- masterTree, err := gitRepo.GetTree(DefaultBranch)
+ masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch)
assert.NoError(t, err)
gitPath := WebPathToGitPath(webPath)
entry, err := masterTree.GetTreeEntryByPath(gitPath)
@@ -215,7 +215,7 @@ func TestRepository_EditWikiPage(t *testing.T) {
// Now need to show that the page has been added:
gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo)
assert.NoError(t, err)
- masterTree, err := gitRepo.GetTree(DefaultBranch)
+ masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch)
assert.NoError(t, err)
gitPath := WebPathToGitPath(webPath)
entry, err := masterTree.GetTreeEntryByPath(gitPath)
@@ -242,7 +242,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
return
}
defer gitRepo.Close()
- masterTree, err := gitRepo.GetTree(DefaultBranch)
+ masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch)
assert.NoError(t, err)
gitPath := WebPathToGitPath("Home")
_, err = masterTree.GetTreeEntryByPath(gitPath)
@@ -280,7 +280,7 @@ func TestPrepareWikiFileName(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
webPath := UserTitleToWebPath("", tt.arg)
- existence, newWikiPath, err := prepareGitPath(gitRepo, webPath)
+ existence, newWikiPath, err := prepareGitPath(gitRepo, repo.DefaultWikiBranch, webPath)
if (err != nil) != tt.wantErr {
assert.NoError(t, err)
return
@@ -312,7 +312,7 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) {
}
defer gitRepo.Close()
- existence, newWikiPath, err := prepareGitPath(gitRepo, "Home")
+ existence, newWikiPath, err := prepareGitPath(gitRepo, "master", "Home")
assert.False(t, existence)
assert.NoError(t, err)
assert.EqualValues(t, "Home.md", newWikiPath)
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index 0de42b34ea..a699396a84 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -335,6 +335,10 @@
<label>{{ctx.Locale.Tr "repo.settings.use_internal_wiki"}}</label>
</div>
</div>
+ <div class="inline field gt-pl-4">
+ <label>{{ctx.Locale.Tr "repo.settings.default_wiki_branch_name"}}</label>
+ <input name="default_wiki_branch" value="{{.Repository.DefaultWikiBranch}}">
+ </div>
<div class="field">
<div class="ui radio checkbox{{if $isExternalWikiGlobalDisabled}} disabled{{end}}"{{if $isExternalWikiGlobalDisabled}} data-tooltip-content="{{ctx.Locale.Tr "repo.unit_disabled"}}"{{end}}>
<input class="enable-system-radio" name="enable_external_wiki" type="radio" value="true" data-target="#external_wiki_box" {{if .Repository.UnitEnabled $.Context $.UnitTypeExternalWiki}}checked{{end}}>
diff --git a/templates/repo/wiki/new.tmpl b/templates/repo/wiki/new.tmpl
index ff31df0c32..640f8ca9cd 100644
--- a/templates/repo/wiki/new.tmpl
+++ b/templates/repo/wiki/new.tmpl
@@ -36,9 +36,8 @@
</div>
<div class="divider"></div>
<div class="text right">
- <button class="ui primary button">
- {{ctx.Locale.Tr "repo.wiki.save_page"}}
- </button>
+ <a class="ui basic cancel button" href="{{.Link}}">{{ctx.Locale.Tr "cancel"}}</a>
+ <button class="ui primary button">{{ctx.Locale.Tr "repo.wiki.save_page"}}</button>
</div>
</form>
</div>
diff --git a/templates/repo/wiki/pages.tmpl b/templates/repo/wiki/pages.tmpl
index 22eb2619f9..cace0d48e0 100644
--- a/templates/repo/wiki/pages.tmpl
+++ b/templates/repo/wiki/pages.tmpl
@@ -10,6 +10,7 @@
{{end}}
</span>
</h2>
+ {{if .IsRepositoryAdmin}}<div>{{ctx.Locale.Tr "repo.default_branch"}}: {{.Repository.DefaultWikiBranch}}</div>{{end}}
<table class="ui table wiki-pages-list">
<tbody>
{{range .Pages}}