Skip to content

Commit dbcdd52

Browse files
Merge branch 'main' into feat/actions-token-permissions
2 parents 349a1a7 + a440116 commit dbcdd52

File tree

33 files changed

+463
-100
lines changed

33 files changed

+463
-100
lines changed

models/repo/repo.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -869,16 +869,6 @@ func GetRepositoriesMapByIDs(ctx context.Context, ids []int64) (map[int64]*Repos
869869
return repos, db.GetEngine(ctx).In("id", ids).Find(&repos)
870870
}
871871

872-
// IsRepositoryModelOrDirExist returns true if the repository with given name under user has already existed.
873-
func IsRepositoryModelOrDirExist(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
874-
has, err := IsRepositoryModelExist(ctx, u, repoName)
875-
if err != nil {
876-
return false, err
877-
}
878-
isDir, err := util.IsDir(RepoPath(u.Name, repoName))
879-
return has || isDir, err
880-
}
881-
882872
func IsRepositoryModelExist(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
883873
return db.GetEngine(ctx).Get(&Repository{
884874
OwnerID: u.ID,

models/repo/update.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import (
99
"time"
1010

1111
"code.gitea.io/gitea/models/db"
12-
user_model "code.gitea.io/gitea/models/user"
13-
"code.gitea.io/gitea/modules/log"
1412
"code.gitea.io/gitea/modules/util"
1513
)
1614

@@ -106,35 +104,6 @@ func (err ErrRepoFilesAlreadyExist) Unwrap() error {
106104
return util.ErrAlreadyExist
107105
}
108106

109-
// CheckCreateRepository check if doer could create a repository in new owner
110-
func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, name string, overwriteOrAdopt bool) error {
111-
if !doer.CanCreateRepoIn(owner) {
112-
return ErrReachLimitOfRepo{owner.MaxRepoCreation}
113-
}
114-
115-
if err := IsUsableRepoName(name); err != nil {
116-
return err
117-
}
118-
119-
has, err := IsRepositoryModelOrDirExist(ctx, owner, name)
120-
if err != nil {
121-
return fmt.Errorf("IsRepositoryExist: %w", err)
122-
} else if has {
123-
return ErrRepoAlreadyExist{owner.Name, name}
124-
}
125-
126-
repoPath := RepoPath(owner.Name, name)
127-
isExist, err := util.IsExist(repoPath)
128-
if err != nil {
129-
log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
130-
return err
131-
}
132-
if !overwriteOrAdopt && isExist {
133-
return ErrRepoFilesAlreadyExist{owner.Name, name}
134-
}
135-
return nil
136-
}
137-
138107
// UpdateRepoSize updates the repository size, calculating it using getDirectorySize
139108
func UpdateRepoSize(ctx context.Context, repoID, gitSize, lfsSize int64) error {
140109
_, err := db.GetEngine(ctx).ID(repoID).Cols("size", "git_size", "lfs_size").NoAutoTime().Update(&Repository{

modules/git/repo.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,18 +186,21 @@ func Clone(ctx context.Context, from, to string, opts CloneRepoOptions) error {
186186

187187
// PushOptions options when push to remote
188188
type PushOptions struct {
189-
Remote string
190-
Branch string
191-
Force bool
192-
Mirror bool
193-
Env []string
194-
Timeout time.Duration
189+
Remote string
190+
Branch string
191+
Force bool
192+
ForceWithLease string
193+
Mirror bool
194+
Env []string
195+
Timeout time.Duration
195196
}
196197

197198
// Push pushs local commits to given remote branch.
198199
func Push(ctx context.Context, repoPath string, opts PushOptions) error {
199200
cmd := gitcmd.NewCommand("push")
200-
if opts.Force {
201+
if opts.ForceWithLease != "" {
202+
cmd.AddOptionFormat("--force-with-lease=%s", opts.ForceWithLease)
203+
} else if opts.Force {
201204
cmd.AddArguments("-f")
202205
}
203206
if opts.Mirror {

modules/gitrepo/push.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ import (
99
"code.gitea.io/gitea/modules/git"
1010
)
1111

12-
func Push(ctx context.Context, repo Repository, opts git.PushOptions) error {
12+
// PushToExternal pushes a managed repository to an external remote.
13+
func PushToExternal(ctx context.Context, repo Repository, opts git.PushOptions) error {
1314
return git.Push(ctx, repoPath(repo), opts)
1415
}
16+
17+
// Push pushes from one managed repository to another managed repository.
18+
func Push(ctx context.Context, fromRepo, toRepo Repository, opts git.PushOptions) error {
19+
opts.Remote = repoPath(toRepo)
20+
return git.Push(ctx, repoPath(fromRepo), opts)
21+
}
22+
23+
// PushFromLocal pushes from a local path to a managed repository.
24+
func PushFromLocal(ctx context.Context, fromLocalPath string, toRepo Repository, opts git.PushOptions) error {
25+
opts.Remote = repoPath(toRepo)
26+
return git.Push(ctx, fromLocalPath, opts)
27+
}

modules/markup/markdown/markdown_math_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ func TestMathRender(t *testing.T) {
3030
"$ a $",
3131
`<p><code class="language-math">a</code></p>` + nl,
3232
},
33+
{
34+
"$a$$b$",
35+
`<p><code class="language-math">a</code><code class="language-math">b</code></p>` + nl,
36+
},
3337
{
3438
"$a$ $b$",
3539
`<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
@@ -59,7 +63,7 @@ func TestMathRender(t *testing.T) {
5963
`<p>a$b $a a$b b$</p>` + nl,
6064
},
6165
{
62-
"a$x$",
66+
"a$x$", // Pattern: "word$other$" The real world example is: "Price is between US$1 and US$2.", so don't parse this.
6367
`<p>a$x$</p>` + nl,
6468
},
6569
{
@@ -70,6 +74,10 @@ func TestMathRender(t *testing.T) {
7074
"$a$ ($b$) [$c$] {$d$}",
7175
`<p><code class="language-math">a</code> (<code class="language-math">b</code>) [$c$] {$d$}</p>` + nl,
7276
},
77+
{
78+
"[$a$](link)",
79+
`<p><a href="/link" rel="nofollow"><code class="language-math">a</code></a></p>` + nl,
80+
},
7381
{
7482
"$$a$$",
7583
`<p><code class="language-math">a</code></p>` + nl,

modules/markup/markdown/math/inline_parser.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ func isAlphanumeric(b byte) bool {
5454
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
5555
}
5656

57+
func isInMarkdownLinkText(block text.Reader, lineAfter []byte) bool {
58+
return block.PrecendingCharacter() == '[' && bytes.HasPrefix(lineAfter, []byte("]("))
59+
}
60+
5761
// Parse parses the current line and returns a result of parsing.
5862
func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
5963
line, _ := block.PeekLine()
@@ -115,7 +119,9 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
115119
}
116120
// check valid ending character
117121
isValidEndingChar := isPunctuation(succeedingCharacter) || isParenthesesClose(succeedingCharacter) ||
118-
succeedingCharacter == ' ' || succeedingCharacter == '\n' || succeedingCharacter == 0
122+
succeedingCharacter == ' ' || succeedingCharacter == '\n' || succeedingCharacter == 0 ||
123+
succeedingCharacter == '$' ||
124+
isInMarkdownLinkText(block, line[i+len(stopMark):])
119125
if checkSurrounding && !isValidEndingChar {
120126
break
121127
}

modules/setting/config_provider.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,14 @@ func LogStartupProblem(skip int, level log.Level, format string, args ...any) {
337337

338338
func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) {
339339
if rootCfg.Section(oldSection).HasKey(oldKey) {
340-
LogStartupProblem(1, log.ERROR, "Deprecation: config option `[%s].%s` presents, please use `[%s].%s` instead because this fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version)
340+
LogStartupProblem(1, log.ERROR, "Deprecation: config option `[%s].%s` present, please use `[%s].%s` instead because this fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version)
341341
}
342342
}
343343

344344
// deprecatedSettingDB add a hint that the configuration has been moved to database but still kept in app.ini
345345
func deprecatedSettingDB(rootCfg ConfigProvider, oldSection, oldKey string) {
346346
if rootCfg.Section(oldSection).HasKey(oldKey) {
347-
LogStartupProblem(1, log.ERROR, "Deprecation: config option `[%s].%s` presents but it won't take effect because it has been moved to admin panel -> config setting", oldSection, oldKey)
347+
LogStartupProblem(1, log.ERROR, "Deprecation: config option `[%s].%s` present but it won't take effect because it has been moved to admin panel -> config setting", oldSection, oldKey)
348348
}
349349
}
350350

modules/structs/repo.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,21 @@ type RenameBranchRepoOption struct {
292292
Name string `json:"name" binding:"Required;GitRefName;MaxSize(100)"`
293293
}
294294

295+
// UpdateBranchRepoOption options when updating a branch reference in a repository
296+
// swagger:model
297+
type UpdateBranchRepoOption struct {
298+
// New commit SHA (or any ref) the branch should point to
299+
//
300+
// required: true
301+
NewCommitID string `json:"new_commit_id" binding:"Required"`
302+
303+
// Expected old commit SHA of the branch; if provided it must match the current tip
304+
OldCommitID string `json:"old_commit_id"`
305+
306+
// Force update even if the change is not a fast-forward
307+
Force bool `json:"force"`
308+
}
309+
295310
// TransferRepoOption options when transfer a repository's ownership
296311
// swagger:model
297312
type TransferRepoOption struct {

routers/api/v1/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,7 @@ func Routes() *web.Router {
12421242
m.Get("/*", repo.GetBranch)
12431243
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteBranch)
12441244
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
1245+
m.Put("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.UpdateBranchRepoOption{}), repo.UpdateBranch)
12451246
m.Patch("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.RenameBranchRepoOption{}), repo.RenameBranch)
12461247
}, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode))
12471248
m.Group("/branch_protections", func() {

routers/api/v1/repo/branch.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,81 @@ func ListBranches(ctx *context.APIContext) {
380380
ctx.JSON(http.StatusOK, apiBranches)
381381
}
382382

383+
// UpdateBranch moves a branch reference to a new commit.
384+
func UpdateBranch(ctx *context.APIContext) {
385+
// swagger:operation PUT /repos/{owner}/{repo}/branches/{branch} repository repoUpdateBranch
386+
// ---
387+
// summary: Update a branch reference to a new commit
388+
// consumes:
389+
// - application/json
390+
// produces:
391+
// - application/json
392+
// parameters:
393+
// - name: owner
394+
// in: path
395+
// description: owner of the repo
396+
// type: string
397+
// required: true
398+
// - name: repo
399+
// in: path
400+
// description: name of the repo
401+
// type: string
402+
// required: true
403+
// - name: branch
404+
// in: path
405+
// description: name of the branch
406+
// type: string
407+
// required: true
408+
// - name: body
409+
// in: body
410+
// schema:
411+
// "$ref": "#/definitions/UpdateBranchRepoOption"
412+
// responses:
413+
// "204":
414+
// "$ref": "#/responses/empty"
415+
// "403":
416+
// "$ref": "#/responses/forbidden"
417+
// "404":
418+
// "$ref": "#/responses/notFound"
419+
// "409":
420+
// "$ref": "#/responses/conflict"
421+
// "422":
422+
// "$ref": "#/responses/validationError"
423+
424+
opt := web.GetForm(ctx).(*api.UpdateBranchRepoOption)
425+
426+
branchName := ctx.PathParam("*")
427+
repo := ctx.Repo.Repository
428+
429+
if repo.IsEmpty {
430+
ctx.APIError(http.StatusNotFound, "Git Repository is empty.")
431+
return
432+
}
433+
434+
if repo.IsMirror {
435+
ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.")
436+
return
437+
}
438+
439+
// permission check has been done in api.go
440+
if err := repo_service.UpdateBranch(ctx, repo, ctx.Repo.GitRepo, ctx.Doer, branchName, opt.NewCommitID, opt.OldCommitID, opt.Force); err != nil {
441+
switch {
442+
case git_model.IsErrBranchNotExist(err):
443+
ctx.APIErrorNotFound(err)
444+
case errors.Is(err, util.ErrInvalidArgument):
445+
ctx.APIError(http.StatusUnprocessableEntity, err)
446+
case git.IsErrPushRejected(err):
447+
rej := err.(*git.ErrPushRejected)
448+
ctx.APIError(http.StatusForbidden, rej.Message)
449+
default:
450+
ctx.APIErrorInternal(err)
451+
}
452+
return
453+
}
454+
455+
ctx.Status(http.StatusNoContent)
456+
}
457+
383458
// RenameBranch renames a repository's branch.
384459
func RenameBranch(ctx *context.APIContext) {
385460
// swagger:operation PATCH /repos/{owner}/{repo}/branches/{branch} repository repoRenameBranch

0 commit comments

Comments
 (0)