forked from Gitlink/gitea-1156
Compare commits
4 Commits
hh_code_re
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
a536c60e48 | |
|
|
db1eeabc85 | |
|
|
72ac212a9f | |
|
|
1a408bbe98 |
|
|
@ -327,10 +327,6 @@ var migrations = []Migration{
|
|||
NewMigration("Drop unneeded webhook related columns", dropWebhookColumns),
|
||||
// v188 -> v189
|
||||
NewMigration("Add key is verified to gpg key", addKeyIsVerified),
|
||||
// v189 -> v190
|
||||
NewMigration("Add index about user email", addIndexAboutUserEmail),
|
||||
// v190 -> v191
|
||||
NewMigration("Add index about access token last eight", addIndexAboutAccessTokenLastEight),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* @Description: Do not edit
|
||||
* @Date: 2022-04-27 17:58:22
|
||||
* @LastEditors: viletyy
|
||||
* @Author: viletyy
|
||||
* @LastEditTime: 2022-04-27 18:04:33
|
||||
* @FilePath: /gitea-1156/models/migrations/v189.go
|
||||
*/
|
||||
package migrations
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func addIndexAboutUserEmail(x *xorm.Engine) error {
|
||||
|
||||
type User struct {
|
||||
Email string `xorm:"INDEX NOT NULL"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(User))
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* @Description: Do not edit
|
||||
* @Date: 2022-04-27 18:04:31
|
||||
* @LastEditors: viletyy
|
||||
* @Author: viletyy
|
||||
* @LastEditTime: 2022-04-27 18:05:38
|
||||
* @FilePath: /gitea-1156/models/migrations/v190.go
|
||||
*/
|
||||
package migrations
|
||||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func addIndexAboutAccessTokenLastEight(x *xorm.Engine) error {
|
||||
|
||||
type AccessToken struct {
|
||||
TokenLastEight string `xorm:"INDEX token_last_eight"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(AccessToken))
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ type AccessToken struct {
|
|||
Token string `xorm:"-"`
|
||||
TokenHash string `xorm:"UNIQUE"` // sha256 of token
|
||||
TokenSalt string
|
||||
TokenLastEight string `xorm:"INDEX token_last_eight"`
|
||||
TokenLastEight string `xorm:"token_last_eight"`
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ type User struct {
|
|||
Name string `xorm:"UNIQUE NOT NULL"`
|
||||
FullName string
|
||||
// Email is the primary email address (to be used for communication)
|
||||
Email string `xorm:"INDEX NOT NULL"`
|
||||
Email string `xorm:"NOT NULL"`
|
||||
KeepEmailPrivate bool
|
||||
EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"`
|
||||
Passwd string `xorm:"NOT NULL"`
|
||||
|
|
|
|||
|
|
@ -229,22 +229,6 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetTotalCountHeader set "X-Total-Count" header
|
||||
func (ctx *APIContext) SetTotalCountHeader(total int64) {
|
||||
ctx.RespHeader().Set("X-Total-Count", fmt.Sprint(total))
|
||||
ctx.AppendAccessControlExposeHeaders("X-Total-Count")
|
||||
}
|
||||
|
||||
// AppendAccessControlExposeHeaders append headers by name to "Access-Control-Expose-Headers" header
|
||||
func (ctx *APIContext) AppendAccessControlExposeHeaders(names ...string) {
|
||||
val := ctx.RespHeader().Get("Access-Control-Expose-Headers")
|
||||
if len(val) != 0 {
|
||||
ctx.RespHeader().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", ")))
|
||||
} else {
|
||||
ctx.RespHeader().Set("Access-Control-Expose-Headers", strings.Join(names, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
// RequireCSRF requires a validated a CSRF token
|
||||
func (ctx *APIContext) RequireCSRF() {
|
||||
headerToken := ctx.Req.Header.Get(ctx.csrf.GetHeaderName())
|
||||
|
|
|
|||
|
|
@ -333,11 +333,6 @@ func (ctx *Context) HandleText(status int, title string) {
|
|||
ctx.PlainText(status, []byte(title))
|
||||
}
|
||||
|
||||
// RespHeader returns the response header
|
||||
func (ctx *Context) RespHeader() http.Header {
|
||||
return ctx.Resp.Header()
|
||||
}
|
||||
|
||||
// ServeContent serves content to http request
|
||||
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
|
||||
modtime := time.Now()
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright 2021 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 convert
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
model "code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
)
|
||||
|
||||
// ToWikiCommit convert a git commit into a WikiCommit
|
||||
func ToWikiCommit(commit *git.Commit) *api.WikiCommit {
|
||||
return &api.WikiCommit{
|
||||
ID: commit.ID.String(),
|
||||
Author: &api.CommitUser{
|
||||
Identity: api.Identity{
|
||||
Name: commit.Author.Name,
|
||||
Email: commit.Author.Email,
|
||||
},
|
||||
Date: commit.Author.When.UTC().Format(time.RFC3339),
|
||||
},
|
||||
Committer: &api.CommitUser{
|
||||
Identity: api.Identity{
|
||||
Name: commit.Committer.Name,
|
||||
Email: commit.Committer.Email,
|
||||
},
|
||||
Date: commit.Committer.When.UTC().Format(time.RFC3339),
|
||||
},
|
||||
Message: commit.CommitMessage,
|
||||
}
|
||||
}
|
||||
|
||||
// ToWikiCommitList convert a list of git commits into a WikiCommitList
|
||||
func ToWikiCommitList(commits []*git.Commit, total int64) *api.WikiCommitList {
|
||||
result := make([]*api.WikiCommit, len(commits))
|
||||
for i := range commits {
|
||||
result[i] = ToWikiCommit(commits[i])
|
||||
}
|
||||
return &api.WikiCommitList{
|
||||
WikiCommits: result,
|
||||
Count: total,
|
||||
}
|
||||
}
|
||||
|
||||
// ToWikiPageMetaData converts meta information to a WikiPageMetaData
|
||||
func ToWikiPageMetaData(title string, lastCommit *git.Commit, repo *model.Repository) *api.WikiPageMetaData {
|
||||
suburl := wiki_service.NameToSubURL(title)
|
||||
return &api.WikiPageMetaData{
|
||||
Title: title,
|
||||
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", suburl),
|
||||
SubURL: suburl,
|
||||
LastCommit: ToWikiCommit(lastCommit),
|
||||
}
|
||||
}
|
||||
|
||||
// author hui.he
|
||||
func RegularToWikiPageMetaData(title string, lastCommit *git.Commit, repo *model.Repository) *api.WikiListMetaData {
|
||||
suburl := wiki_service.NameToSubURL(title)
|
||||
return &api.WikiListMetaData{
|
||||
Type: "file",
|
||||
Name: title,
|
||||
HTMLURL: util.URLJoin(repo.HTMLURL(), "wiki", suburl),
|
||||
SubURL: suburl,
|
||||
LastCommit: ToWikiCommit(lastCommit),
|
||||
}
|
||||
}
|
||||
|
||||
// author hui.he
|
||||
func DirToWikiPageMetaData(name string, lastCommit *git.Commit, repo *model.Repository) *api.WikiListMetaData {
|
||||
return &api.WikiListMetaData{
|
||||
Type: "dir",
|
||||
Name: name,
|
||||
LastCommit: ToWikiCommit(lastCommit),
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
)
|
||||
|
|
@ -23,25 +22,6 @@ type BlamePart struct {
|
|||
Lines []string
|
||||
}
|
||||
|
||||
type ApiBlameCommit struct {
|
||||
ID string `json:"id"`
|
||||
Author *Signature `json:"author"`
|
||||
Commiter *Signature `json:"commiter"`
|
||||
CommitMessage string `json:"commit_message"`
|
||||
Parents []string `json:"parents"`
|
||||
AuthoredTime time.Time `json:"authored_time"`
|
||||
CommittedTime time.Time `json:"committed_time"`
|
||||
CreatedTime time.Time `json:"created_time"`
|
||||
}
|
||||
|
||||
type ApiBlamePart struct {
|
||||
Sha string `json:"-"`
|
||||
Commit *ApiBlameCommit `json:"commit"`
|
||||
CurrentNumber int `json:"current_number"`
|
||||
EffectLine int `json:"effect_line"`
|
||||
Lines []string `json:"lines"`
|
||||
}
|
||||
|
||||
// BlameReader returns part of file blame one by one
|
||||
type BlameReader struct {
|
||||
cmd *exec.Cmd
|
||||
|
|
@ -54,95 +34,6 @@ type BlameReader struct {
|
|||
|
||||
var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
|
||||
|
||||
func GetBlameCommit(repo *Repository, sha string) *ApiBlameCommit {
|
||||
commit, err := repo.GetCommit(sha)
|
||||
var apiParents []string
|
||||
for i := 0; i < commit.ParentCount(); i++ {
|
||||
sha, _ := commit.ParentID(i)
|
||||
apiParents = append(apiParents, sha.String())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return &ApiBlameCommit{}
|
||||
} else {
|
||||
return &ApiBlameCommit{
|
||||
ID: sha,
|
||||
Author: commit.Author,
|
||||
Commiter: commit.Committer,
|
||||
CommitMessage: commit.CommitMessage,
|
||||
Parents: apiParents,
|
||||
AuthoredTime: commit.Author.When,
|
||||
CommittedTime: commit.Committer.When,
|
||||
CreatedTime: commit.Committer.When,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *BlameReader) NextApiPart(repo *Repository) (*ApiBlamePart, error) {
|
||||
var blamePart *ApiBlamePart
|
||||
|
||||
reader := r.reader
|
||||
effectLine := 0
|
||||
|
||||
if r.lastSha != nil {
|
||||
blamePart = &ApiBlamePart{*r.lastSha, GetBlameCommit(repo, *r.lastSha), 0, effectLine, make([]string, 0)}
|
||||
}
|
||||
|
||||
var line []byte
|
||||
var isPrefix bool
|
||||
var err error
|
||||
|
||||
for err != io.EOF {
|
||||
line, isPrefix, err = reader.ReadLine()
|
||||
if err != nil && err != io.EOF {
|
||||
return blamePart, err
|
||||
}
|
||||
|
||||
if len(line) == 0 {
|
||||
// isPrefix will be false
|
||||
continue
|
||||
}
|
||||
|
||||
lines := shaLineRegex.FindSubmatch(line)
|
||||
if lines != nil {
|
||||
sha1 := string(lines[1])
|
||||
|
||||
if blamePart == nil {
|
||||
blamePart = &ApiBlamePart{sha1, GetBlameCommit(repo, sha1), 0, effectLine, make([]string, 0)}
|
||||
}
|
||||
|
||||
if blamePart.Sha != sha1 {
|
||||
r.lastSha = &sha1
|
||||
// need to munch to end of line...
|
||||
for isPrefix {
|
||||
_, isPrefix, err = reader.ReadLine()
|
||||
if err != nil && err != io.EOF {
|
||||
return blamePart, err
|
||||
}
|
||||
}
|
||||
return blamePart, nil
|
||||
}
|
||||
} else if line[0] == '\t' {
|
||||
code := line[1:]
|
||||
effectLine += 1
|
||||
blamePart.Lines = append(blamePart.Lines, string(code))
|
||||
}
|
||||
blamePart.EffectLine = effectLine
|
||||
|
||||
// need to munch to end of line...
|
||||
for isPrefix {
|
||||
_, isPrefix, err = reader.ReadLine()
|
||||
if err != nil && err != io.EOF {
|
||||
return blamePart, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.lastSha = nil
|
||||
|
||||
return blamePart, nil
|
||||
}
|
||||
|
||||
// NextPart returns next part of blame (sequential code lines with the same commit)
|
||||
func (r *BlameReader) NextPart() (*BlamePart, error) {
|
||||
var blamePart *BlamePart
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ func (c *Commit) CommitsByRange(page, pageSize int) (*list.List, error) {
|
|||
|
||||
// CommitsByFileAndRange returns the specific page page commits before current revision and file, every page's number default by CommitsRangeSize
|
||||
func (c *Commit) CommitsByFileAndRange(file string, page, pageSize int) (*list.List, error) {
|
||||
return c.repo.CommitsByFileAndRange(c.ID.String(), file, page, pageSize)
|
||||
return c.repo.CommitsByFileAndRange(c.ID.String(), file, page)
|
||||
}
|
||||
|
||||
// CommitsBefore returns all the commits before current revision
|
||||
|
|
|
|||
|
|
@ -52,25 +52,6 @@ func (repo *Repository) parsePrettyFormatLogToList(logs []byte) (*list.List, err
|
|||
return l, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) parsePrettyFormatLogToCommits(logs []byte) ([]*Commit, error) {
|
||||
var commits []*Commit
|
||||
if len(logs) == 0 {
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
parts := bytes.Split(logs, []byte{'\n'})
|
||||
|
||||
for _, commitID := range parts {
|
||||
commit, err := repo.GetCommit(string(commitID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commits = append(commits, commit)
|
||||
}
|
||||
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
// IsRepoURLAccessible checks if given repository URL is accessible.
|
||||
func IsRepoURLAccessible(url string) bool {
|
||||
_, err := NewCommand("ls-remote", "-q", "-h", url, "HEAD").Run()
|
||||
|
|
|
|||
|
|
@ -77,32 +77,6 @@ func (repo *Repository) GetBranch(branch string) (*Branch, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// GetBranchesByPath returns a branch by it's path
|
||||
// if limit = 0 it will not limit
|
||||
func GetSearchBranchesByPath(path, search string, skip, limit int) ([]*Branch, int, error) {
|
||||
gitRepo, err := OpenRepository(path)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
|
||||
brs, countAll, err := gitRepo.GetSearchBranches(search, skip, limit)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
branches := make([]*Branch, len(brs))
|
||||
for i := range brs {
|
||||
branches[i] = &Branch{
|
||||
Path: path,
|
||||
Name: brs[i],
|
||||
gitRepo: gitRepo,
|
||||
}
|
||||
}
|
||||
|
||||
return branches, countAll, nil
|
||||
}
|
||||
|
||||
// GetBranchesByPath returns a branch by it's path
|
||||
// if limit = 0 it will not limit
|
||||
func GetBranchesByPath(path string, skip, limit int) ([]*Branch, int, error) {
|
||||
|
|
|
|||
|
|
@ -59,101 +59,12 @@ func (repo *Repository) IsBranchExist(name string) bool {
|
|||
return repo.IsReferenceExist(BranchPrefix + name)
|
||||
}
|
||||
|
||||
func (repo *Repository) GetSearchBranches(search string, skip, limit int) ([]string, int, error) {
|
||||
return callShowSearchRef(repo.Path, BranchPrefix, "--heads", search, skip, limit)
|
||||
}
|
||||
|
||||
// GetBranches returns branches from the repository, skipping skip initial branches and
|
||||
// returning at most limit branches, or all branches if limit is 0.
|
||||
func (repo *Repository) GetBranches(skip, limit int) ([]string, int, error) {
|
||||
return callShowRef(repo.Path, BranchPrefix, "--heads", skip, limit)
|
||||
}
|
||||
|
||||
func callShowSearchRef(repoPath, prefix, arg, search string, skip, limit int) (branchNames []string, countAll int, err error) {
|
||||
stdoutReader, stdoutWriter := io.Pipe()
|
||||
defer func() {
|
||||
_ = stdoutReader.Close()
|
||||
_ = stdoutWriter.Close()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
stderrBuilder := &strings.Builder{}
|
||||
err := NewCommand("show-ref", arg).RunInDirPipeline(repoPath, stdoutWriter, stderrBuilder)
|
||||
if err != nil {
|
||||
if stderrBuilder.Len() == 0 {
|
||||
_ = stdoutWriter.Close()
|
||||
return
|
||||
}
|
||||
_ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
|
||||
} else {
|
||||
_ = stdoutWriter.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
i := 0
|
||||
bufReader := bufio.NewReader(stdoutReader)
|
||||
for i < skip {
|
||||
line, isPrefix, err := bufReader.ReadLine()
|
||||
if err == io.EOF {
|
||||
return branchNames, i, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
branchName := strings.TrimPrefix(strings.Split(string(line), " ")[1], prefix)
|
||||
if len(branchName) > 0 {
|
||||
branchName = branchName[:len(branchName)-1]
|
||||
}
|
||||
isSeached := strings.Contains(branchName, search)
|
||||
|
||||
if !isPrefix && isSeached {
|
||||
i++
|
||||
}
|
||||
}
|
||||
for limit == 0 || i < skip+limit {
|
||||
|
||||
branchName, err := bufReader.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
// This shouldn't happen... but we'll tolerate it for the sake of peace
|
||||
return branchNames, i, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, i, err
|
||||
}
|
||||
branchName = strings.TrimPrefix(strings.Split(string(branchName), " ")[1], prefix)
|
||||
if len(branchName) > 0 {
|
||||
branchName = branchName[:len(branchName)-1]
|
||||
}
|
||||
isSeached := strings.Contains(branchName, search)
|
||||
if isSeached {
|
||||
i++
|
||||
branchNames = append(branchNames, branchName)
|
||||
}
|
||||
}
|
||||
// count all refs
|
||||
for limit != 0 {
|
||||
line, isPrefix, err := bufReader.ReadLine()
|
||||
if err == io.EOF {
|
||||
return branchNames, i, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
branchName := strings.TrimPrefix(strings.Split(string(line), " ")[1], prefix)
|
||||
if len(branchName) > 0 {
|
||||
branchName = branchName[:len(branchName)-1]
|
||||
}
|
||||
isSeached := strings.Contains(branchName, search)
|
||||
|
||||
if !isPrefix && isSeached {
|
||||
i++
|
||||
}
|
||||
}
|
||||
return branchNames, i, nil
|
||||
}
|
||||
|
||||
// callShowRef return refs, if limit = 0 it will not limit
|
||||
func callShowRef(repoPath, prefix, arg string, skip, limit int) (branchNames []string, countAll int, err error) {
|
||||
stdoutReader, stdoutWriter := io.Pipe()
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ func (repo *Repository) GetFirstAndLastCommitByPath(revision, relpath string) (*
|
|||
}
|
||||
|
||||
// CommitsByFileAndRange return the commits according revision file and the page
|
||||
func (repo *Repository) CommitsByFileAndRange(revision, file string, page int, pageSize int) (*list.List, error) {
|
||||
func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (*list.List, error) {
|
||||
skip := (page - 1) * setting.Git.CommitsRangeSize
|
||||
|
||||
stdoutReader, stdoutWriter := io.Pipe()
|
||||
|
|
@ -223,12 +223,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int, p
|
|||
_ = stdoutWriter.Close()
|
||||
}()
|
||||
go func() {
|
||||
if pageSize <= 0 {
|
||||
pageSize = setting.Git.CommitsRangeSize
|
||||
}
|
||||
stderr := strings.Builder{}
|
||||
err := NewCommand("log", revision, "--follow",
|
||||
"--max-count="+strconv.Itoa(pageSize*page),
|
||||
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
|
||||
prettyLogFormat, "--", file).
|
||||
RunInDirPipeline(repo.Path, stdoutWriter, &stderr)
|
||||
if err != nil {
|
||||
|
|
@ -266,15 +263,6 @@ func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, pag
|
|||
return repo.parsePrettyFormatLogToList(stdout)
|
||||
}
|
||||
|
||||
func (repo *Repository) NewCommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) {
|
||||
stdout, err := NewCommand("log", revision, "--skip="+strconv.Itoa((page-1)*50),
|
||||
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunInDirBytes(repo.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.parsePrettyFormatLogToCommits(stdout)
|
||||
}
|
||||
|
||||
// FilesCountBetween return the number of files changed between two commits
|
||||
func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) {
|
||||
stdout, err := NewCommand("diff", "--name-only", startCommitID+"..."+endCommitID).RunInDir(repo.Path)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* @Descripttion:
|
||||
* @Author: hang
|
||||
* @version:
|
||||
* @Date: 2021-10-28 18:21:53
|
||||
* @LastEditors: hang
|
||||
*/
|
||||
// Copyright 2019 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.
|
||||
|
|
@ -12,8 +5,6 @@
|
|||
package repofiles
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
|
@ -46,25 +37,3 @@ func GetBlobBySHA(repo *models.Repository, sha string) (*api.GitBlobResponse, er
|
|||
Content: content,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash.
|
||||
func GetBlobBySHANew(repo *models.Repository, gitRepo *git.Repository, sha string) (*api.GitBlobResponse, error) {
|
||||
gitBlob, err := gitRepo.GetBlob(sha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content := ""
|
||||
if gitBlob.Size() <= setting.API.DefaultMaxBlobSize {
|
||||
content, err = gitBlob.GetBlobContentBase64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &api.GitBlobResponse{
|
||||
SHA: gitBlob.ID.String(),
|
||||
URL: repo.APIURL() + "/git/blobs/" + url.PathEscape(gitBlob.ID.String()),
|
||||
Size: gitBlob.Size(),
|
||||
Encoding: "base64",
|
||||
Content: content,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ func GetContentsOrList(ctx context.Context, repo *models.Repository, treePath, r
|
|||
if ref == "" {
|
||||
ref = repo.DefaultBranch
|
||||
}
|
||||
origRef := fmt.Sprintf("%s", url.PathEscape(ref))
|
||||
origRef := ref
|
||||
|
||||
// Check that the path given in opts.treePath is valid (not a git path)
|
||||
cleanTreePath := CleanUploadFileName(treePath)
|
||||
if cleanTreePath == "" && treePath != "" {
|
||||
|
|
@ -102,20 +103,18 @@ func GetContentsOrList(ctx context.Context, repo *models.Repository, treePath, r
|
|||
subTreePath := path.Join(treePath, name)
|
||||
fileContentResponse, err := GetContents(repo, subTreePath, origRef, true)
|
||||
for _, commitInfo := range commitsInfo {
|
||||
if commitInfo.Entry != nil && fileContentResponse != nil {
|
||||
if commitInfo.Entry.Name() == fileContentResponse.Name {
|
||||
var entryCommit *git.Commit
|
||||
entryCommit = commitInfo.Commit
|
||||
if e.IsSubModule() {
|
||||
entryCommit = commitInfo.SubModuleFile.Commit
|
||||
}
|
||||
fileContentResponse.LatestCommit = api.ContentsResponseCommit{
|
||||
Message: entryCommit.CommitMessage,
|
||||
LatestCommitSha: entryCommit.ID.String(),
|
||||
Created: entryCommit.Author.When.Unix(),
|
||||
}
|
||||
break
|
||||
if commitInfo.Entry.Name() == fileContentResponse.Name {
|
||||
var entryCommit *git.Commit
|
||||
entryCommit = commitInfo.Commit
|
||||
if e.IsSubModule() {
|
||||
entryCommit = commitInfo.SubModuleFile.Commit
|
||||
}
|
||||
fileContentResponse.LatestCommit = api.ContentsResponseCommit{
|
||||
Message: entryCommit.CommitMessage,
|
||||
LatestCommitSha: entryCommit.ID.String(),
|
||||
Created: entryCommit.Author.When.Unix(),
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
|
|
@ -168,8 +167,8 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
|
|||
if refType == "invalid" {
|
||||
return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
|
||||
}
|
||||
// selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", repo.APIURL(), treePath, origRef))
|
||||
selfURL, err := url.Parse(url.PathEscape(fmt.Sprintf("%s/contents/%s?ref=%s", repo.APIURL(), treePath, origRef)))
|
||||
|
||||
selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", repo.APIURL(), treePath, origRef))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -190,7 +189,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
|
|||
// Now populate the rest of the ContentsResponse based on entry type
|
||||
if entry.IsRegular() || entry.IsExecutable() {
|
||||
contentsResponse.Type = string(ContentTypeRegular)
|
||||
if blobResponse, err := GetBlobBySHANew(repo, gitRepo, entry.ID.String()); err != nil {
|
||||
if blobResponse, err := GetBlobBySHA(repo, entry.ID.String()); err != nil {
|
||||
return nil, err
|
||||
} else if !forList {
|
||||
// We don't show the content if we are getting a list of FileContentResponses
|
||||
|
|
@ -220,8 +219,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
|
|||
// Handle links
|
||||
if entry.IsRegular() || entry.IsLink() {
|
||||
ref = fmt.Sprintf("%s", url.PathEscape(ref))
|
||||
// downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
||||
downloadURL, err := url.Parse(url.PathEscape(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath)))
|
||||
downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -230,16 +228,15 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
|
|||
}
|
||||
if !entry.IsSubModule() {
|
||||
ref = fmt.Sprintf("%s", url.PathEscape(ref))
|
||||
// htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
||||
htmlURL, err := url.Parse(url.PathEscape(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath)))
|
||||
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
htmlURLString := htmlURL.String()
|
||||
contentsResponse.HTMLURL = &htmlURLString
|
||||
contentsResponse.Links.HTMLURL = &htmlURLString
|
||||
// gitURL, err := url.Parse(fmt.Sprintf("%s/git/blobs/%s", repo.APIURL(), entry.ID.String()))
|
||||
gitURL, err := url.Parse(url.PathEscape(fmt.Sprintf("%s/git/blobs/%s", repo.APIURL(), entry.ID.String())))
|
||||
|
||||
gitURL, err := url.Parse(fmt.Sprintf("%s/git/blobs/%s", repo.APIURL(), entry.ID.String()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,21 +15,6 @@ import (
|
|||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
func GetBatchFileResponseFromCommit(repo *models.Repository, commit *git.Commit, branch string, treeNames []string) (*api.BatchFileResponse, error) {
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, commit)
|
||||
verification := GetPayloadCommitVerification(commit)
|
||||
batchFileResponse := &api.BatchFileResponse{
|
||||
Commit: fileCommitResponse,
|
||||
Verification: verification,
|
||||
}
|
||||
for _, treeName := range treeNames {
|
||||
fileContent, _ := GetContents(repo, treeName, branch, false)
|
||||
batchFileResponse.Contents = append(batchFileResponse.Contents, fileContent)
|
||||
}
|
||||
|
||||
return batchFileResponse, nil
|
||||
}
|
||||
|
||||
// GetFileResponseFromCommit Constructs a FileResponse from a Commit object
|
||||
func GetFileResponseFromCommit(repo *models.Repository, commit *git.Commit, branch, treeName string) (*api.FileResponse, error) {
|
||||
fileContents, _ := GetContents(repo, treeName, branch, false) // ok if fails, then will be nil
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
/*
|
||||
* @Descripttion:
|
||||
* @Author: hang
|
||||
* @version:
|
||||
* @Date: 2021-10-28 18:21:53
|
||||
* @LastEditors: hang
|
||||
*/
|
||||
// Copyright 2019 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 repofiles
|
||||
|
|
@ -19,7 +12,7 @@ import (
|
|||
// CleanUploadFileName Trims a filename and returns empty string if it is a .git directory
|
||||
func CleanUploadFileName(name string) string {
|
||||
// Rebase the filename
|
||||
name = strings.Trim(path.Clean("/"+name), "/")
|
||||
name = strings.Trim(path.Clean("/"+name), " /")
|
||||
// Git disallows any filenames to have a .git directory in them.
|
||||
for _, part := range strings.Split(name, "/") {
|
||||
if strings.ToLower(part) == ".git" {
|
||||
|
|
|
|||
|
|
@ -20,30 +20,11 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"github.com/gobwas/glob"
|
||||
|
||||
stdcharset "golang.org/x/net/html/charset"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
type FileActionType int
|
||||
|
||||
const (
|
||||
ActionTypeCreate FileActionType = iota + 1
|
||||
ActionTypeUpdate
|
||||
ActionTypeDelete
|
||||
)
|
||||
|
||||
var fileActionTypes = map[string]FileActionType{
|
||||
"create": ActionTypeCreate,
|
||||
"update": ActionTypeUpdate,
|
||||
"delete": ActionTypeDelete,
|
||||
}
|
||||
|
||||
func ToFileActionType(name string) FileActionType {
|
||||
return fileActionTypes[name]
|
||||
}
|
||||
|
||||
// IdentityOptions for a person's identity like an author or committer
|
||||
type IdentityOptions struct {
|
||||
Name string
|
||||
|
|
@ -73,31 +54,6 @@ type UpdateRepoFileOptions struct {
|
|||
Signoff bool
|
||||
}
|
||||
|
||||
type ExchangeFileOption struct {
|
||||
FileChan chan BatchSingleFileOption
|
||||
StopChan chan bool
|
||||
ErrChan chan error
|
||||
}
|
||||
|
||||
type BatchSingleFileOption struct {
|
||||
Content string
|
||||
TreePath string
|
||||
FromTreePath string
|
||||
ActionType FileActionType
|
||||
}
|
||||
type BatchUpdateFileOptions struct {
|
||||
Files []BatchSingleFileOption
|
||||
LastCommitID string
|
||||
OldBranch string
|
||||
NewBranch string
|
||||
Message string
|
||||
SHA string
|
||||
Author *IdentityOptions
|
||||
Commiter *IdentityOptions
|
||||
Dates *CommitDateOptions
|
||||
Signoff bool
|
||||
}
|
||||
|
||||
func detectEncodingAndBOM(entry *git.TreeEntry, repo *models.Repository) (string, bool) {
|
||||
reader, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
|
|
@ -307,7 +263,7 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
|||
} else if changed {
|
||||
return nil, models.ErrCommitIDDoesNotMatch{
|
||||
GivenCommitID: opts.LastCommitID,
|
||||
CurrentCommitID: commit.ID.String(),
|
||||
CurrentCommitID: opts.LastCommitID,
|
||||
}
|
||||
}
|
||||
// The file wasn't modified, so we are good to delete it
|
||||
|
|
@ -510,403 +466,3 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
|
|||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func CreateOrUpdateOrDeleteRepofiles(repo *models.Repository, doer *models.User, opts *BatchUpdateFileOptions, exchange *ExchangeFileOption) (*structs.BatchFileResponse, error) {
|
||||
|
||||
var protectedPatterns []glob.Glob
|
||||
if opts.OldBranch == "" {
|
||||
opts.OldBranch = repo.DefaultBranch
|
||||
}
|
||||
|
||||
if opts.NewBranch == "" {
|
||||
opts.NewBranch = opts.OldBranch
|
||||
}
|
||||
|
||||
// oldBranch must exist for this operation
|
||||
if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.NewBranch != opts.OldBranch {
|
||||
existingBranch, err := repo_module.GetBranch(repo, opts.NewBranch)
|
||||
if existingBranch != nil {
|
||||
return nil, models.ErrBranchAlreadyExists{
|
||||
BranchName: opts.NewBranch,
|
||||
}
|
||||
}
|
||||
if err != nil && !git.IsErrBranchNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
protectedBranch, err := repo.GetBranchProtection(opts.OldBranch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if protectedBranch != nil {
|
||||
if !protectedBranch.CanUserPush(doer.ID) {
|
||||
return nil, models.ErrUserCannotCommit{
|
||||
UserName: doer.LowerName,
|
||||
}
|
||||
}
|
||||
if protectedBranch.RequireSignedCommits {
|
||||
_, _, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), opts.OldBranch)
|
||||
if err != nil {
|
||||
if !models.IsErrWontSign(err) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, models.ErrUserCannotCommit{
|
||||
UserName: doer.LowerName,
|
||||
}
|
||||
}
|
||||
}
|
||||
protectedPatterns = protectedBranch.GetProtectedFilePatterns()
|
||||
}
|
||||
}
|
||||
|
||||
message := strings.TrimSpace(opts.Message)
|
||||
author, commiter := GetAuthorAndCommitterUsers(opts.Author, opts.Commiter, doer)
|
||||
|
||||
t, err := NewTemporaryUploadRepository(repo)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
}
|
||||
defer t.Close()
|
||||
if err := t.Clone(opts.OldBranch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := t.SetDefaultIndex(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the commit of the original branch
|
||||
commit, err := t.GetBranchCommit(opts.OldBranch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.LastCommitID == "" {
|
||||
opts.LastCommitID = commit.ID.String()
|
||||
} else {
|
||||
lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ConvertToSHA1: Invalid last commit ID: %v", err)
|
||||
}
|
||||
opts.LastCommitID = lastCommitID.String()
|
||||
}
|
||||
var commitHash string
|
||||
var treeNames []string
|
||||
|
||||
for {
|
||||
select {
|
||||
case file := <-exchange.FileChan:
|
||||
for _, pat := range protectedPatterns {
|
||||
if pat.Match(strings.ToLower(file.TreePath)) {
|
||||
return nil, models.ErrFilePathProtected{
|
||||
Path: file.TreePath,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
optTreePath := file.TreePath
|
||||
optFromTreePath := file.FromTreePath
|
||||
optActionType := file.ActionType
|
||||
optContent := file.Content
|
||||
|
||||
if optTreePath != "" && optFromTreePath == "" {
|
||||
optFromTreePath = optTreePath
|
||||
}
|
||||
|
||||
treePath := CleanUploadFileName(optTreePath)
|
||||
if treePath == "" {
|
||||
return nil, models.ErrFilenameInvalid{
|
||||
Path: optTreePath,
|
||||
}
|
||||
}
|
||||
|
||||
fromTreePath := CleanUploadFileName(optFromTreePath)
|
||||
if fromTreePath == "" && optFromTreePath != "" {
|
||||
return nil, models.ErrFilenameInvalid{
|
||||
Path: optFromTreePath,
|
||||
}
|
||||
}
|
||||
|
||||
if optActionType == ActionTypeDelete {
|
||||
// Get the files in the index
|
||||
filesInIndex, err := t.LsFiles(optTreePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("DeleteRepoFile: %v", err)
|
||||
}
|
||||
// Find the file we want to delete in the index
|
||||
inFilelist := false
|
||||
for _, file := range filesInIndex {
|
||||
if file == optTreePath {
|
||||
inFilelist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !inFilelist {
|
||||
return nil, models.ErrRepoFileDoesNotExist{
|
||||
Path: optTreePath,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the entry of treePath and check if the SHA given is the same as the file
|
||||
entry, err := commit.GetTreeEntryByPath(treePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if opts.SHA != "" {
|
||||
// If a SHA was given and the SHA given doesn't match the SHA of the fromTreePath, throw error
|
||||
if opts.SHA != entry.ID.String() {
|
||||
return nil, models.ErrSHADoesNotMatch{
|
||||
Path: treePath,
|
||||
GivenSHA: opts.SHA,
|
||||
CurrentSHA: entry.ID.String(),
|
||||
}
|
||||
}
|
||||
} else if opts.LastCommitID != "" {
|
||||
// If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
|
||||
// an error, but only if we aren't creating a new branch.
|
||||
if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
|
||||
// CommitIDs don't match, but we don't want to throw a ErrCommitIDDoesNotMatch unless
|
||||
// this specific file has been edited since opts.LastCommitID
|
||||
if changed, err := commit.FileChangedSinceCommit(treePath, opts.LastCommitID); err != nil {
|
||||
return nil, err
|
||||
} else if changed {
|
||||
return nil, models.ErrCommitIDDoesNotMatch{
|
||||
GivenCommitID: opts.LastCommitID,
|
||||
CurrentCommitID: opts.LastCommitID,
|
||||
}
|
||||
}
|
||||
// The file wasn't modified, so we are good to delete it
|
||||
}
|
||||
} else {
|
||||
// When deleting a file, a lastCommitID or SHA needs to be given to make sure other commits haven't been
|
||||
// made. We throw an error if one wasn't provided.
|
||||
return nil, models.ErrSHAOrCommitIDNotProvided{}
|
||||
}
|
||||
|
||||
// Remove the file from the index
|
||||
if err := t.RemoveFilesFromIndex(optTreePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
encoding := "UTF-8"
|
||||
bom := false
|
||||
executable := false
|
||||
|
||||
if optActionType == ActionTypeUpdate {
|
||||
fromEntry, err := commit.GetTreeEntryByPath(fromTreePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if opts.SHA != "" {
|
||||
if opts.SHA != fromEntry.ID.String() {
|
||||
return nil, models.ErrSHADoesNotMatch{
|
||||
Path: optTreePath,
|
||||
GivenSHA: opts.SHA,
|
||||
CurrentSHA: fromEntry.ID.String(),
|
||||
}
|
||||
}
|
||||
} else if opts.LastCommitID != "" {
|
||||
if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
|
||||
if changed, err := commit.FileChangedSinceCommit(treePath, opts.LastCommitID); err != nil {
|
||||
return nil, err
|
||||
} else if changed {
|
||||
return nil, models.ErrCommitIDDoesNotMatch{
|
||||
GivenCommitID: opts.LastCommitID,
|
||||
CurrentCommitID: opts.LastCommitID,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return nil, models.ErrSHAOrCommitIDNotProvided{}
|
||||
}
|
||||
encoding, bom = detectEncodingAndBOM(fromEntry, repo)
|
||||
executable = fromEntry.IsExecutable()
|
||||
}
|
||||
|
||||
treePathParts := strings.Split(treePath, "/")
|
||||
subTreePath := ""
|
||||
for index, part := range treePathParts {
|
||||
subTreePath = path.Join(subTreePath, part)
|
||||
entry, err := commit.GetTreeEntryByPath(subTreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if index < len(treePathParts)-1 {
|
||||
if !entry.IsDir() {
|
||||
return nil, models.ErrFilePathInvalid{
|
||||
Message: fmt.Sprintf("a file exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
|
||||
Path: subTreePath,
|
||||
Name: part,
|
||||
Type: git.EntryModeBlob,
|
||||
}
|
||||
}
|
||||
} else if entry.IsLink() {
|
||||
return nil, models.ErrFilePathInvalid{
|
||||
Message: fmt.Sprintf("a symbolic link exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
|
||||
Path: subTreePath,
|
||||
Name: part,
|
||||
Type: git.EntryModeSymlink,
|
||||
}
|
||||
} else if entry.IsDir() {
|
||||
return nil, models.ErrFilePathInvalid{
|
||||
Message: fmt.Sprintf("a directory exists where you’re trying to create a file [path: %s]", subTreePath),
|
||||
Path: subTreePath,
|
||||
Name: part,
|
||||
Type: git.EntryModeTree,
|
||||
}
|
||||
} else if fromTreePath != treePath || optActionType == ActionTypeCreate {
|
||||
return nil, models.ErrRepoFileAlreadyExists{
|
||||
Path: treePath,
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the two paths (might be the same if not moving) from the index if they exist
|
||||
filesInIndex, err := t.LsFiles(optTreePath, optFromTreePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("UpdateRepoFile: %v", err)
|
||||
}
|
||||
|
||||
if optActionType == ActionTypeCreate {
|
||||
for _, file := range filesInIndex {
|
||||
if file == optTreePath {
|
||||
return nil, models.ErrRepoFileAlreadyExists{
|
||||
Path: optTreePath,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the old path from the tree
|
||||
if fromTreePath != treePath && len(filesInIndex) > 0 {
|
||||
for _, file := range filesInIndex {
|
||||
if file == fromTreePath {
|
||||
if err := t.RemoveFilesFromIndex(optFromTreePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content := optContent
|
||||
if bom {
|
||||
content = string(charset.UTF8BOM) + content
|
||||
}
|
||||
if encoding != "UTF-8" {
|
||||
charsetEncoding, _ := stdcharset.Lookup(encoding)
|
||||
if charsetEncoding != nil {
|
||||
result, _, err := transform.String(charsetEncoding.NewEncoder(), content)
|
||||
if err != nil {
|
||||
log.Error("Error re-encoding %s (%s) as %s - will stay as UTF-8: %v", optTreePath, optFromTreePath, encoding, err)
|
||||
result = content
|
||||
}
|
||||
content = result
|
||||
} else {
|
||||
log.Error("Unknown encoding: %s", encoding)
|
||||
}
|
||||
}
|
||||
|
||||
optContent = content
|
||||
var lfsMetaObject *models.LFSMetaObject
|
||||
if setting.LFS.StartServer {
|
||||
filename2attribute2info, err := t.gitRepo.CheckAttribute(git.CheckAttributeOpts{
|
||||
Attributes: []string{"filter"},
|
||||
Filenames: []string{treePath},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
|
||||
pointer, err := lfs.GeneratePointer(strings.NewReader(optContent))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lfsMetaObject = &models.LFSMetaObject{Pointer: pointer, RepositoryID: repo.ID}
|
||||
content = pointer.StringContent()
|
||||
}
|
||||
}
|
||||
|
||||
objectHash, err := t.HashObject(strings.NewReader(content))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if executable {
|
||||
if err := t.AddObjectToIndex("100755", objectHash, treePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := t.AddObjectToIndex("100644", objectHash, treePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if lfsMetaObject != nil {
|
||||
lfsMetaObject, err = models.NewLFSMetaObject(lfsMetaObject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contentStore := lfs.NewContentStore()
|
||||
exist, err := contentStore.Exists(lfsMetaObject.Pointer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
if err := contentStore.Put(lfsMetaObject.Pointer, strings.NewReader(optContent)); err != nil {
|
||||
if _, err2 := repo.RemoveLFSMetaObjectByOid(lfsMetaObject.Oid); err2 != nil {
|
||||
return nil, fmt.Errorf("Error whilst removing failed inserted LFS object %s: %v (Prev Error: %v)", lfsMetaObject.Oid, err2, err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
opts.Files = append(opts.Files, file)
|
||||
treeNames = append(treeNames, file.TreePath)
|
||||
case err := <-exchange.ErrChan:
|
||||
return nil, err
|
||||
case _ = <-exchange.StopChan:
|
||||
goto end
|
||||
}
|
||||
}
|
||||
end:
|
||||
// Now write the tree
|
||||
treeHash, err := t.WriteTree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now commit the tree
|
||||
if opts.Dates != nil {
|
||||
commitHash, err = t.CommitTreeWithDate(author, commiter, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer)
|
||||
} else {
|
||||
commitHash, err = t.CommitTree(author, commiter, treeHash, message, opts.Signoff)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := t.Push(doer, commitHash, opts.NewBranch); err != nil {
|
||||
log.Error("%T %v", err, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commit, err = t.GetCommit(commitHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file, err := GetBatchFileResponseFromCommit(repo, commit, opts.NewBranch, treeNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ func GetBranch(repo *models.Repository, branch string) (*git.Branch, error) {
|
|||
return gitRepo.GetBranch(branch)
|
||||
}
|
||||
|
||||
func GetSearchBranches(repo *models.Repository, search string, skip, limit int) ([]*git.Branch, int, error) {
|
||||
return git.GetSearchBranchesByPath(repo.RepoPath(), search, skip, limit)
|
||||
}
|
||||
|
||||
// GetBranches returns branches from the repository, skipping skip initial branches and
|
||||
// returning at most limit branches, or all branches if limit is 0.
|
||||
func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int, error) {
|
||||
|
|
|
|||
|
|
@ -54,18 +54,18 @@ func (bk BranchKind) Title() string {
|
|||
type BranchesSlice struct {
|
||||
BranchName string `json:"branch_name"`
|
||||
// BranchKind int `json:"branch_kind"`
|
||||
Branches []*Branch `json:"branches"`
|
||||
Branches []Branch `json:"branches"`
|
||||
}
|
||||
|
||||
// sort by branchkind
|
||||
type SortBranch []*Branch
|
||||
type SortBranch []Branch
|
||||
|
||||
func (s SortBranch) Len() int { return len(s) }
|
||||
func (s SortBranch) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s SortBranch) Less(i, j int) bool { return s[i].BranchKind < s[j].BranchKind }
|
||||
|
||||
// sort by CommiTime of the branch
|
||||
type SortBranchTime []*Branch
|
||||
type SortBranchTime []Branch
|
||||
|
||||
func (s SortBranchTime) Len() int { return len(s) }
|
||||
func (s SortBranchTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
|
|
|||
|
|
@ -30,19 +30,6 @@ type CreateFileOptions struct {
|
|||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// BatchCreateFileOptions options for creating more files
|
||||
type BatchChangeFileOptions struct {
|
||||
Header FileOptions `json:"header"`
|
||||
Files []struct {
|
||||
// enum: text,base64
|
||||
Encoding string `json:"encoding"`
|
||||
FilePath string `json:"file_path"`
|
||||
Content string `json:"content"`
|
||||
// enum: create,update,delete
|
||||
ActionType string `json:"action_type"`
|
||||
} `json:"files"`
|
||||
}
|
||||
|
||||
// DeleteFileOptions options for deleting files (used for other File structs below)
|
||||
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
|
||||
type DeleteFileOptions struct {
|
||||
|
|
@ -119,12 +106,6 @@ type FileResponse struct {
|
|||
Verification *PayloadCommitVerification `json:"verification"`
|
||||
}
|
||||
|
||||
type BatchFileResponse struct {
|
||||
Contents []*ContentsResponse `json:"contents"`
|
||||
Commit *FileCommitResponse `json:"commit"`
|
||||
Verification *PayloadCommitVerification `json:"verification"`
|
||||
}
|
||||
|
||||
// FileDeleteResponse contains information about a repo's file that was deleted
|
||||
type FileDeleteResponse struct {
|
||||
Content interface{} `json:"content"` // to be set to nil
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2021 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 structs
|
||||
|
||||
// WikiCommit page commit/revision
|
||||
type WikiCommit struct {
|
||||
ID string `json:"sha"`
|
||||
Author *CommitUser `json:"author"`
|
||||
Committer *CommitUser `json:"commiter"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// WikiPage a wiki page
|
||||
type WikiPage struct {
|
||||
*WikiPageMetaData
|
||||
// Page content, base64 encoded
|
||||
ContentBase64 string `json:"content_base64"`
|
||||
CommitCount int64 `json:"commit_count"`
|
||||
Sidebar string `json:"sidebar"`
|
||||
Footer string `json:"footer"`
|
||||
}
|
||||
|
||||
// WikiPageMetaData wiki page meta information
|
||||
type WikiPageMetaData struct {
|
||||
Title string `json:"title"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
SubURL string `json:"sub_url"`
|
||||
LastCommit *WikiCommit `json:"last_commit"`
|
||||
}
|
||||
|
||||
type WikiListMetaData struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
SubURL string `json:"sub_url"`
|
||||
LastCommit *WikiCommit `json:"last_commit"`
|
||||
}
|
||||
|
||||
// CreateWikiPageOptions form for creating wiki
|
||||
type CreateWikiPageOptions struct {
|
||||
// page title. leave empty to keep unchanged
|
||||
Title string `json:"title"`
|
||||
// content must be base64 encoded
|
||||
ContentBase64 string `json:"content_base64"`
|
||||
// optional commit message summarizing the change
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// WikiCommitList commit/revision list
|
||||
type WikiCommitList struct {
|
||||
WikiCommits []*WikiCommit `json:"commits"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
|
@ -6,13 +6,13 @@ type WikiesResponse struct {
|
|||
}
|
||||
|
||||
type WikiMeta struct {
|
||||
Name string `json:"name"`
|
||||
Commit OldWikiCommit `json:"commit"`
|
||||
FirstCommit OldWikiCommit `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Commit WikiCommit `json:"commit"`
|
||||
FirstCommit WikiCommit `json:"-"`
|
||||
//WikiCloneLink CloneLink `json:"wiki_clone_link"`
|
||||
}
|
||||
|
||||
type OldWikiCommit struct {
|
||||
type WikiCommit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Author WikiUser `json:"author"`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
本协议是您(如下也称“用户”)与国防科技大学计算机学院国产基础软件工程研究中心(以下简称“中心”),关于麒麟如意内核软件(以下简称“本软件”)的协议,请认真阅读。
|
||||
1.申请使用本软件的用户均需填写本协议,并遵守本协议各项条件的约束。
|
||||
2.用户须在本平台内使用本软件,不得以拷贝、刻录等方式将本软件传播至本平台以外的任何第三方平台或主体。若需要向本平台以外的第三方平台或主体传播,用户需向中心提出申请并获书面授权。
|
||||
3.对于未签署本协议的第三者,一旦申请使用本软件,即表示第三者同意接受本协议各项条件的约束。如果第三者不同意本协议的条件,则不能获得使用本软件的权利。
|
||||
4.用户有权提出对软件的使用反馈及意见,用户可以发表对软件的使用体验及感受,但不得随意诽谤、中伤。
|
||||
5.用户可以在软件上添加、修改源代码,但必须遵守本软件的开源许可协议的规定。
|
||||
6.用户须保证其添加、修改的代码内容所涉及的知识产权均为其个体所有,或经过知识产权所有者的授权,用户须保证其对于前述代码内容造成的侵权并不知情。若用户提供的代码内容涉及其它第三方开源平台,用户需保证其传播方式满足该开源平台的相关约定。
|
||||
7.本中心/本协议鼓励用户将开发成果返回至开发团队,或在如意内核软件中开源,开发者将在代码中署名。
|
||||
8.未经本中心书面许可,用户不得将该软件用于商业用途;若该软件被用户用于学术研究,则相关学术成果中应明示引用如意内核软件。
|
||||
9.您获得的只是对于本软件非商业用途的使用权。本软件仅限中华人民共和国公民申请使用。
|
||||
10.本协议的最终解释权归中心。
|
||||
|
|
@ -826,12 +826,12 @@ func Routes() *web.Route {
|
|||
})
|
||||
}, reqToken(), reqAdmin())
|
||||
m.Group("/wikies", func() {
|
||||
m.Combo("").Get(repo.OldListWikiPages).
|
||||
Post(bind(api.WikiOption{}), repo.OldCreateWiki)
|
||||
m.Combo("").Get(repo.ListWikiPages).
|
||||
Post(bind(api.WikiOption{}), repo.CreateWiki)
|
||||
m.Group("/{page}", func() {
|
||||
m.Combo("").Get(repo.OldGetWiki).
|
||||
Patch(bind(api.WikiOption{}), repo.OldEditWiki).
|
||||
Delete(repo.OldDeleteWiki)
|
||||
m.Combo("").Get(repo.GetWiki).
|
||||
Patch(bind(api.WikiOption{}), repo.EditWiki).
|
||||
Delete(repo.DeleteWiki)
|
||||
})
|
||||
})
|
||||
m.Group("/readme", func() {
|
||||
|
|
@ -859,15 +859,6 @@ func Routes() *web.Route {
|
|||
m.Combo("").Get(repo.ListTrackedTimesByRepository)
|
||||
m.Combo("/{timetrackingusername}").Get(repo.ListTrackedTimesByUser)
|
||||
}, mustEnableIssues, reqToken())
|
||||
m.Group("/wiki", func() {
|
||||
m.Combo("/page/{pageName}").
|
||||
Get(repo.GetWikiPage).
|
||||
Patch(mustNotBeArchived, bind(api.CreateWikiPageOptions{}), repo.EditWikiPage).
|
||||
Delete(mustNotBeArchived, repo.DeleteWikiPage)
|
||||
m.Get("/revisions/{pageName}", repo.ListPageRevisions)
|
||||
m.Post("/new", mustNotBeArchived, bind(api.CreateWikiPageOptions{}), repo.NewWikiPage)
|
||||
m.Get("/pages", repo.ListWikiPages)
|
||||
})
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("").Get(repo.ListIssues).
|
||||
Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue)
|
||||
|
|
@ -1032,9 +1023,6 @@ func Routes() *web.Route {
|
|||
m.Put("", bind(api.UpdateFileOptions{}), repo.UpdateFile)
|
||||
m.Delete("", bind(api.DeleteFileOptions{}), repo.DeleteFile)
|
||||
}, reqRepoWriter(models.UnitTypeCode), reqToken())
|
||||
m.Group("/batch", func() {
|
||||
m.Post("", bind(api.BatchChangeFileOptions{}), repo.BatchChangeFile)
|
||||
}, reqRepoWriter(models.UnitTypeCode), reqToken())
|
||||
}, reqRepoReader(models.UnitTypeCode))
|
||||
m.Get("/signing-key.gpg", misc.SigningKey)
|
||||
m.Group("/topics", func() {
|
||||
|
|
@ -1047,8 +1035,6 @@ func Routes() *web.Route {
|
|||
}, reqAnyRepoReader())
|
||||
m.Get("/issue_templates", context.ReferencesGitRepo(false), repo.GetIssueTemplates)
|
||||
m.Get("/languages", reqRepoReader(models.UnitTypeCode), repo.GetLanguages)
|
||||
m.Get("/diffs", context.RepoRef(), repo.GetRepoDiffs)
|
||||
m.Get("/blame", context.RepoRef(), repo.GetRepoRefBlame)
|
||||
}, repoAssignment())
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
)
|
||||
|
||||
type APIBlameResponse struct {
|
||||
FileSize int64 `json:"file_size"`
|
||||
FileName string `json:"file_name"`
|
||||
NumberLines int `json:"num_lines"`
|
||||
BlameParts []git.ApiBlamePart `json:"blame_parts"`
|
||||
}
|
||||
|
||||
func GetRepoRefBlame(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/blame repository repoGetRefBlame
|
||||
// ---
|
||||
// summary: Get blame from a repository by sha and filepath***
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: sha
|
||||
// in: query
|
||||
// description: repo commit sha or branch
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: filepath
|
||||
// in: query
|
||||
// description: filepath in repository
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// 200:
|
||||
// description: success
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
var commit *git.Commit
|
||||
if sha := ctx.QueryTrim("sha"); len(sha) > 0 {
|
||||
var err error
|
||||
commit, err = ctx.Repo.GitRepo.GetCommit(sha)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Println(commit)
|
||||
|
||||
filepath := ctx.QueryTrim("filepath")
|
||||
fmt.Println(filepath)
|
||||
entry, err := commit.GetTreeEntryByPath(filepath)
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("commit.GetTreeEntryByPath", git.IsErrNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
blob := entry.Blob()
|
||||
numLines, err := blob.GetBlobLineCount()
|
||||
if err != nil {
|
||||
ctx.NotFound("GetBlobLineCount", err)
|
||||
return
|
||||
}
|
||||
blameReader, err := git.CreateBlameReader(ctx, models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name), commit.ID.String(), filepath)
|
||||
if err != nil {
|
||||
ctx.NotFound("CreateBlameReader", err)
|
||||
return
|
||||
}
|
||||
defer blameReader.Close()
|
||||
|
||||
blameParts := make([]git.ApiBlamePart, 0)
|
||||
currentNumber := 1
|
||||
for {
|
||||
blamePart, err := blameReader.NextApiPart(ctx.Repo.GitRepo)
|
||||
if err != nil {
|
||||
ctx.NotFound("NextPart", err)
|
||||
return
|
||||
}
|
||||
if blamePart == nil {
|
||||
break
|
||||
}
|
||||
blamePart.CurrentNumber = currentNumber
|
||||
blameParts = append(blameParts, *blamePart)
|
||||
currentNumber += blamePart.EffectLine
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, APIBlameResponse{
|
||||
FileSize: blob.Size(),
|
||||
FileName: blob.Name(),
|
||||
NumberLines: numLines,
|
||||
BlameParts: blameParts,
|
||||
})
|
||||
}
|
||||
|
|
@ -244,10 +244,6 @@ func ListBranches(ctx *context.APIContext) {
|
|||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: name
|
||||
// in: query
|
||||
// description: name of the branch
|
||||
// type: string
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
|
|
@ -260,10 +256,9 @@ func ListBranches(ctx *context.APIContext) {
|
|||
// "200":
|
||||
// "$ref": "#/responses/BranchList"
|
||||
|
||||
searchName := ctx.Query("name")
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
skip, _ := listOptions.GetStartEnd()
|
||||
branches, totalNumOfBranches, err := repo_module.GetSearchBranches(ctx.Repo.Repository, searchName, skip, listOptions.PageSize)
|
||||
branches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
|
||||
return
|
||||
|
|
@ -312,27 +307,21 @@ func ListBranchesSlice(ctx *context.APIContext) {
|
|||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/BranchList"
|
||||
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
skip, _ := listOptions.GetStartEnd()
|
||||
// listOptions := utils.GetListOptions(ctx)
|
||||
// skip, _ := listOptions.GetStartEnd()
|
||||
// branches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize)
|
||||
branches, totalNumOfBranches, err := repo_module.GetBranchesNoLimit(ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
|
||||
return
|
||||
}
|
||||
|
||||
apiBranches := make([]*api.Branch, len(branches))
|
||||
// apiBranchesSlice := []api.Branch{}
|
||||
apiBranchesList := []api.Branch{}
|
||||
for i := range branches {
|
||||
c, err := branches[i].GetCommit()
|
||||
if err != nil {
|
||||
|
|
@ -349,38 +338,19 @@ func ListBranchesSlice(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
sort.Sort(api.SortBranch(apiBranches))
|
||||
branchSlice := pageate(apiBranches, skip, listOptions.PageSize)
|
||||
BranchesSlice := BranchesSliceByProtection(ctx, branchSlice)
|
||||
apiBranchesList = append(apiBranchesList, *apiBranches[i])
|
||||
sort.Sort(api.SortBranch(apiBranchesList))
|
||||
|
||||
ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize)
|
||||
}
|
||||
|
||||
// ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize)
|
||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumOfBranches))
|
||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
|
||||
ctx.JSON(http.StatusOK, &BranchesSlice)
|
||||
|
||||
// ctx.JSON(http.StatusOK, &apiBranches)
|
||||
ctx.JSON(http.StatusOK, BranchesSliceByProtection(ctx, apiBranchesList))
|
||||
}
|
||||
|
||||
func pageate(branchSlice []*api.Branch, skip, pageSize int) []*api.Branch {
|
||||
limit := func() int {
|
||||
if skip+pageSize > len(branchSlice) {
|
||||
return len(branchSlice)
|
||||
} else {
|
||||
return skip + pageSize
|
||||
}
|
||||
}
|
||||
start := func() int {
|
||||
if skip > len(branchSlice) {
|
||||
return len(branchSlice)
|
||||
} else {
|
||||
return skip
|
||||
}
|
||||
}
|
||||
return branchSlice[start():limit()]
|
||||
|
||||
}
|
||||
|
||||
func BranchesSliceByProtection(ctx *context.APIContext, branchList []*api.Branch) []api.BranchesSlice {
|
||||
func BranchesSliceByProtection(ctx *context.APIContext, branchList []api.Branch) []api.BranchesSlice {
|
||||
// group by protection
|
||||
sort.Sort(api.SortBranch(branchList))
|
||||
branchSlice := make([]api.BranchesSlice, 0)
|
||||
|
|
|
|||
|
|
@ -539,34 +539,7 @@ func GetFileAllCommits(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
// 获取 commit diff
|
||||
// Diff get diffs by commit on a repository
|
||||
func Diff(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/commits/{sha}/diff repository repoGetDiffs***
|
||||
// ---
|
||||
// summary: Get diffs by commit from a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: sha
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// 200:
|
||||
// description: success
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
commitID := ctx.Params(":sha")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
)
|
||||
|
||||
// GetRepoDiffs get diffs by from\to on a repository
|
||||
func GetRepoDiffs(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/diffs repository repoGetDiffs
|
||||
// ---
|
||||
// summary: Get diffs from a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: from
|
||||
// in: query
|
||||
// description: "from branch or sha"
|
||||
// type: string
|
||||
// required: false
|
||||
// - name: to
|
||||
// in: query
|
||||
// description: "to branch or sha"
|
||||
// type: string
|
||||
// required: false
|
||||
// responses:
|
||||
// 200:
|
||||
// description: success
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if from := ctx.QueryTrim("from"); len(from) > 0 {
|
||||
var err error
|
||||
_, err = ctx.Repo.GitRepo.GetCommit(from)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if to := ctx.QueryTrim("to"); len(to) > 0 {
|
||||
var err error
|
||||
_, err = ctx.Repo.GitRepo.GetCommit(to)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound()
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if diffs, err := gitdiff.GetDiffRange(ctx.Repo.GitRepo, ctx.QueryTrim("from"), ctx.QueryTrim("to"), setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles); err == nil {
|
||||
ctx.JSON(200, diffs)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetDiffRange", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -280,76 +280,11 @@ func CreateFile(ctx *context.APIContext) {
|
|||
|
||||
if fileResponse, err := createOrUpdateFile(ctx, opts); err != nil {
|
||||
handleCreateOrUpdateFileError(ctx, err)
|
||||
return
|
||||
} else {
|
||||
ctx.JSON(http.StatusCreated, fileResponse)
|
||||
}
|
||||
}
|
||||
|
||||
// BatchChangeFile handles API call for change some files***
|
||||
func BatchChangeFile(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/contents/batch repository repoBatchChangeFile
|
||||
// ---
|
||||
// summary: Change some files in a repository***
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// required: true
|
||||
// schema:
|
||||
// "$ref": "#/definitions/BatchChangeFileOptions"
|
||||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/BatchFileResponse"
|
||||
// "403":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
// "$ref": "#/responses/error"
|
||||
apiBatchOpts := web.GetForm(ctx).(*api.BatchChangeFileOptions)
|
||||
fmt.Println(apiBatchOpts)
|
||||
|
||||
if ctx.Repo.Repository.IsEmpty {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
|
||||
}
|
||||
|
||||
if apiBatchOpts.Header.BranchName == "" {
|
||||
apiBatchOpts.Header.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||
}
|
||||
|
||||
if apiBatchOpts.Header.Message == "" {
|
||||
apiBatchOpts.Header.Message = time.Now().Format("RFC3339")
|
||||
}
|
||||
|
||||
if apiBatchOpts.Header.Dates.Author.IsZero() {
|
||||
apiBatchOpts.Header.Dates.Author = time.Now()
|
||||
}
|
||||
|
||||
if apiBatchOpts.Header.Dates.Committer.IsZero() {
|
||||
apiBatchOpts.Header.Dates.Committer = time.Now()
|
||||
}
|
||||
|
||||
if batchFileResponse, err := createOrUpdateOrDeleteFiles(ctx, apiBatchOpts); err != nil {
|
||||
handleCreateOrUpdateFileError(ctx, err)
|
||||
} else {
|
||||
ctx.JSON(http.StatusOK, batchFileResponse)
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateFile handles API call for updating a file
|
||||
func UpdateFile(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /repos/{owner}/{repo}/contents/{filepath} repository repoUpdateFile
|
||||
|
|
@ -457,59 +392,6 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
|
|||
ctx.Error(http.StatusInternalServerError, "UpdateFile", err)
|
||||
}
|
||||
|
||||
func createOrUpdateOrDeleteFiles(ctx *context.APIContext, apiBatchOpts *api.BatchChangeFileOptions) (*api.BatchFileResponse, error) {
|
||||
if !canWriteFiles(ctx.Repo) {
|
||||
return nil, models.ErrUserDoesNotHaveAccessToRepo{
|
||||
UserID: ctx.User.ID,
|
||||
RepoName: ctx.Repo.Repository.LowerName,
|
||||
}
|
||||
}
|
||||
fileChan := make(chan repofiles.BatchSingleFileOption)
|
||||
stopChan := make(chan bool)
|
||||
errChan := make(chan error)
|
||||
exchangeOption := &repofiles.ExchangeFileOption{
|
||||
FileChan: fileChan,
|
||||
StopChan: stopChan,
|
||||
ErrChan: errChan,
|
||||
}
|
||||
go func() {
|
||||
for _, f := range apiBatchOpts.Files {
|
||||
if f.Encoding == "base64" {
|
||||
content, err := base64.StdEncoding.DecodeString(f.Content)
|
||||
exchangeOption.ErrChan <- err
|
||||
f.Content = string(content)
|
||||
}
|
||||
exchangeOption.FileChan <- repofiles.BatchSingleFileOption{
|
||||
Content: f.Content,
|
||||
TreePath: f.FilePath,
|
||||
ActionType: repofiles.ToFileActionType(f.ActionType),
|
||||
}
|
||||
}
|
||||
exchangeOption.StopChan <- true
|
||||
}()
|
||||
|
||||
opts := &repofiles.BatchUpdateFileOptions{
|
||||
Message: apiBatchOpts.Header.Message,
|
||||
OldBranch: apiBatchOpts.Header.BranchName,
|
||||
NewBranch: apiBatchOpts.Header.NewBranchName,
|
||||
Commiter: &repofiles.IdentityOptions{
|
||||
Name: apiBatchOpts.Header.Committer.Name,
|
||||
Email: apiBatchOpts.Header.Committer.Email,
|
||||
},
|
||||
Author: &repofiles.IdentityOptions{
|
||||
Name: apiBatchOpts.Header.Author.Name,
|
||||
Email: apiBatchOpts.Header.Author.Email,
|
||||
},
|
||||
Dates: &repofiles.CommitDateOptions{
|
||||
Author: apiBatchOpts.Header.Dates.Author,
|
||||
Committer: apiBatchOpts.Header.Dates.Committer,
|
||||
},
|
||||
Signoff: apiBatchOpts.Header.Signoff,
|
||||
}
|
||||
|
||||
return repofiles.CreateOrUpdateOrDeleteRepofiles(ctx.Repo.Repository, ctx.User, opts, exchangeOption)
|
||||
}
|
||||
|
||||
// Called from both CreateFile or UpdateFile to handle both
|
||||
func createOrUpdateFile(ctx *context.APIContext, opts *repofiles.UpdateRepoFileOptions) (*api.FileResponse, error) {
|
||||
if !canWriteFiles(ctx.Repo) {
|
||||
|
|
|
|||
|
|
@ -1383,39 +1383,7 @@ func GetPullCommits(ctx *context.APIContext) {
|
|||
|
||||
ctx.JSON(200, result)
|
||||
}
|
||||
|
||||
// GetPullFiles gets all files with a given PR
|
||||
func GetPullFiles(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/pulls/{index}/files repository repoListPullRequestsFiles
|
||||
// ---
|
||||
// summary: List a repo's pull requests files
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: index
|
||||
// in: path
|
||||
// description: index of the pull request to get
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: not-need-files
|
||||
// in: query
|
||||
// description: "not need responses files"
|
||||
// type: string
|
||||
// enum: [true, false]
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/Diff"
|
||||
|
||||
pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
issue := pr.Issue
|
||||
|
|
@ -1462,22 +1430,6 @@ func GetPullFiles(ctx *context.APIContext) {
|
|||
endCommitID = headCommitID
|
||||
|
||||
ctx.Data["WhitespaceBehavior"] = ""
|
||||
if ctx.Query("not-need-files") == "true" {
|
||||
diff := &gitdiff.Diff{Files: make([]*gitdiff.DiffFile, 0)}
|
||||
shortstatArgs := []string{startCommitID + "..." + endCommitID}
|
||||
if len(startCommitID) == 0 || startCommitID == git.EmptySHA {
|
||||
shortstatArgs = []string{git.EmptyTreeSHA, endCommitID}
|
||||
}
|
||||
diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Path, shortstatArgs...)
|
||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||
// git >= 2.28 now returns an error if base and head have become unrelated.
|
||||
// previously it would return the results of git diff --shortstat base head so let's try that...
|
||||
shortstatArgs = []string{startCommitID, endCommitID}
|
||||
diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Path, shortstatArgs...)
|
||||
}
|
||||
ctx.JSON(200, diff)
|
||||
return
|
||||
}
|
||||
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
|
||||
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
|
||||
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
|
||||
|
|
|
|||
|
|
@ -1198,20 +1198,17 @@ func CompareDiff(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
different := struct {
|
||||
Commits []CompareCommit
|
||||
Diff interface{}
|
||||
CommitsCount int
|
||||
LatestSha string
|
||||
Commits []CompareCommit
|
||||
Diff interface{}
|
||||
LatestSha string
|
||||
}{
|
||||
Commits: result,
|
||||
Diff: ctx.Context.Data["Diff"],
|
||||
}
|
||||
|
||||
// if len(different.Commits) != 0 {
|
||||
// different.LatestSha = different.Commits[0].Sha
|
||||
// }
|
||||
different.CommitsCount = compareInfo.Commits.Len()
|
||||
different.LatestSha = compareInfo.HeadCommitID
|
||||
if len(different.Commits) != 0 {
|
||||
different.LatestSha = different.Commits[0].Sha
|
||||
}
|
||||
|
||||
ctx.JSON(200, different)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,9 +301,7 @@ func BranchTagCount(ctx *context.APIContext) {
|
|||
// "200":
|
||||
// "$ref": "#/responses/RepoBranchAndTagCount"
|
||||
|
||||
tagsCount, err := models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
|
||||
IncludeTags: true,
|
||||
})
|
||||
tagsCount, err := ctx.Repo.GitRepo.GetTagCount() // tags info
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetTagCount", err)
|
||||
return
|
||||
|
|
@ -338,17 +336,12 @@ func BranchNameSet(ctx *context.APIContext) {
|
|||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: name
|
||||
// in: query
|
||||
// description: name of the branch
|
||||
// type: string
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/BranchNameSet"
|
||||
|
||||
searchName := ctx.Query("name")
|
||||
repo := ctx.Repo.Repository
|
||||
branches, _, err := repo_module.GetSearchBranches(repo, searchName, 0, 0) //get count of the branch
|
||||
branches, _, err := repo_module.GetBranches(repo, 0, 0) //get count of the branch
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBranches", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -2,22 +2,15 @@ package repo
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/markdown"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
webWiki "code.gitea.io/gitea/routers/web/repo"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
|
|
@ -25,525 +18,7 @@ import (
|
|||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
)
|
||||
|
||||
// NewWikiPage response for wiki create request
|
||||
func NewWikiPage(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/wiki/new repository repoCreateWikiPage
|
||||
// ---
|
||||
// summary: Create a wiki page
|
||||
// consumes:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/CreateWikiPageOptions"
|
||||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/WikiPage"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
|
||||
form := web.GetForm(ctx).(*api.CreateWikiPageOptions)
|
||||
|
||||
if util.IsEmptyString(form.Title) {
|
||||
ctx.Error(http.StatusBadRequest, "emptyTitle", nil)
|
||||
return
|
||||
}
|
||||
|
||||
wikiName := wiki_service.NormalizeWikiName(form.Title)
|
||||
|
||||
if len(form.Message) == 0 {
|
||||
form.Message = fmt.Sprintf("Add '%s'", form.Title)
|
||||
}
|
||||
|
||||
content, err := base64.StdEncoding.DecodeString(form.ContentBase64)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusBadRequest, "invalid base64 encoding of content", err)
|
||||
return
|
||||
}
|
||||
form.ContentBase64 = string(content)
|
||||
|
||||
if err := wiki_service.AddWikiPage(ctx.User, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil {
|
||||
if models.IsErrWikiReservedName(err) {
|
||||
ctx.Error(http.StatusBadRequest, "IsErrWikiReservedName", err)
|
||||
} else if models.IsErrWikiAlreadyExist(err) {
|
||||
ctx.Error(http.StatusBadRequest, "IsErrWikiAlreadyExists", err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "AddWikiPage", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
wikiPage := getWikiPage(ctx, wikiName)
|
||||
if !ctx.Written() {
|
||||
ctx.JSON(http.StatusCreated, wikiPage)
|
||||
}
|
||||
}
|
||||
|
||||
// EditWikiPage response for wiki modify request
|
||||
func EditWikiPage(ctx *context.APIContext) {
|
||||
// swagger:operation PATCH /repos/{owner}/{repo}/wiki/page/{pageName} repository repoEditWikiPage
|
||||
// ---
|
||||
// summary: Edit a wiki page
|
||||
// consumes:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: pageName
|
||||
// in: path
|
||||
// description: name of the page
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/CreateWikiPageOptions"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/WikiPage"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
form := web.GetForm(ctx).(*api.CreateWikiPageOptions)
|
||||
|
||||
oldWikiName := wiki_service.NormalizeWikiName(ctx.Params(":pageName"))
|
||||
newWikiName := wiki_service.NormalizeWikiName(form.Title)
|
||||
|
||||
if len(newWikiName) == 0 {
|
||||
newWikiName = oldWikiName
|
||||
}
|
||||
|
||||
if len(form.Message) == 0 {
|
||||
form.Message = fmt.Sprintf("Update '%s'", newWikiName)
|
||||
}
|
||||
|
||||
content, err := base64.RawStdEncoding.DecodeString(form.ContentBase64)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusBadRequest, "invalid base64 encoding of content", err)
|
||||
return
|
||||
}
|
||||
form.ContentBase64 = string(content)
|
||||
|
||||
if err := wiki_service.EditWikiPage(ctx.User, ctx.Repo.Repository, oldWikiName, newWikiName, form.ContentBase64, form.Message); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "EditWikiPage", err)
|
||||
return
|
||||
}
|
||||
|
||||
wikiPage := getWikiPage(ctx, newWikiName)
|
||||
|
||||
if !ctx.Written() {
|
||||
ctx.JSON(http.StatusOK, wikiPage)
|
||||
}
|
||||
}
|
||||
|
||||
func getWikiPage(ctx *context.APIContext, title string) *api.WikiPage {
|
||||
title = wiki_service.NormalizeWikiName(title)
|
||||
|
||||
wikiRepo, commit := findWikiRepoCommit(ctx)
|
||||
if wikiRepo != nil {
|
||||
defer wikiRepo.Close()
|
||||
}
|
||||
if ctx.Written() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// lookup filename in wiki - get filecontent, real filename
|
||||
content, pageFilename := wikiContentsByName(ctx, commit, title, false)
|
||||
if ctx.Written() {
|
||||
return nil
|
||||
}
|
||||
|
||||
sidebarContent, _ := wikiContentsByName(ctx, commit, "_Sidebar", true)
|
||||
if ctx.Written() {
|
||||
return nil
|
||||
}
|
||||
|
||||
footerContent, _ := wikiContentsByName(ctx, commit, "_Footer", true)
|
||||
if ctx.Written() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// get commit count - wiki revisions
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
|
||||
// Get last change information
|
||||
lastCommit, err := wikiRepo.GetCommitByPath(pageFilename)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommitByPath", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return &api.WikiPage{
|
||||
WikiPageMetaData: convert.ToWikiPageMetaData(title, lastCommit, ctx.Repo.Repository),
|
||||
ContentBase64: content,
|
||||
CommitCount: commitsCount,
|
||||
Sidebar: sidebarContent,
|
||||
Footer: footerContent,
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteWikiPage delete wiki page
|
||||
func DeleteWikiPage(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/wiki/page/{pageName} repository repoDeleteWikiPage
|
||||
// ---
|
||||
// summary: Delete a wiki page
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: pageName
|
||||
// in: path
|
||||
// description: name of the page
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
wikiName := wiki_service.NormalizeWikiName(ctx.Params(":pageName"))
|
||||
|
||||
if err := wiki_service.DeleteWikiPage(ctx.User, ctx.Repo.Repository, wikiName); err != nil {
|
||||
if err.Error() == "file does not exist" {
|
||||
ctx.NotFound(err)
|
||||
return
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteWikiPage", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// ListWikiPages get wiki pages list
|
||||
func ListWikiPages(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/wiki/pages repository repoGetWikiPages
|
||||
// ---
|
||||
// summary: Get all wiki pages
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: filepath
|
||||
// in: query
|
||||
// description: path of the file
|
||||
// type: string
|
||||
// required: false
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// - name: limit
|
||||
// in: query
|
||||
// description: page size of results
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/WikiPageList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
wikiRepo, commit := findWikiRepoCommit(ctx)
|
||||
if wikiRepo != nil {
|
||||
defer wikiRepo.Close()
|
||||
}
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
limit := ctx.QueryInt("limit")
|
||||
if limit <= 1 {
|
||||
limit = setting.API.DefaultPagingNum
|
||||
}
|
||||
|
||||
skip := (page - 1) * limit
|
||||
max := page * limit
|
||||
filePath := ctx.Query("filepath")
|
||||
var entries []*git.TreeEntry
|
||||
var err error
|
||||
if filePath == "" {
|
||||
entries, err = commit.ListEntries()
|
||||
} else {
|
||||
tree, subTreeErr := commit.SubTree(filePath)
|
||||
if subTreeErr != nil {
|
||||
ctx.ServerError("SubTree", err)
|
||||
return
|
||||
}
|
||||
entries, err = tree.ListEntries()
|
||||
}
|
||||
if err != nil {
|
||||
ctx.ServerError("ListEntries", err)
|
||||
return
|
||||
}
|
||||
lists := make([]*api.WikiListMetaData, 0, len(entries))
|
||||
for i, entry := range entries {
|
||||
if i < skip || i >= max || (!entry.IsRegular() && !entry.IsDir()) {
|
||||
continue
|
||||
}
|
||||
if entry.IsRegular() {
|
||||
c, err := wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name()))
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||
return
|
||||
}
|
||||
wikiName, err := wiki_service.FilenameToName(entry.Name())
|
||||
if err != nil {
|
||||
if models.IsErrWikiInvalidFileName(err) {
|
||||
continue
|
||||
}
|
||||
ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err)
|
||||
return
|
||||
}
|
||||
lists = append(lists, convert.RegularToWikiPageMetaData(wikiName, c, ctx.Repo.Repository))
|
||||
}
|
||||
if entry.IsDir() {
|
||||
c, err := wikiRepo.GetCommitByPath(fmt.Sprintf("%s/%s", filePath, entry.Name()))
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||
return
|
||||
}
|
||||
lists = append(lists, convert.DirToWikiPageMetaData(entry.Name(), c, ctx.Repo.Repository))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(int64(len(entries)))
|
||||
ctx.JSON(http.StatusOK, lists)
|
||||
}
|
||||
|
||||
// GetWikiPage get single wiki page
|
||||
func GetWikiPage(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/wiki/page/{pageName} repository repoGetWikiPage
|
||||
// ---
|
||||
// summary: Get a wiki page
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: pageName
|
||||
// in: path
|
||||
// description: name of the page
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/WikiPage"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
// get requested pagename
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":pageName"))
|
||||
|
||||
wikiPage := getWikiPage(ctx, pageName)
|
||||
if !ctx.Written() {
|
||||
ctx.JSON(http.StatusOK, wikiPage)
|
||||
}
|
||||
}
|
||||
|
||||
// ListPageRevisions renders file revision list of wiki page
|
||||
func ListPageRevisions(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/wiki/revisions/{pageName} repository repoGetWikiPageRevisions
|
||||
// ---
|
||||
// summary: Get revisions of a wiki page
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: pageName
|
||||
// in: path
|
||||
// description: name of the page
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: page
|
||||
// in: query
|
||||
// description: page number of results to return (1-based)
|
||||
// type: integer
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/WikiCommitList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
wikiRepo, commit := findWikiRepoCommit(ctx)
|
||||
if wikiRepo != nil {
|
||||
defer wikiRepo.Close()
|
||||
}
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
// get requested pagename
|
||||
pageName := wiki_service.NormalizeWikiName(ctx.Params(":pageName"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
}
|
||||
|
||||
// lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
_, pageFilename := wikiContentsByName(ctx, commit, pageName, false)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
// get commit count - wiki revisions
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
|
||||
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
// get Commit Count
|
||||
commitsHistory, err := wikiRepo.NewCommitsByFileAndRangeNoFollow("master", pageFilename, page)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(commitsCount)
|
||||
ctx.JSON(http.StatusOK, convert.ToWikiCommitList(commitsHistory, commitsCount))
|
||||
}
|
||||
|
||||
// findEntryForFile finds the tree entry for a target filepath.
|
||||
func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
|
||||
entry, err := commit.GetTreeEntryByPath(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entry != nil {
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// Then the unescaped, shortest alternative
|
||||
var unescapedTarget string
|
||||
if unescapedTarget, err = url.QueryUnescape(target); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return commit.GetTreeEntryByPath(unescapedTarget)
|
||||
}
|
||||
|
||||
// findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error.
|
||||
// The caller is responsible for closing the returned repo again
|
||||
func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) {
|
||||
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
|
||||
if err != nil {
|
||||
|
||||
if git.IsErrNotExist(err) || err.Error() == "no such file or directory" {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
commit, err := wikiRepo.GetBranchCommit("master")
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetBranchCommit", err)
|
||||
}
|
||||
return wikiRepo, nil
|
||||
}
|
||||
return wikiRepo, commit
|
||||
}
|
||||
|
||||
// wikiContentsByEntry returns the contents of the wiki page referenced by the
|
||||
// given tree entry, encoded with base64. Writes to ctx if an error occurs.
|
||||
func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) string {
|
||||
blob := entry.Blob()
|
||||
if blob.Size() > setting.API.DefaultMaxBlobSize {
|
||||
return ""
|
||||
}
|
||||
content, err := blob.GetBlobContentBase64()
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "GetBlobContentBase64", err)
|
||||
return ""
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
// wikiContentsByName returns the contents of a wiki page, along with a boolean
|
||||
// indicating whether the page exists. Writes to ctx if an error occurs.
|
||||
func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName string, isSidebarOrFooter bool) (string, string) {
|
||||
pageFilename := wiki_service.NameToFilename(wikiName)
|
||||
entry, err := findEntryForFile(commit, pageFilename)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
if !isSidebarOrFooter {
|
||||
ctx.NotFound()
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError("findEntryForFile", err)
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
return wikiContentsByEntry(ctx, entry), pageFilename
|
||||
}
|
||||
|
||||
func OldListWikiPages(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/wikies repository repoWikiList
|
||||
// ---
|
||||
// summary: List the wikies in a repository
|
||||
|
|
@ -613,7 +88,7 @@ func OldListWikiPages(ctx *context.APIContext) {
|
|||
},
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: wikiName,
|
||||
Commit: api.OldWikiCommit{
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: lastCommit.Author.Name,
|
||||
Email: lastCommit.Author.Email,
|
||||
|
|
@ -627,7 +102,7 @@ func OldListWikiPages(ctx *context.APIContext) {
|
|||
ID: lastCommit.ID.String(),
|
||||
Message: lastCommit.Message(),
|
||||
},
|
||||
FirstCommit: api.OldWikiCommit{
|
||||
FirstCommit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: firstCommit.Author.Name,
|
||||
Email: firstCommit.Author.Email,
|
||||
|
|
@ -651,7 +126,7 @@ func OldListWikiPages(ctx *context.APIContext) {
|
|||
ctx.JSON(http.StatusOK, pages)
|
||||
}
|
||||
|
||||
func OldCreateWiki(ctx *context.APIContext) {
|
||||
func CreateWiki(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/wikies repository repoCreateWiki
|
||||
// ---
|
||||
// summary: Create a wiki in a repository
|
||||
|
|
@ -699,11 +174,6 @@ func OldCreateWiki(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
data, entry, pageFilename, _ := webWiki.WikiContentsByName(ctx.Context, commit, form.Name)
|
||||
metas := ctx.Repo.Repository.ComposeDocumentMetas()
|
||||
|
||||
|
|
@ -736,7 +206,7 @@ func OldCreateWiki(ctx *context.APIContext) {
|
|||
},
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: form.Name,
|
||||
Commit: api.OldWikiCommit{
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
|
|
@ -759,7 +229,7 @@ func OldCreateWiki(ctx *context.APIContext) {
|
|||
|
||||
}
|
||||
|
||||
func OldGetWiki(ctx *context.APIContext) {
|
||||
func GetWiki(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/wikies/{pagename} repository repoGetWiki
|
||||
// ---
|
||||
// summary: Get a Wiki
|
||||
|
|
@ -786,11 +256,6 @@ func OldGetWiki(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/Wiki"
|
||||
|
||||
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
wikiCloneWiki := ctx.Repo.Repository.WikiCloneLink()
|
||||
|
||||
|
|
@ -840,7 +305,7 @@ func OldGetWiki(ctx *context.APIContext) {
|
|||
},
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: pageName,
|
||||
Commit: api.OldWikiCommit{
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
|
|
@ -862,7 +327,7 @@ func OldGetWiki(ctx *context.APIContext) {
|
|||
ctx.JSON(http.StatusOK, wiki)
|
||||
}
|
||||
|
||||
func OldEditWiki(ctx *context.APIContext) {
|
||||
func EditWiki(ctx *context.APIContext) {
|
||||
// swagger:operation PATCH /repos/{owner}/{repo}/wikies/{pagename} repository repoEditWiki
|
||||
// ---
|
||||
// summary: Edit a wiki in a repository
|
||||
|
|
@ -901,11 +366,6 @@ func OldEditWiki(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if _, _, _, noEntry := webWiki.WikiContentsByName(ctx.Context, commit, oldWikiName); noEntry {
|
||||
ctx.Error(http.StatusNotFound, "WikiNotFound", "wiki不存在")
|
||||
|
|
@ -925,12 +385,7 @@ func OldEditWiki(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "EditWikiPage", err)
|
||||
return
|
||||
}
|
||||
wikiRepo, newCommit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
_, newCommit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
|
||||
data, entry, pageFilename, _ := webWiki.WikiContentsByName(ctx.Context, newCommit, newWikiName)
|
||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||
if err != nil {
|
||||
|
|
@ -960,7 +415,7 @@ func OldEditWiki(ctx *context.APIContext) {
|
|||
wiki := api.WikiResponse{
|
||||
WikiMeta: api.WikiMeta{
|
||||
Name: form.Name,
|
||||
Commit: api.OldWikiCommit{
|
||||
Commit: api.WikiCommit{
|
||||
Author: api.WikiUser{
|
||||
Name: c.Author.Name,
|
||||
Email: c.Author.Email,
|
||||
|
|
@ -981,7 +436,7 @@ func OldEditWiki(ctx *context.APIContext) {
|
|||
}
|
||||
ctx.JSON(http.StatusOK, wiki)
|
||||
}
|
||||
func OldDeleteWiki(ctx *context.APIContext) {
|
||||
func DeleteWiki(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/wikies/{pagename} repository repoDeleteWiki
|
||||
// ---
|
||||
// summary: Delete a wiki in a repository
|
||||
|
|
|
|||
|
|
@ -119,9 +119,6 @@ type swaggerParameterBodies struct {
|
|||
// in:body
|
||||
CreateFileOptions api.CreateFileOptions
|
||||
|
||||
// in:body
|
||||
BatchChangeFileOptions api.BatchChangeFileOptions
|
||||
|
||||
// in:body
|
||||
UpdateFileOptions api.UpdateFileOptions
|
||||
|
||||
|
|
@ -175,7 +172,4 @@ type swaggerParameterBodies struct {
|
|||
|
||||
// in:body
|
||||
UserSettingsOptions api.UserSettingsOptions
|
||||
|
||||
// in:body
|
||||
CreateWikiPageOptions api.CreateWikiPageOptions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"code.gitea.io/gitea/models"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/viewfile"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
)
|
||||
|
||||
// Repository
|
||||
|
|
@ -170,13 +169,6 @@ type swaggerResponsePullRequest struct {
|
|||
Body api.PullRequest `json:"body"`
|
||||
}
|
||||
|
||||
// Diff
|
||||
// swagger:response Diff
|
||||
type swaggerResponseDiff struct {
|
||||
// in:body
|
||||
Body gitdiff.Diff `json:"body"`
|
||||
}
|
||||
|
||||
// PullRequestList
|
||||
// swagger:response PullRequestList
|
||||
type swaggerResponsePullRequestList struct {
|
||||
|
|
@ -333,13 +325,6 @@ type swaggerFileResponse struct {
|
|||
Body api.FileResponse `json:"body"`
|
||||
}
|
||||
|
||||
// WikiPageList
|
||||
// swagger:response WikiPageList
|
||||
type swaggerWikiPageList struct {
|
||||
// in:body
|
||||
Body []api.WikiListMetaData `json:"body"`
|
||||
}
|
||||
|
||||
// ContentsResponse
|
||||
// swagger:response ContentsResponse
|
||||
type swaggerContentsResponse struct {
|
||||
|
|
|
|||
|
|
@ -66,10 +66,10 @@ func CheckCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption)
|
|||
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type")
|
||||
return false
|
||||
}
|
||||
// if !models.IsValidHookHttpMethod(form.Config["http_method"]) {
|
||||
// ctx.Error(http.StatusUnprocessableEntity, "", "Invalid http method")
|
||||
// return false
|
||||
// }
|
||||
if !models.IsValidHookHttpMethod(form.Config["http_method"]) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid http method")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -137,9 +137,8 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
|
|||
},
|
||||
BranchFilter: form.BranchFilter,
|
||||
},
|
||||
BranchFilter: form.BranchFilter,
|
||||
IsActive: form.Active,
|
||||
Type: models.HookType(form.Type),
|
||||
IsActive: form.Active,
|
||||
Type: models.HookType(form.Type),
|
||||
}
|
||||
if w.Type == models.SLACK {
|
||||
channel, ok := form.Config["channel"]
|
||||
|
|
|
|||
|
|
@ -230,12 +230,11 @@ func FileHistory(ctx *context.Context) {
|
|||
}
|
||||
|
||||
page := ctx.QueryInt("page")
|
||||
limit := ctx.QueryInt("limit")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(branchName, fileName, page, limit)
|
||||
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(branchName, fileName, page)
|
||||
if err != nil {
|
||||
ctx.ServerError("CommitsByFileAndRange", err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ func UploadFilePost(ctx *context.Context) {
|
|||
|
||||
func cleanUploadFileName(name string) string {
|
||||
// Rebase the filename
|
||||
name = strings.Trim(path.Clean("/"+name), "/")
|
||||
name = strings.Trim(path.Clean("/"+name), " /")
|
||||
// Git disallows any filenames to have a .git directory in them.
|
||||
for _, part := range strings.Split(name, "/") {
|
||||
if strings.ToLower(part) == ".git" {
|
||||
|
|
|
|||
|
|
@ -174,19 +174,19 @@ func SignInPost(ctx *context.Context) {
|
|||
}
|
||||
|
||||
form := web.GetForm(ctx).(*forms.SignInForm)
|
||||
// if user, err := models.GetUserByName(form.UserName); models.IsErrUserNotExist(err) {
|
||||
// ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
|
||||
// log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
// return
|
||||
// } else {
|
||||
// // If this user not is administrator
|
||||
// // Instead, tip error
|
||||
// if !user.IsAdmin {
|
||||
// ctx.RenderWithErr(ctx.Tr("form.User is not an administrator"), tplSignIn, &form)
|
||||
// log.Info("Failed authentiation attempt for %s from %s ", form.UserName, ctx.RemoteAddr())
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
if user, err := models.GetUserByName(form.UserName); models.IsErrUserNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
return
|
||||
} else {
|
||||
// If this user not is administrator
|
||||
// Instead, tip error
|
||||
if !user.IsAdmin {
|
||||
ctx.RenderWithErr(ctx.Tr("form.User is not an administrator"), tplSignIn, &form)
|
||||
log.Info("Failed authentiation attempt for %s from %s ", form.UserName, ctx.RemoteAddr())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
u, err := models.UserSignIn(form.UserName, form.Password)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -233,10 +233,10 @@ func RegisterRoutes(m *web.Route) {
|
|||
m.Get("", func(ctx *context.Context) {
|
||||
ctx.Redirect(setting.AppSubURL + "/explore/repos")
|
||||
})
|
||||
m.Get("/repos", reqSignIn, explore.Repos)
|
||||
m.Get("/users", reqSignIn, explore.Users)
|
||||
m.Get("/organizations", reqSignIn, explore.Organizations)
|
||||
m.Get("/code", reqSignIn, explore.Code)
|
||||
m.Get("/repos", explore.Repos)
|
||||
m.Get("/users", explore.Users)
|
||||
m.Get("/organizations", explore.Organizations)
|
||||
m.Get("/code", explore.Code)
|
||||
}, ignExploreSignIn)
|
||||
m.Get("/issues", reqSignIn, user.Issues)
|
||||
m.Get("/pulls", reqSignIn, user.Pulls)
|
||||
|
|
@ -457,7 +457,7 @@ func RegisterRoutes(m *web.Route) {
|
|||
// ***** END: Admin *****
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/{username}", reqSignIn, user.Profile)
|
||||
m.Get("/{username}", user.Profile)
|
||||
m.Get("/attachments/{uuid}", repo.GetAttachment)
|
||||
}, ignSignIn)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees
|
|||
|
||||
// Loop through all assignees to add them
|
||||
for _, assigneeName := range multipleAssignees {
|
||||
if assigneeName == "" {
|
||||
continue
|
||||
}
|
||||
assignee, err := models.GetUserByName(assigneeName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -6,18 +6,17 @@
|
|||
package wiki
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"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"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -41,7 +40,7 @@ func NameToSubURL(name string) string {
|
|||
|
||||
// NormalizeWikiName normalizes a wiki name
|
||||
func NormalizeWikiName(name string) string {
|
||||
return strings.ReplaceAll(name, "-", "-")
|
||||
return strings.ReplaceAll(name, "-", " ")
|
||||
}
|
||||
|
||||
// NameToFilename converts a wiki name to its corresponding filename.
|
||||
|
|
@ -81,6 +80,7 @@ func InitWiki(repo *models.Repository) error {
|
|||
if repo.HasWiki() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := git.InitRepository(repo.WikiPath(), true); err != nil {
|
||||
return fmt.Errorf("InitRepository: %v", err)
|
||||
} else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil {
|
||||
|
|
@ -206,7 +206,7 @@ func updateWikiPage(doer *models.User, repo *models.Repository, oldWikiName, new
|
|||
}
|
||||
|
||||
// FIXME: The wiki doesn't have lfs support at present - if this changes need to check attributes here
|
||||
// content = strings.Replace(content, "<br/>", "\n", -1)
|
||||
|
||||
objectHash, err := gitRepo.HashObject(strings.NewReader(content))
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
|
|
|
|||
|
|
@ -2424,56 +2424,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/blame": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Get blame from a repository by sha and filepath***",
|
||||
"operationId": "repoGetRefBlame",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "repo commit sha or branch",
|
||||
"name": "sha",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "filepath in repository",
|
||||
"name": "filepath",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "success"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/branch_name_set": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
|
@ -2498,12 +2448,6 @@
|
|||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the branch",
|
||||
"name": "name",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -2792,12 +2736,6 @@
|
|||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the branch",
|
||||
"name": "name",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
|
|
@ -2889,18 +2827,6 @@
|
|||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
|
@ -3469,59 +3395,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/contents/batch": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Change some files in a repository***",
|
||||
"operationId": "repoBatchChangeFile",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/BatchChangeFileOptions"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/responses/BatchFileResponse"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#/responses/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/contents/{filepath}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
|
@ -3823,54 +3696,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/diffs": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Get diffs from a repository",
|
||||
"operationId": "repoGetDiffs",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "from branch or sha",
|
||||
"name": "from",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "to branch or sha",
|
||||
"name": "to",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "success"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/editorconfig/{filepath}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
|
@ -8077,57 +7902,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/pulls/{index}/files": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "List a repo's pull requests files",
|
||||
"operationId": "repoListPullRequestsFiles",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "index of the pull request to get",
|
||||
"name": "index",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
true,
|
||||
false
|
||||
],
|
||||
"type": "string",
|
||||
"description": "not need responses files",
|
||||
"name": "not-need-files",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/Diff"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/pulls/{index}/merge": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
|
@ -10643,290 +10417,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wiki/new": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Create a wiki page",
|
||||
"operationId": "repoCreateWikiPage",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/CreateWikiPageOptions"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"$ref": "#/responses/WikiPage"
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/forbidden"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wiki/page/{pageName}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Get a wiki page",
|
||||
"operationId": "repoGetWikiPage",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the page",
|
||||
"name": "pageName",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/WikiPage"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Delete a wiki page",
|
||||
"operationId": "repoDeleteWikiPage",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the page",
|
||||
"name": "pageName",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"$ref": "#/responses/empty"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/forbidden"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Edit a wiki page",
|
||||
"operationId": "repoEditWikiPage",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the page",
|
||||
"name": "pageName",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/CreateWikiPageOptions"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/WikiPage"
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/responses/error"
|
||||
},
|
||||
"403": {
|
||||
"$ref": "#/responses/forbidden"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wiki/pages": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Get all wiki pages",
|
||||
"operationId": "repoGetWikiPages",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "path of the file",
|
||||
"name": "filepath",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page size of results",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/WikiPageList"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wiki/revisions/{pageName}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Get revisions of a wiki page",
|
||||
"operationId": "repoGetWikiPageRevisions",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the repo",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the repo",
|
||||
"name": "repo",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the page",
|
||||
"name": "pageName",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "page number of results to return (1-based)",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/WikiCommitList"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/{owner}/{repo}/wikies": {
|
||||
"get": {
|
||||
"produces": [
|
||||
|
|
@ -13517,50 +13007,6 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"BatchChangeFileOptions": {
|
||||
"description": "BatchCreateFileOptions options for creating more files",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"create",
|
||||
"update",
|
||||
"delete"
|
||||
],
|
||||
"x-go-name": "ActionType"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"x-go-name": "Content"
|
||||
},
|
||||
"encoding": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"text",
|
||||
"base64"
|
||||
],
|
||||
"x-go-name": "Encoding"
|
||||
},
|
||||
"file_path": {
|
||||
"type": "string",
|
||||
"x-go-name": "FilePath"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-go-name": "Files"
|
||||
},
|
||||
"header": {
|
||||
"$ref": "#/definitions/FileOptions"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"Branch": {
|
||||
"description": "Branch represents a repository branch",
|
||||
"type": "object",
|
||||
|
|
@ -15044,28 +14490,6 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"CreateWikiPageOptions": {
|
||||
"description": "CreateWikiPageOptions form for creating wiki",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content_base64": {
|
||||
"description": "content must be base64 encoded",
|
||||
"type": "string",
|
||||
"x-go-name": "ContentBase64"
|
||||
},
|
||||
"message": {
|
||||
"description": "optional commit message summarizing the change",
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
},
|
||||
"title": {
|
||||
"description": "page title. leave empty to keep unchanged",
|
||||
"type": "string",
|
||||
"x-go-name": "Title"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"Cron": {
|
||||
"description": "Cron represents a Cron task",
|
||||
"type": "object",
|
||||
|
|
@ -15200,187 +14624,6 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"Diff": {
|
||||
"type": "object",
|
||||
"title": "Diff represents a difference between two git trees.",
|
||||
"properties": {
|
||||
"Files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DiffFile"
|
||||
}
|
||||
},
|
||||
"IsIncomplete": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"NumFiles": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TotalDeletion"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffFile": {
|
||||
"type": "object",
|
||||
"title": "DiffFile represents a file diff.",
|
||||
"properties": {
|
||||
"Addition": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "Deletion"
|
||||
},
|
||||
"Index": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"IsAmbiguous": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsBin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsCreated": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsDeleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsIncomplete": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsIncompleteLineTooLong": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsLFSFile": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsProtected": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsRenamed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"IsSubmodule": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Name": {
|
||||
"type": "string"
|
||||
},
|
||||
"OldName": {
|
||||
"type": "string"
|
||||
},
|
||||
"Sections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DiffSection"
|
||||
}
|
||||
},
|
||||
"Type": {
|
||||
"$ref": "#/definitions/DiffFileType"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffFileType": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"title": "DiffFileType represents the type of a DiffFile.",
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffLine": {
|
||||
"type": "object",
|
||||
"title": "DiffLine represents a line difference in a DiffSection.",
|
||||
"properties": {
|
||||
"Comments": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Comment"
|
||||
}
|
||||
},
|
||||
"Content": {
|
||||
"type": "string"
|
||||
},
|
||||
"LeftIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Match": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"RightIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"SectionInfo": {
|
||||
"$ref": "#/definitions/DiffLineSectionInfo"
|
||||
},
|
||||
"Type": {
|
||||
"$ref": "#/definitions/DiffLineType"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffLineSectionInfo": {
|
||||
"description": "DiffLineSectionInfo represents diff line section meta data",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"LastLeftIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"LastRightIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"LeftHunkSize": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"LeftIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Path": {
|
||||
"type": "string"
|
||||
},
|
||||
"RightHunkSize": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"RightIdx": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffLineType": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"title": "DiffLineType represents the type of a DiffLine.",
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DiffSection": {
|
||||
"type": "object",
|
||||
"title": "DiffSection represents a section of a DiffFile.",
|
||||
"properties": {
|
||||
"FileName": {
|
||||
"type": "string"
|
||||
},
|
||||
"Lines": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DiffLine"
|
||||
}
|
||||
},
|
||||
"Name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/services/gitdiff"
|
||||
},
|
||||
"DismissPullReviewOptions": {
|
||||
"description": "DismissPullReviewOptions are options to dismiss a pull review",
|
||||
"type": "object",
|
||||
|
|
@ -16211,42 +15454,6 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"FileOptions": {
|
||||
"description": "FileOptions options for all file APIs",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/Identity"
|
||||
},
|
||||
"branch": {
|
||||
"description": "branch (optional) to base this file from. if not given, the default branch is used",
|
||||
"type": "string",
|
||||
"x-go-name": "BranchName"
|
||||
},
|
||||
"committer": {
|
||||
"$ref": "#/definitions/Identity"
|
||||
},
|
||||
"dates": {
|
||||
"$ref": "#/definitions/CommitDateOptions"
|
||||
},
|
||||
"message": {
|
||||
"description": "message (optional) for the commit of this file. if not supplied, a default message will be used",
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
},
|
||||
"new_branch": {
|
||||
"description": "new_branch (optional) will make a new branch from `branch` before creating the file",
|
||||
"type": "string",
|
||||
"x-go-name": "NewBranchName"
|
||||
},
|
||||
"signoff": {
|
||||
"description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.",
|
||||
"type": "boolean",
|
||||
"x-go-name": "Signoff"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"FileResponse": {
|
||||
"description": "FileResponse contains information about a repo's file",
|
||||
"type": "object",
|
||||
|
|
@ -17423,23 +16630,6 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"OldWikiCommit": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/WikiUser"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"x-go-name": "ID"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"Organization": {
|
||||
"description": "Organization represents an organization",
|
||||
"type": "object",
|
||||
|
|
@ -19036,47 +18226,18 @@
|
|||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"WikiCommit": {
|
||||
"description": "WikiCommit page commit/revision",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/CommitUser"
|
||||
"$ref": "#/definitions/WikiUser"
|
||||
},
|
||||
"commiter": {
|
||||
"$ref": "#/definitions/CommitUser"
|
||||
"id": {
|
||||
"type": "string",
|
||||
"x-go-name": "ID"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"x-go-name": "Message"
|
||||
},
|
||||
"sha": {
|
||||
"type": "string",
|
||||
"x-go-name": "ID"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"WikiListMetaData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"html_url": {
|
||||
"type": "string",
|
||||
"x-go-name": "HTMLURL"
|
||||
},
|
||||
"last_commit": {
|
||||
"$ref": "#/definitions/WikiCommit"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"x-go-name": "Name"
|
||||
},
|
||||
"sub_url": {
|
||||
"type": "string",
|
||||
"x-go-name": "SubURL"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"x-go-name": "Type"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
|
|
@ -19103,7 +18264,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"commit": {
|
||||
"$ref": "#/definitions/OldWikiCommit"
|
||||
"$ref": "#/definitions/WikiCommit"
|
||||
},
|
||||
"commit_counts": {
|
||||
"type": "integer",
|
||||
|
|
@ -19151,7 +18312,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"commit": {
|
||||
"$ref": "#/definitions/OldWikiCommit"
|
||||
"$ref": "#/definitions/WikiCommit"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
|
|
@ -19371,12 +18532,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"Diff": {
|
||||
"description": "Diff",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Diff"
|
||||
}
|
||||
},
|
||||
"EmailList": {
|
||||
"description": "EmailList",
|
||||
"schema": {
|
||||
|
|
@ -19947,15 +19102,6 @@
|
|||
"$ref": "#/definitions/WikiesResponse"
|
||||
}
|
||||
},
|
||||
"WikiPageList": {
|
||||
"description": "WikiPageList",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/WikiListMetaData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"conflict": {
|
||||
"description": "APIConflict is a conflict empty response"
|
||||
},
|
||||
|
|
@ -20004,7 +19150,7 @@
|
|||
"parameterBodies": {
|
||||
"description": "parameterBodies",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/CreateWikiPageOptions"
|
||||
"$ref": "#/definitions/UserSettingsOptions"
|
||||
}
|
||||
},
|
||||
"redirect": {
|
||||
|
|
@ -20090,4 +19236,4 @@
|
|||
"TOTPHeader": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue