Skip to content

Commit eea6584

Browse files
authored
Merge branch 'master' into fix-12440-prevent-panic-on-git-blame
2 parents c3602de + 77e5081 commit eea6584

File tree

24 files changed

+348
-92
lines changed

24 files changed

+348
-92
lines changed

docs/content/doc/features/comparison.en-us.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ _Symbols used in table:_
4747
| Built-in Container Registry | [](https://github.com/go-gitea/gitea/issues/2316) |||||||
4848
| External git mirroring ||||||||
4949
| FIDO U2F (2FA) ||||||||
50-
| Built-in CI/CD ||| |||||
50+
| Built-in CI/CD ||| |||||
5151
| Subgroups: groups within groups ||||||||
5252

5353
#### Code management
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
date: "2020-03-19T19:27:00+02:00"
3+
title: "Install on Kubernetes"
4+
slug: "install-on-kubernetes"
5+
weight: 10
6+
toc: true
7+
draft: false
8+
menu:
9+
sidebar:
10+
parent: "installation"
11+
name: "Kubernetes"
12+
weight: 50
13+
identifier: "install-on-kubernetes"
14+
---
15+
16+
# Installation with Helm (on Kubernetes)
17+
18+
Gitea provides a Helm Chart to allow for installation on kubernetes.
19+
20+
A non-customized install can be done with:
21+
22+
```
23+
helm repo add gitea-charts https://dl.gitea.io/charts/
24+
helm install gitea gitea-charts/gitea
25+
```
26+
27+
If you would like to customize your install, which includes kubernetes ingress, please refer to the complete [Gitea helm chart configuration details](https://gitea.com/gitea/helm-chart/)

integrations/api_helper_for_declarative_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64)
235235
DecodeJSON(t, resp, &err)
236236
assert.EqualValues(t, "Please try again later", err.Message)
237237
queue.GetManager().FlushAll(context.Background(), 5*time.Second)
238+
req = NewRequestWithJSON(t, http.MethodPost, urlStr, &auth.MergePullRequestForm{
239+
MergeMessageField: "doAPIMergePullRequest Merge",
240+
Do: string(models.MergeStyleMerge),
241+
})
238242
resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus)
239243
}
240244

