Skip to content

Commit 4320cba

Browse files
committed
Merge branch 'master' of git://github.com/go-gitea/gitea
2 parents 10043ac + 51fade4 commit 4320cba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+763
-430
lines changed

contrib/systemd/gitea.service

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Type=simple
2020
User=git
2121
Group=git
2222
WorkingDirectory=/var/lib/gitea/
23+
# If using unix socket: Tells Systemd to create /run/gitea folder to home gitea.sock
24+
# Manual cration would vanish after reboot.
25+
#RuntimeDirectory=gitea
2326
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
2427
Restart=always
2528
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea

docs/content/doc/advanced/ci-cd.en-us.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ the purpose is to give a starting point to integrate a CI/CD process with your G
2727
- [Agola](https://agola.io)
2828
- [Buildkite](https://buildkite.com) with [Gitea connector](https://github.com/techknowlogick/gitea-buildkite-connector)
2929
- [AppVeyor](https://www.appveyor.com) with [built-in Gitea support](https://www.appveyor.com/blog/2019/09/05/gitea-receives-first-class-support-in-appveyor/)
30+
- [Buildbot](https://www.buildbot.net/) with [Gitea plugin](https://github.com/lab132/buildbot-gitea)
31+
3032

3133
Others CI/CD solutions that partially can be integrated with Gitea:
3234
- [Concourse](https://www.concourse-ci.org), see more information at [Concourse community forum](https://discuss.concourse-ci.org/t/concourse-ci-and-gitea-oauth/1475)

docs/content/doc/installation/from-binary.en-us.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ location. When launched manually, Gitea can be killed using `Ctrl+C`.
4444

4545
## Recommended server configuration
4646

47-
**NOTE:** Many of the following directories can be configured using [Environment Variables]({{< relref "doc/advanced/specific-variables.en-us.md" >}}) as well!
47+
**NOTE:** Many of the following directories can be configured using [Environment Variables]({{< relref "doc/advanced/specific-variables.en-us.md" >}}) as well!
4848
Of note, configuring `GITEA_WORK_DIR` will tell Gitea where to base its working directory, as well as ease installation.
4949

5050
### Prepare environment
@@ -80,7 +80,7 @@ chmod 770 /etc/gitea
8080
**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done, it is recommended to set rights to read-only using:
8181
```
8282
chmod 750 /etc/gitea
83-
chmod 644 /etc/gitea/app.ini
83+
chmod 640 /etc/gitea/app.ini
8484
```
8585
If you don't want the web installer to be able to write the config file at all, it is also possible to make the config file read-only for the gitea user (owner/group `root:root`, mode `0660`), and set `INSTALL_LOCK = true`. In that case all database configuration details must be set beforehand in the config file, as well as the `SECRET_KEY` and `INTERNAL_TOKEN` values. See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret INTERNAL_TOKEN`.
8686

@@ -113,16 +113,16 @@ GITEA_WORK_DIR=/var/lib/gitea/ /usr/local/bin/gitea web -c /etc/gitea/app.ini
113113

114114
## Updating to a new version
115115

116-
You can update to a new version of Gitea by stopping Gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance.
117-
The binary file name should not be changed during the update to avoid problems
118-
in existing repositories.
116+
You can update to a new version of Gitea by stopping Gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance.
117+
The binary file name should not be changed during the update to avoid problems
118+
in existing repositories.
119119

120120
It is recommended you do a [backup]({{< relref "doc/usage/backup-and-restore.en-us.md" >}}) before updating your installation.
121121

122-
If you have carried out the installation steps as described above, the binary should
123-
have the generic name `gitea`. Do not change this, i.e. to include the version number.
122+
If you have carried out the installation steps as described above, the binary should
123+
have the generic name `gitea`. Do not change this, i.e. to include the version number.
124124

125-
See below for troubleshooting instructions to repair broken repositories after
125+
See below for troubleshooting instructions to repair broken repositories after
126126
an update of your Gitea version.
127127

128128
## Troubleshooting
@@ -145,7 +145,7 @@ is already running.
145145

146146
### Running Gitea on Raspbian
147147

148-
As of v1.8, there is a problem with the arm7 version of Gitea and it doesn't run on Raspberry Pi and similar devices.
148+
As of v1.8, there is a problem with the arm7 version of Gitea and it doesn't run on Raspberry Pi and similar devices.
149149

150150
It is therefore recommended to switch to the arm6 version which has been tested and shown to work on Raspberry Pi and similar devices.
151151

@@ -154,18 +154,18 @@ please remove after fixing the arm7 bug
154154
--->
155155
### Git error after updating to a new version of Gitea
156156

157-
If the binary file name has been changed during the update to a new version of Gitea,
158-
git hooks in existing repositories will not work any more. In that case, a git
157+
If the binary file name has been changed during the update to a new version of Gitea,
158+
git hooks in existing repositories will not work any more. In that case, a git
159159
error will be displayed when pushing to the repository.
160160

161161
```
162162
remote: ./hooks/pre-receive.d/gitea: line 2: [...]: No such file or directory
163163
```
164164

165-
The `[...]` part of the error message will contain the path to your previous Gitea
165+
The `[...]` part of the error message will contain the path to your previous Gitea
166166
binary.
167167

168-
To solve this, go to the admin options and run the task `Resynchronize pre-receive,
168+
To solve this, go to the admin options and run the task `Resynchronize pre-receive,
169169
update and post-receive hooks of all repositories` to update all hooks to contain
170170
the new binary path. Please note that this overwrite all git hooks including ones
171171
with customizations made.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
date: "2019-10-06T08:00:00+05:00"
3+
title: "Usage: Git LFS setup"
4+
slug: "git-lfs-setup"
5+
weight: 12
6+
toc: true
7+
draft: false
8+
menu:
9+
sidebar:
10+
parent: "usage"
11+
name: "Git LFS setup"
12+
weight: 12
13+
identifier: "git-lfs-setup"
14+
---
15+
16+
# Git Large File Storage setup
17+
18+
To use Gitea's built-in LFS support, you must update the `app.ini` file:
19+
20+
```ini
21+
[server]
22+
; Enables git-lfs support. true or false, default is false.
23+
LFS_START_SERVER = true
24+
; Where your lfs files reside, default is data/lfs.
25+
LFS_CONTENT_PATH = /home/gitea/data/lfs
26+
```

docs/content/doc/usage/https-support.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ To use Gitea's built-in HTTPS support, you must change your `app.ini` file:
2424

2525
```ini
2626
[server]
27-
PROTOCOL=https
28-
ROOT_URL = `https://git.example.com:3000/`
27+
PROTOCOL = https
28+
ROOT_URL = https://git.example.com:3000/
2929
HTTP_PORT = 3000
3030
CERT_FILE = cert.pem
31-
KEY_FILE = key.pem
31+
KEY_FILE = key.pem
3232
```
3333

3434
To learn more about the config values, please checkout the [Config Cheat Sheet](../config-cheat-sheet#server).

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ require (
4848
github.com/go-redis/redis v6.15.2+incompatible
4949
github.com/go-sql-driver/mysql v1.4.1
5050
github.com/go-swagger/go-swagger v0.20.1
51-
github.com/go-xorm/xorm v0.7.8
51+
github.com/go-xorm/xorm v0.7.9
5252
github.com/gobwas/glob v0.2.3
5353
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
5454
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
@@ -64,7 +64,7 @@ require (
6464
github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f
6565
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect
6666
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect
67-
github.com/lafriks/xormstore v1.3.0
67+
github.com/lafriks/xormstore v1.3.1
6868
github.com/lib/pq v1.2.0
6969
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
7070
github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l
249249
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
250250
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
251251
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
252-
github.com/go-xorm/xorm v0.7.8 h1:rKxZJB9mWQ9Nw2TbjsepiThR031jkGePOWXwTtEAU08=
253-
github.com/go-xorm/xorm v0.7.8/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
252+
github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=
253+
github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
254254
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
255255
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
256256
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@@ -384,8 +384,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
384384
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
385385
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
386386
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
387-
github.com/lafriks/xormstore v1.3.0 h1:9A2wAZrdEXtTgfjCFtclPz3pwnmmxY7sJxQgIi62li4=
388-
github.com/lafriks/xormstore v1.3.0/go.mod h1:RAhtOztWBjK9xeZpXwKq59rhUxoRgo1zfYl0H1mtK7A=
387+
github.com/lafriks/xormstore v1.3.1 h1:KpzRUamSV3zmA85Kzw+PZOU9wgMbYsNzuDzLuBMbxpA=
388+
github.com/lafriks/xormstore v1.3.1/go.mod h1:qALRD4Vto2Ic7/A5eplMpu5V62mugtSqFysRwz8FETs=
389389
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
390390
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
391391
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

integrations/api_repo_lfs_locks_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestAPILFSLocksLogged(t *testing.T) {
126126
assert.Len(t, lfsLocks.Locks, test.totalCount)
127127
for i, lock := range lfsLocks.Locks {
128128
assert.EqualValues(t, test.locksOwners[i].DisplayName(), lock.Owner.Name)
129-
assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 3*time.Second)
129+
assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 10*time.Second)
130130
assert.EqualValues(t, lock.LockedAt.Format(time.RFC3339), lock.LockedAt.Format(time.RFC3339Nano)) //locked at should be rounded to second
131131
}
132132

models/error.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,21 @@ func (err ErrIssueLabelTemplateLoad) Error() string {
10891089
return fmt.Sprintf("Failed to load label template file '%s': %v", err.TemplateFile, err.OriginalError)
10901090
}
10911091

1092+
// ErrNewIssueInsert is used when the INSERT statement in newIssue fails
1093+
type ErrNewIssueInsert struct {
1094+
OriginalError error
1095+
}
1096+
1097+
// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert.
1098+
func IsErrNewIssueInsert(err error) bool {
1099+
_, ok := err.(ErrNewIssueInsert)
1100+
return ok
1101+
}
1102+
1103+
func (err ErrNewIssueInsert) Error() string {
1104+
return err.OriginalError.Error()
1105+
}
1106+
10921107
// __________ .__ .__ __________ __
10931108
// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
10941109
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\

models/issue.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (er
766766
}
767767

768768
// Update issue count of milestone
769-
if err = changeMilestoneIssueStats(e, issue); err != nil {
769+
if err := updateMilestoneClosedNum(e, issue.MilestoneID); err != nil {
770770
return err
771771
}
772772

@@ -1104,21 +1104,10 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
11041104
}
11051105

11061106
// Milestone and assignee validation should happen before insert actual object.
1107-
1108-
// There's no good way to identify a duplicate key error in database/sql; brute force some retries
1109-
dupIndexAttempts := issueMaxDupIndexAttempts
1110-
for {
1111-
_, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
1112-
Where("repo_id=?", opts.Issue.RepoID).
1113-
Insert(opts.Issue)
1114-
if err == nil {
1115-
break
1116-
}
1117-
1118-
dupIndexAttempts--
1119-
if dupIndexAttempts <= 0 {
1120-
return err
1121-
}
1107+
if _, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
1108+
Where("repo_id=?", opts.Issue.RepoID).
1109+
Insert(opts.Issue); err != nil {
1110+
return ErrNewIssueInsert{err}
11221111
}
11231112

11241113
inserted, err := getIssueByID(e, opts.Issue.ID)
@@ -1130,7 +1119,7 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
11301119
opts.Issue.Index = inserted.Index
11311120

11321121
if opts.Issue.MilestoneID > 0 {
1133-
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
1122+
if _, err = e.Exec("UPDATE `milestone` SET num_issues=num_issues+1 WHERE id=?", opts.Issue.MilestoneID); err != nil {
11341123
return err
11351124
}
11361125
}
@@ -1201,6 +1190,24 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
12011190

12021191
// NewIssue creates new issue with labels for repository.
12031192
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) (err error) {
1193+
// Retry several times in case INSERT fails due to duplicate key for (repo_id, index); see #7887
1194+
i := 0
1195+
for {
1196+
if err = newIssueAttempt(repo, issue, labelIDs, assigneeIDs, uuids); err == nil {
1197+
return nil
1198+
}
1199+
if !IsErrNewIssueInsert(err) {
1200+
return err
1201+
}
1202+
if i++; i == issueMaxDupIndexAttempts {
1203+
break
1204+
}
1205+
log.Error("NewIssue: error attempting to insert the new issue; will retry. Original error: %v", err)
1206+
}
1207+
return fmt.Errorf("NewIssue: too many errors attempting to insert the new issue. Last error was: %v", err)
1208+
}
1209+
1210+
func newIssueAttempt(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) (err error) {
12041211
sess := x.NewSession()
12051212
defer sess.Close()
12061213
if err = sess.Begin(); err != nil {
@@ -1214,7 +1221,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
12141221
Attachments: uuids,
12151222
AssigneeIDs: assigneeIDs,
12161223
}); err != nil {
1217-
if IsErrUserDoesNotHaveAccessToRepo(err) {
1224+
if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
12181225
return err
12191226
}
12201227
return fmt.Errorf("newIssue: %v", err)
@@ -1223,7 +1230,6 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
12231230
if err = sess.Commit(); err != nil {
12241231
return fmt.Errorf("Commit: %v", err)
12251232
}
1226-
sess.Close()
12271233

12281234
return nil
12291235
}
@@ -1655,14 +1661,14 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
16551661
return nil, err
16561662
}
16571663
case FilterModeAssign:
1658-
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false).
1664+
stats.OpenCount, err = x.Where(cond).And("issue.is_closed = ?", false).
16591665
Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
16601666
And("issue_assignees.assignee_id = ?", opts.UserID).
16611667
Count(new(Issue))
16621668
if err != nil {
16631669
return nil, err
16641670
}
1665-
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true).
1671+
stats.ClosedCount, err = x.Where(cond).And("issue.is_closed = ?", true).
16661672
Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
16671673
And("issue_assignees.assignee_id = ?", opts.UserID).
16681674
Count(new(Issue))
@@ -1683,14 +1689,14 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
16831689
return nil, err
16841690
}
16851691
case FilterModeMention:
1686-
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false).
1692+
stats.OpenCount, err = x.Where(cond).And("issue.is_closed = ?", false).
16871693
Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true).
16881694
And("issue_user.uid = ?", opts.UserID).
16891695
Count(new(Issue))
16901696
if err != nil {
16911697
return nil, err
16921698
}
1693-
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true).
1699+
stats.ClosedCount, err = x.Where(cond).And("issue.is_closed = ?", true).
16941700
Join("INNER", "issue_user", "issue.id = issue_user.issue_id and issue_user.is_mentioned = ?", true).
16951701
And("issue_user.uid = ?", opts.UserID).
16961702
Count(new(Issue))

0 commit comments

Comments
 (0)