aboutsummaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/auth/oauth2_test.go2
-rw-r--r--services/context/pagination.go6
-rw-r--r--services/context/repo.go6
-rw-r--r--services/doctor/fix16961_test.go6
-rw-r--r--services/doctor/misc.go8
-rw-r--r--services/feed/feed.go13
-rw-r--r--services/migrations/gitlab.go9
-rw-r--r--services/mirror/mirror_pull.go40
-rw-r--r--services/mirror/mirror_pull_test.go (renamed from services/mirror/mirror_test.go)28
-rw-r--r--services/repository/adopt_test.go2
-rw-r--r--services/repository/migrate.go14
11 files changed, 97 insertions, 37 deletions
diff --git a/services/auth/oauth2_test.go b/services/auth/oauth2_test.go
index 9edf18d58e..f003742a94 100644
--- a/services/auth/oauth2_test.go
+++ b/services/auth/oauth2_test.go
@@ -26,7 +26,7 @@ func TestUserIDFromToken(t *testing.T) {
o := OAuth2{}
uid := o.userIDFromToken(t.Context(), token, ds)
- assert.Equal(t, int64(user_model.ActionsUserID), uid)
+ assert.Equal(t, user_model.ActionsUserID, uid)
assert.Equal(t, true, ds["IsActionsToken"])
assert.Equal(t, ds["ActionsTaskID"], int64(RunningTaskID))
})
diff --git a/services/context/pagination.go b/services/context/pagination.go
index d33dd217d0..25a9298e01 100644
--- a/services/context/pagination.go
+++ b/services/context/pagination.go
@@ -21,12 +21,18 @@ type Pagination struct {
// NewPagination creates a new instance of the Pagination struct.
// "pagingNum" is "page size" or "limit", "current" is "page"
+// total=-1 means only showing prev/next
func NewPagination(total, pagingNum, current, numPages int) *Pagination {
p := &Pagination{}
p.Paginater = paginator.New(total, pagingNum, current, numPages)
return p
}
+func (p *Pagination) WithCurRows(n int) *Pagination {
+ p.Paginater.SetCurRows(n)
+ return p
+}
+
func (p *Pagination) AddParamFromRequest(req *http.Request) {
for key, values := range req.URL.Query() {
if key == "page" || len(values) == 0 || (len(values) == 1 && values[0] == "") {
diff --git a/services/context/repo.go b/services/context/repo.go
index 6eccd1312a..7d0b44c42f 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -328,7 +328,9 @@ func RedirectToRepo(ctx *Base, redirectRepoID int64) {
if ctx.Req.URL.RawQuery != "" {
redirectPath += "?" + ctx.Req.URL.RawQuery
}
- ctx.Redirect(path.Join(setting.AppSubURL, redirectPath), http.StatusTemporaryRedirect)
+ // Git client needs a 301 redirect by default to follow the new location
+ // It's not documentated in git documentation, but it's the behavior of git client
+ ctx.Redirect(path.Join(setting.AppSubURL, redirectPath), http.StatusMovedPermanently)
}
func repoAssignment(ctx *Context, repo *repo_model.Repository) {
@@ -344,7 +346,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
return
}
- if !ctx.Repo.Permission.HasAnyUnitAccessOrEveryoneAccess() && !canWriteAsMaintainer(ctx) {
+ if !ctx.Repo.Permission.HasAnyUnitAccessOrPublicAccess() && !canWriteAsMaintainer(ctx) {
if ctx.FormString("go-get") == "1" {
EarlyResponseForGoGetMeta(ctx)
return
diff --git a/services/doctor/fix16961_test.go b/services/doctor/fix16961_test.go
index 498ed9c8d5..d5eded1117 100644
--- a/services/doctor/fix16961_test.go
+++ b/services/doctor/fix16961_test.go
@@ -19,12 +19,6 @@ func Test_fixUnitConfig_16961(t *testing.T) {
wantErr bool
}{
{
- name: "empty",
- bs: "",
- wantFixed: true,
- wantErr: false,
- },
- {
name: "normal: {}",
bs: "{}",
wantFixed: false,
diff --git a/services/doctor/misc.go b/services/doctor/misc.go
index d934640af5..1269d088c3 100644
--- a/services/doctor/misc.go
+++ b/services/doctor/misc.go
@@ -8,7 +8,7 @@ import (
"fmt"
"os"
"os/exec"
- "path"
+ "path/filepath"
"strings"
"code.gitea.io/gitea/models"
@@ -148,7 +148,7 @@ func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) err
}
// Create/Remove git-daemon-export-ok for git-daemon...
- daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`)
+ daemonExportFile := filepath.Join(repo.RepoPath(), `git-daemon-export-ok`)
isExist, err := util.IsExist(daemonExportFile)
if err != nil {
log.Error("Unable to check if %s exists. Error: %v", daemonExportFile, err)
@@ -196,7 +196,7 @@ func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) erro
commitGraphExists := func() (bool, error) {
// Check commit-graph exists
- commitGraphFile := path.Join(repo.RepoPath(), `objects/info/commit-graph`)
+ commitGraphFile := filepath.Join(repo.RepoPath(), `objects/info/commit-graph`)
isExist, err := util.IsExist(commitGraphFile)
if err != nil {
logger.Error("Unable to check if %s exists. Error: %v", commitGraphFile, err)
@@ -204,7 +204,7 @@ func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) erro
}
if !isExist {
- commitGraphsDir := path.Join(repo.RepoPath(), `objects/info/commit-graphs`)
+ commitGraphsDir := filepath.Join(repo.RepoPath(), `objects/info/commit-graphs`)
isExist, err = util.IsExist(commitGraphsDir)
if err != nil {
logger.Error("Unable to check if %s exists. Error: %v", commitGraphsDir, err)
diff --git a/services/feed/feed.go b/services/feed/feed.go
index 41a918f00e..214e9b5765 100644
--- a/services/feed/feed.go
+++ b/services/feed/feed.go
@@ -15,24 +15,17 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
)
func userFeedCacheKey(userID int64) string {
return fmt.Sprintf("user_feed_%d", userID)
}
-func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int64, error) {
+func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int, error) {
opts.DontCount = opts.RequestedTeam == nil && opts.Date == ""
results, cnt, err := activities_model.GetFeeds(ctx, opts)
- if err != nil {
- return nil, 0, err
- }
- if opts.DontCount {
- cnt, err = cache.GetInt64(userFeedCacheKey(opts.Actor.ID), func() (int64, error) {
- return activities_model.CountUserFeeds(ctx, opts.Actor.ID)
- })
- }
- return results, cnt, err
+ return results, util.Iif(opts.DontCount, -1, int(cnt)), err
}
// GetFeeds returns actions according to the provided options
diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go
index efc5b960cf..4bed8e2f6c 100644
--- a/services/migrations/gitlab.go
+++ b/services/migrations/gitlab.go
@@ -16,6 +16,7 @@ import (
"time"
issues_model "code.gitea.io/gitea/models/issues"
+ "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration"
@@ -535,11 +536,15 @@ func (g *GitlabDownloader) GetComments(ctx context.Context, commentable base.Com
}
for _, stateEvent := range stateEvents {
+ posterUserID, posterUsername := user.GhostUserID, user.GhostUserName
+ if stateEvent.User != nil {
+ posterUserID, posterUsername = int64(stateEvent.User.ID), stateEvent.User.Username
+ }
comment := &base.Comment{
IssueIndex: commentable.GetLocalIndex(),
Index: int64(stateEvent.ID),
- PosterID: int64(stateEvent.User.ID),
- PosterName: stateEvent.User.Username,
+ PosterID: posterUserID,
+ PosterName: posterUsername,
Content: "",
Created: *stateEvent.CreatedAt,
}
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index 658747e7c8..fa5b9934ec 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -235,6 +235,24 @@ func pruneBrokenReferences(ctx context.Context,
return pruneErr
}
+// checkRecoverableSyncError takes an error message from a git fetch command and returns false if it should be a fatal/blocking error
+func checkRecoverableSyncError(stderrMessage string) bool {
+ switch {
+ case strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken"):
+ return true
+ case strings.Contains(stderrMessage, "remote error") && strings.Contains(stderrMessage, "not our ref"):
+ return true
+ case strings.Contains(stderrMessage, "cannot lock ref") && strings.Contains(stderrMessage, "but expected"):
+ return true
+ case strings.Contains(stderrMessage, "cannot lock ref") && strings.Contains(stderrMessage, "unable to resolve reference"):
+ return true
+ case strings.Contains(stderrMessage, "Unable to create") && strings.Contains(stderrMessage, ".lock"):
+ return true
+ default:
+ return false
+ }
+}
+
// runSync returns true if sync finished without error.
func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bool) {
repoPath := m.Repo.RepoPath()
@@ -275,7 +293,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
stdoutMessage := util.SanitizeCredentialURLs(stdout)
// Now check if the error is a resolve reference due to broken reference
- if strings.Contains(stderr, "unable to resolve reference") && strings.Contains(stderr, "reference broken") {
+ if checkRecoverableSyncError(stderr) {
log.Warn("SyncMirrors [repo: %-v]: failed to update mirror repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
err = nil
@@ -324,6 +342,15 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
return nil, false
}
+ if m.LFS && setting.LFS.StartServer {
+ log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
+ endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
+ lfsClient := lfs.NewClient(endpoint, nil)
+ if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
+ log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
+ }
+ }
+
log.Trace("SyncMirrors [repo: %-v]: syncing branches...", m.Repo)
if _, err = repo_module.SyncRepoBranchesWithRepo(ctx, m.Repo, gitRepo, 0); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize branches: %v", m.Repo, err)
@@ -333,15 +360,6 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
if err = repo_module.SyncReleasesWithTags(ctx, m.Repo, gitRepo); err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to synchronize tags to releases: %v", m.Repo, err)
}
-
- if m.LFS && setting.LFS.StartServer {
- log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
- endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
- lfsClient := lfs.NewClient(endpoint, nil)
- if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
- log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
- }
- }
gitRepo.Close()
log.Trace("SyncMirrors [repo: %-v]: updating size of repository", m.Repo)
@@ -368,7 +386,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
stdoutMessage := util.SanitizeCredentialURLs(stdout)
// Now check if the error is a resolve reference due to broken reference
- if strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken") {
+ if checkRecoverableSyncError(stderrMessage) {
log.Warn("SyncMirrors [repo: %-v Wiki]: failed to update mirror wiki repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
err = nil
diff --git a/services/mirror/mirror_test.go b/services/mirror/mirror_pull_test.go
index 76632b6872..67ef37c954 100644
--- a/services/mirror/mirror_test.go
+++ b/services/mirror/mirror_pull_test.go
@@ -64,3 +64,31 @@ func Test_parseRemoteUpdateOutput(t *testing.T) {
assert.EqualValues(t, "1c97ebc746", results[9].oldCommitID)
assert.EqualValues(t, "976d27d52f", results[9].newCommitID)
}
+
+func Test_checkRecoverableSyncError(t *testing.T) {
+ cases := []struct {
+ recoverable bool
+ message string
+ }{
+ // A race condition in http git-fetch where certain refs were listed on the remote and are no longer there, would exit status 128
+ {true, "fatal: remote error: upload-pack: not our ref 988881adc9fc3655077dc2d4d757d480b5ea0e11"},
+ // A race condition where a local gc/prune removes a named ref during a git-fetch would exit status 1
+ {true, "cannot lock ref 'refs/pull/123456/merge': unable to resolve reference 'refs/pull/134153/merge'"},
+ // A race condition in http git-fetch where named refs were listed on the remote and are no longer there
+ {true, "error: cannot lock ref 'refs/remotes/origin/foo': unable to resolve reference 'refs/remotes/origin/foo': reference broken"},
+ // A race condition in http git-fetch where named refs were force-pushed during the update, would exit status 128
+ {true, "error: cannot lock ref 'refs/pull/123456/merge': is at 988881adc9fc3655077dc2d4d757d480b5ea0e11 but expected 7f894307ffc9553edbd0b671cab829786866f7b2"},
+ // A race condition with other local git operations, such as git-maintenance, would exit status 128 (well, "Unable" the "U" is uppercase)
+ {true, "fatal: Unable to create '/data/gitea-repositories/foo-org/bar-repo.git/./objects/info/commit-graphs/commit-graph-chain.lock': File exists."},
+ // Missing or unauthorized credentials, would exit status 128
+ {false, "fatal: Authentication failed for 'https://example.com/foo-does-not-exist/bar.git/'"},
+ // A non-existent remote repository, would exit status 128
+ {false, "fatal: Could not read from remote repository."},
+ // A non-functioning proxy, would exit status 128
+ {false, "fatal: unable to access 'https://example.com/foo-does-not-exist/bar.git/': Failed to connect to configured-https-proxy port 1080 after 0 ms: Couldn't connect to server"},
+ }
+
+ for _, c := range cases {
+ assert.Equal(t, c.recoverable, checkRecoverableSyncError(c.message), "test case: %s", c.message)
+ }
+}
diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go
index 123cedc1f2..294185ea1f 100644
--- a/services/repository/adopt_test.go
+++ b/services/repository/adopt_test.go
@@ -71,7 +71,7 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
username := "user2"
unadoptedList := []string{path.Join(username, "unadopted1"), path.Join(username, "unadopted2")}
for _, unadopted := range unadoptedList {
- _ = os.Mkdir(path.Join(setting.RepoRootPath, unadopted+".git"), 0o755)
+ _ = os.Mkdir(filepath.Join(setting.RepoRootPath, unadopted+".git"), 0o755)
}
opts := db.ListOptions{Page: 1, PageSize: 1}
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 5b6feccb8d..9a5c6ffb0f 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
@@ -246,6 +247,19 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
}
}
+ var enableRepoUnits []repo_model.RepoUnit
+ if opts.Releases && !unit_model.TypeReleases.UnitGlobalDisabled() {
+ enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeReleases})
+ }
+ if opts.Wiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
+ enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeWiki})
+ }
+ if len(enableRepoUnits) > 0 {
+ err = UpdateRepositoryUnits(ctx, repo, enableRepoUnits, nil)
+ if err != nil {
+ return nil, err
+ }
+ }
return repo, committer.Commit()
}