integrations/repo_branch_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,12 @@ func testCreateBranches(t *testing.T, giteaURL *url.URL) {
104104
{
105105
OldRefSubURL: "tag/v1.0.0",
106106
NewBranch: "feature/test4",
107-
CreateRelease: "v1.0.0",
107+
CreateRelease: "v1.0.1",
108108
ExpectedStatus: http.StatusFound,
109109
FlashMessage: i18n.Tr("en", "repo.branch.create_success", "feature/test4"),
110110
},
111111
}
112112
for _, test := range tests {
113-
defer prepareTestEnv(t)()
114113
session := loginUser(t, "user2")
115114
if test.CreateRelease != "" {
116115
createNewRelease(t, session, "/user2/repo1", test.CreateRelease, test.CreateRelease, false, false)

integrations/repo_commits_search_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import (
1414
)
1515

1616
func testRepoCommitsSearch(t *testing.T, query, commit string) {
17-
defer prepareTestEnv(t)()
18-
1917
session := loginUser(t, "user2")
2018

2119
// Request repository commits page
@@ -28,6 +26,7 @@ func testRepoCommitsSearch(t *testing.T, query, commit string) {
2826
}
2927

3028
func TestRepoCommitsSearch(t *testing.T) {
29+
defer prepareTestEnv(t)()
3130
testRepoCommitsSearch(t, "e8eabd", "")
3231
testRepoCommitsSearch(t, "38a9cb", "")
3332
testRepoCommitsSearch(t, "6e8e", "6e8eabd9a7")

models/issue_comment.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
712712
RefAction: opts.RefAction,
713713
RefIsPull: opts.RefIsPull,
714714
IsForcePush: opts.IsForcePush,
715+
Invalidated: opts.Invalidated,
715716
}
716717
if _, err = e.Insert(comment); err != nil {
717718
return nil, err
@@ -878,6 +879,7 @@ type CreateCommentOptions struct {
878879
RefAction references.XRefAction
879880
RefIsPull bool
880881
IsForcePush bool
882+
Invalidated bool
881883
}
882884

883885
// CreateComment creates comment of issue or commit.
@@ -953,6 +955,8 @@ type FindCommentsOptions struct {
953955
ReviewID int64
954956
Since int64
955957
Before int64
958+
Line int64
959+
TreePath string
956960
Type CommentType
957961
}
958962

@@ -976,6 +980,12 @@ func (opts *FindCommentsOptions) toConds() builder.Cond {
976980
if opts.Type != CommentTypeUnknown {
977981
cond = cond.And(builder.Eq{"comment.type": opts.Type})
978982
}
983+
if opts.Line > 0 {
984+
cond = cond.And(builder.Eq{"comment.line": opts.Line})
985+
}
986+
if len(opts.TreePath) > 0 {
987+
cond = cond.And(builder.Eq{"comment.tree_path": opts.TreePath})
988+
}
979989
return cond
980990
}
981991

@@ -990,6 +1000,8 @@ func findComments(e Engine, opts FindCommentsOptions) ([]*Comment, error) {
9901000
sess = opts.setSessionPagination(sess)
9911001
}
9921002

1003+
// WARNING: If you change this order you will need to fix createCodeComment
1004+
9931005
return comments, sess.
9941006
Asc("comment.created_unix").
9951007
Asc("comment.id").

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ var migrations = []Migration{
250250
NewMigration("fix publisher ID for tag releases", fixPublisherIDforTagReleases),
251251
// v157 -> v158
252252
NewMigration("ensure repo topics are up-to-date", fixRepoTopics),
253+
// v158 -> v159
254+
NewMigration("code comment replies should have the commitID of the review they are replying to", updateCodeCommentReplies),
253255
}
254256

255257
// GetCurrentDBVersion returns the current db version

models/migrations/v158.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"fmt"
9+
"strconv"
10+
11+
"code.gitea.io/gitea/modules/log"
12+
"code.gitea.io/gitea/modules/setting"
13+
14+
"xorm.io/xorm"
15+
)
16+
17+
func updateCodeCommentReplies(x *xorm.Engine) error {
18+
type Comment struct {
19+
ID int64 `xorm:"pk autoincr"`
20+
CommitSHA string `xorm:"VARCHAR(40)"`
21+
Patch string `xorm:"TEXT patch"`
22+
Invalidated bool
23+
24+
// Not extracted but used in the below query
25+
Type int `xorm:"INDEX"`
26+
Line int64 // - previous line / + proposed line
27+
TreePath string
28+
ReviewID int64 `xorm:"index"`
29+
}
30+
31+
if err := x.Sync2(new(Comment)); err != nil {
32+
return err
33+
}
34+
35+
sqlSelect := `SELECT comment.id as id, first.commit_sha as commit_sha, first.patch as patch, first.invalidated as invalidated`
36+
sqlTail := ` FROM comment INNER JOIN (
37+
SELECT C.id, C.review_id, C.line, C.tree_path, C.patch, C.commit_sha, C.invalidated
38+
FROM comment AS C
39+
WHERE C.type = 21
40+
AND C.created_unix =
41+
(SELECT MIN(comment.created_unix)
42+
FROM comment
43+
WHERE comment.review_id = C.review_id
44+
AND comment.type = 21
45+
AND comment.line = C.line
46+
AND comment.tree_path = C.tree_path)
47+
) AS first
48+
ON comment.review_id = first.review_id
49+
AND comment.tree_path = first.tree_path AND comment.line = first.line
50+
WHERE comment.type = 21
51+
AND comment.id != first.id
52+
AND comment.commit_sha != first.commit_sha`
53+
54+
var sqlCmd string
55+
var start = 0
56+
var batchSize = 100
57+
sess := x.NewSession()
58+
defer sess.Close()
59+
for {
60+
if err := sess.Begin(); err != nil {
61+
return err
62+
}
63+
64+
if setting.Database.UseMSSQL {
65+
if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil {
66+
log.Error("unable to create temporary table")
67+
return err
68+
}
69+
}
70+
71+
var comments = make([]*Comment, 0, batchSize)
72+
73+
switch {
74+
case setting.Database.UseMySQL:
75+
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start)
76+
case setting.Database.UsePostgreSQL:
77+
fallthrough
78+
case setting.Database.UseSQLite3:
79+
sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + " OFFSET " + strconv.Itoa(start)
80+
case setting.Database.UseMSSQL:
81+
sqlCmd = "SELECT TOP " + strconv.Itoa(batchSize) + " * FROM #temp_comments WHERE " +
82+
"(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id"
83+
default:
84+
return fmt.Errorf("Unsupported database type")
85+
}
86+
87+
if err := sess.SQL(sqlCmd).Find(&comments); err != nil {
88+
log.Error("failed to select: %v", err)
89+
return err
90+
}
91+
92+
for _, comment := range comments {
93+
if _, err := sess.Table("comment").ID(comment.ID).Cols("commit_sha", "patch", "invalidated").Update(comment); err != nil {
94+
log.Error("failed to update comment[%d]: %v %v", comment.ID, comment, err)
95+
return err
96+
}
97+
}
98+
99+
start += len(comments)
100+
101+
if err := sess.Commit(); err != nil {
102+
return err
103+
}
104+
if len(comments) < batchSize {
105+
break
106+
}
107+
}
108+
109+
return nil
110+
}

modules/references/references.go

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -235,40 +235,78 @@ func findAllIssueReferencesMarkdown(content string) []*rawReference {
235235
return findAllIssueReferencesBytes(bcontent, links)
236236
}
237237

238+
func convertFullHTMLReferencesToShortRefs(re *regexp.Regexp, contentBytes *[]byte) {
239+
// We will iterate through the content, rewrite and simplify full references.
240+
//
241+
// We want to transform something like:
242+
//
243+
// this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo
244+
// https://ourgitea.com/git/owner/repo/pulls/123456789
245+
//
246+
// Into something like:
247+
//
248+
// this is a #123456789, foo
249+
// !123456789
250+
251+
pos := 0
252+
for {
253+
// re looks for something like: (\s|^|\(|\[)https://ourgitea.com/git/(owner/repo)/(issues)/(123456789)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)
254+
match := re.FindSubmatchIndex((*contentBytes)[pos:])
255+
if match == nil {
256+
break
257+
}
258+
// match is a bunch of indices into the content from pos onwards so
259+
// to simplify things let's just add pos to all of the indices in match
260+
for i := range match {
261+
match[i] += pos
262+
}
263+
264+
// match[0]-match[1] is whole string
265+
// match[2]-match[3] is preamble
266+
267+
// move the position to the end of the preamble
268+
pos = match[3]
269+
270+
// match[4]-match[5] is owner/repo
271+
// now copy the owner/repo to end of the preamble
272+
endPos := pos + match[5] - match[4]
273+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[4]:match[5]])
274+
275+
// move the current position to the end of the newly copied owner/repo
276+
pos = endPos
277+
278+
// Now set the issue/pull marker:
279+
//
280+
// match[6]-match[7] == 'issues'
281+
(*contentBytes)[pos] = '#'
282+
if string((*contentBytes)[match[6]:match[7]]) == "pulls" {
283+
(*contentBytes)[pos] = '!'
284+
}
285+
pos++
286+
287+
// Then add the issue/pull number
288+
//
289+
// match[8]-match[9] is the number
290+
endPos = pos + match[9] - match[8]
291+
copy((*contentBytes)[pos:endPos], (*contentBytes)[match[8]:match[9]])
292+
293+
// Now copy what's left at the end of the string to the new end position
294+
copy((*contentBytes)[endPos:], (*contentBytes)[match[9]:])
295+
// now we reset the length
296+
297+
// our new section has length endPos - match[3]
298+
// our old section has length match[9] - match[3]
299+
(*contentBytes) = (*contentBytes)[:len((*contentBytes))-match[9]+endPos]
300+
pos = endPos
301+
}
302+
}
303+
238304
// FindAllIssueReferences returns a list of unvalidated references found in a string.
239305
func FindAllIssueReferences(content string) []IssueReference {
240306
// Need to convert fully qualified html references to local system to #/! short codes
241307
contentBytes := []byte(content)
242308
if re := getGiteaIssuePullPattern(); re != nil {
243-
pos := 0
244-
for {
245-
match := re.FindSubmatchIndex(contentBytes[pos:])
246-
if match == nil {
247-
break
248-
}
249-
// match[0]-match[1] is whole string
250-
// match[2]-match[3] is preamble
251-
pos += match[3]
252-
// match[4]-match[5] is owner/repo
253-
endPos := pos + match[5] - match[4]
254-
copy(contentBytes[pos:endPos], contentBytes[match[4]:match[5]])
255-
pos = endPos
256-
// match[6]-match[7] == 'issues'
257-
contentBytes[pos] = '#'
258-
if string(contentBytes[match[6]:match[7]]) == "pulls" {
259-
contentBytes[pos] = '!'
260-
}
261-
pos++
262-
// match[8]-match[9] is the number
263-
endPos = pos + match[9] - match[8]
264-
copy(contentBytes[pos:endPos], contentBytes[match[8]:match[9]])
265-
copy(contentBytes[endPos:], contentBytes[match[9]:])
266-
// now we reset the length
267-
// our new section has length endPos - match[3]
268-
// our old section has length match[9] - match[3]
269-
contentBytes = contentBytes[:len(contentBytes)-match[9]+endPos]
270-
pos = endPos
271-
}
309+
convertFullHTMLReferencesToShortRefs(re, &contentBytes)
272310
} else {
273311
log.Debug("No GiteaIssuePullPattern pattern")
274312
}

0 commit comments

Comments
 (0)