diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a88eb1035..a92a61b497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,32 @@ This changelog goes through all the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.io). +## [1.10.0-RC2](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc2) - 2019-10-30 +* BREAKING + * Fix deadline on update issue or PR via API (#8698) + * Hide some user information via API if user doesn't have enough permission (#8655) (#8657) +* BUGFIXES + * Expose db.SetMaxOpenConns and allow non MySQL dbs to set conn pool params (#8528) (#8618) + * Fix milestone close timestamp (#8728) (#8730) + * Fix 500 when getting user as unauthenticated user (#8653) (#8663) + * Fix 'New Issue Missing Milestone Comment' (#8678) (#8681) + * Use AppSubUrl for more redirections (#8647) (#8651) + * Add SubURL to redirect path (#8632) (#8634) + * Fix template error on account page (#8562) (#8622) + * Allow externalID to be UUID (#8551) (#8624) + * Prevent removal of non-empty emoji panel following selection of duplicate (#8609) (#8623) + * Update heatmap fixtures to restore tests (#8615) (#8616) + * Ensure that diff stats can scroll independently of the diff (#8581) (#8621) + * Webhook: set Content-Type for application/x-www-form-urlencoded (#8600) + * Fix #8582 by handling empty repos (#8587) (#8594) + * Fix bug on pull requests when transfer head repository (#8564) (#8569) + * Add missed close in ServeBlobLFS (#8527) (#8542) + * Ensure that GitRepo is set on Empty repositories (#8539) (#8541) + * Fix migrate mirror 500 bug (#8526) (#8530) + * Fix password complexity regex for special characters (#8524) + * Prevent .code-view from overriding font on icon fonts (#8614) (#8627) + * Allow more than 255 characters for tokens in external_login_user table (#8554) + ## [1.10.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc1) - 2019-10-14 * BREAKING * Remove legacy handling of drone token (#8191) @@ -263,6 +289,30 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243) * Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141) +## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30 +* BREAKING + * Hide some user information via API if user doesn't have enough permission (#8655) (#8658) +* BUGFIXES + * Fix milestone close timestamp (#8728) (#8731) + * Fix deadline on update issue or PR via API (#8699) + * Fix 'New Issue Missing Milestone Comment' (#8678) (#8682) + * Fix 500 when getting user as unauthenticated user (#8653) (#8662) + * Use AppSubUrl for more redirections (#8647) (#8652) + * Add SubURL to redirect path (#8632) (#8634) (#8640) + * Fix #8582 by handling empty repos (#8587) (#8593) + * Fix bug on pull requests when transfer head repository (#8571) + * Add missed close in ServeBlobLFS (#8527) (#8543) + * Return false if provided branch name is empty for IsBranchExist (#8485) (#8492) + * Create .ssh dir as necessary (#8369) (#8486) (#8489) + * Restore functionality for early gits (#7775) (#8476) + * Add check for empty set when dropping indexes during migration (#8475) + * Ensure Request Body Readers are closed in LFS server (#8454) (#8459) + * Ensure that LFS files are relative to the LFS content path (#8455) (#8458) +* SECURITY + * Ignore mentions for users with no access (#8395) (#8484) +* TESTING + * Update heatmap fixtures to restore tests (#8615) (#8617) + ## [1.9.4](https://github.com/go-gitea/gitea/releases/tag/v1.9.4) - 2019-10-08 * BUGFIXES * Highlight issue references (#8101) (#8404) diff --git a/cmd/admin.go b/cmd/admin.go index 4346159feb..83ced76c96 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -66,7 +66,7 @@ var ( }, cli.BoolFlag{ Name: "must-change-password", - Usage: "Force the user to change his/her password after initial login", + Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)", }, cli.IntFlag{ Name: "random-password-length", diff --git a/models/pull.go b/models/pull.go index c6da63ec55..45a1daac46 100644 --- a/models/pull.go +++ b/models/pull.go @@ -16,7 +16,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" @@ -26,7 +25,6 @@ import ( "code.gitea.io/gitea/modules/timeutil" "github.com/unknwon/com" - "xorm.io/xorm" ) var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength) @@ -753,66 +751,6 @@ func newPullRequestAttempt(repo *Repository, pull *Issue, labelIDs []int64, uuid return nil } -// PullRequestsOptions holds the options for PRs -type PullRequestsOptions struct { - Page int - State string - SortType string - Labels []string - MilestoneID int64 -} - -func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xorm.Session, error) { - sess := x.Where("pull_request.base_repo_id=?", baseRepoID) - - sess.Join("INNER", "issue", "pull_request.issue_id = issue.id") - switch opts.State { - case "closed", "open": - sess.And("issue.is_closed=?", opts.State == "closed") - } - - if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil { - return nil, err - } else if len(labelIDs) > 0 { - sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id"). - In("issue_label.label_id", labelIDs) - } - - if opts.MilestoneID > 0 { - sess.And("issue.milestone_id=?", opts.MilestoneID) - } - - return sess, nil -} - -// PullRequests returns all pull requests for a base Repo by the given conditions -func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, int64, error) { - if opts.Page <= 0 { - opts.Page = 1 - } - - countSession, err := listPullRequestStatement(baseRepoID, opts) - if err != nil { - log.Error("listPullRequestStatement: %v", err) - return nil, 0, err - } - maxResults, err := countSession.Count(new(PullRequest)) - if err != nil { - log.Error("Count PRs: %v", err) - return nil, maxResults, err - } - - prs := make([]*PullRequest, 0, ItemsPerPage) - findSession, err := listPullRequestStatement(baseRepoID, opts) - sortIssuesSession(findSession, opts.SortType) - if err != nil { - log.Error("listPullRequestStatement: %v", err) - return nil, maxResults, err - } - findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage) - return prs, maxResults, findSession.Find(&prs) -} - // GetUnmergedPullRequest returns a pull request that is open and has not been merged // by given head/base and repo/branch. func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch string) (*PullRequest, error) { @@ -831,17 +769,6 @@ func GetUnmergedPullRequest(headRepoID, baseRepoID int64, headBranch, baseBranch return pr, nil } -// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged -// by given head information (repo and branch). -func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) { - prs := make([]*PullRequest, 0, 2) - return prs, x. - Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?", - repoID, branch, false, false). - Join("INNER", "issue", "issue.id = pull_request.issue_id"). - Find(&prs) -} - // GetLatestPullRequestByHeadInfo returns the latest pull request (regardless of its status) // by given head information (repo and branch). func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest, error) { @@ -856,17 +783,6 @@ func GetLatestPullRequestByHeadInfo(repoID int64, branch string) (*PullRequest, return pr, err } -// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged -// by given base information (repo and branch). -func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) { - prs := make([]*PullRequest, 0, 2) - return prs, x. - Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?", - repoID, branch, false, false). - Join("INNER", "issue", "issue.id=pull_request.issue_id"). - Find(&prs) -} - // GetPullRequestByIndex returns a pull request by the given index func GetPullRequestByIndex(repoID int64, index int64) (*PullRequest, error) { pr := &PullRequest{ @@ -1035,72 +951,6 @@ func (pr *PullRequest) AddToTaskQueue() { }) } -// PullRequestList defines a list of pull requests -type PullRequestList []*PullRequest - -func (prs PullRequestList) loadAttributes(e Engine) error { - if len(prs) == 0 { - return nil - } - - // Load issues. - issueIDs := prs.getIssueIDs() - issues := make([]*Issue, 0, len(issueIDs)) - if err := e. - Where("id > 0"). - In("id", issueIDs). - Find(&issues); err != nil { - return fmt.Errorf("find issues: %v", err) - } - - set := make(map[int64]*Issue) - for i := range issues { - set[issues[i].ID] = issues[i] - } - for i := range prs { - prs[i].Issue = set[prs[i].IssueID] - } - return nil -} - -func (prs PullRequestList) getIssueIDs() []int64 { - issueIDs := make([]int64, 0, len(prs)) - for i := range prs { - issueIDs = append(issueIDs, prs[i].IssueID) - } - return issueIDs -} - -// LoadAttributes load all the prs attributes -func (prs PullRequestList) LoadAttributes() error { - return prs.loadAttributes(x) -} - -func (prs PullRequestList) invalidateCodeComments(e Engine, doer *User, repo *git.Repository, branch string) error { - if len(prs) == 0 { - return nil - } - issueIDs := prs.getIssueIDs() - var codeComments []*Comment - if err := e. - Where("type = ? and invalidated = ?", CommentTypeCode, false). - In("issue_id", issueIDs). - Find(&codeComments); err != nil { - return fmt.Errorf("find code comments: %v", err) - } - for _, comment := range codeComments { - if err := comment.CheckInvalidation(repo, doer, branch); err != nil { - return err - } - } - return nil -} - -// InvalidateCodeComments will lookup the prs for code comments which got invalidated by change -func (prs PullRequestList) InvalidateCodeComments(doer *User, repo *git.Repository, branch string) error { - return prs.invalidateCodeComments(x, doer, repo, branch) -} - // checkAndUpdateStatus checks if pull request is possible to leaving checking status, // and set to be either conflict or mergeable. func (pr *PullRequest) checkAndUpdateStatus() { @@ -1152,64 +1002,3 @@ func (pr *PullRequest) GetWorkInProgressPrefix() string { } return "" } - -// TestPullRequests checks and tests untested patches of pull requests. -// TODO: test more pull requests at same time. -func TestPullRequests() { - prs := make([]*PullRequest, 0, 10) - - err := x.Where("status = ?", PullRequestStatusChecking).Find(&prs) - if err != nil { - log.Error("Find Checking PRs: %v", err) - return - } - - var checkedPRs = make(map[int64]struct{}) - - // Update pull request status. - for _, pr := range prs { - checkedPRs[pr.ID] = struct{}{} - if err := pr.GetBaseRepo(); err != nil { - log.Error("GetBaseRepo: %v", err) - continue - } - if pr.manuallyMerged() { - continue - } - if err := pr.testPatch(x); err != nil { - log.Error("testPatch: %v", err) - continue - } - - pr.checkAndUpdateStatus() - } - - // Start listening on new test requests. - for prID := range pullRequestQueue.Queue() { - log.Trace("TestPullRequests[%v]: processing test task", prID) - pullRequestQueue.Remove(prID) - - id := com.StrTo(prID).MustInt64() - if _, ok := checkedPRs[id]; ok { - continue - } - - pr, err := GetPullRequestByID(id) - if err != nil { - log.Error("GetPullRequestByID[%s]: %v", prID, err) - continue - } else if pr.manuallyMerged() { - continue - } else if err = pr.testPatch(x); err != nil { - log.Error("testPatch[%d]: %v", pr.ID, err) - continue - } - - pr.checkAndUpdateStatus() - } -} - -// InitTestPullRequests runs the task to test all the checking status pull requests -func InitTestPullRequests() { - go TestPullRequests() -} diff --git a/models/pull_list.go b/models/pull_list.go new file mode 100644 index 0000000000..4ec6fdde3b --- /dev/null +++ b/models/pull_list.go @@ -0,0 +1,224 @@ +// 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 models + +import ( + "fmt" + + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "github.com/unknwon/com" + "xorm.io/xorm" +) + +// PullRequestsOptions holds the options for PRs +type PullRequestsOptions struct { + Page int + State string + SortType string + Labels []string + MilestoneID int64 +} + +func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xorm.Session, error) { + sess := x.Where("pull_request.base_repo_id=?", baseRepoID) + + sess.Join("INNER", "issue", "pull_request.issue_id = issue.id") + switch opts.State { + case "closed", "open": + sess.And("issue.is_closed=?", opts.State == "closed") + } + + if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil { + return nil, err + } else if len(labelIDs) > 0 { + sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id"). + In("issue_label.label_id", labelIDs) + } + + if opts.MilestoneID > 0 { + sess.And("issue.milestone_id=?", opts.MilestoneID) + } + + return sess, nil +} + +// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged +// by given head information (repo and branch). +func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) { + prs := make([]*PullRequest, 0, 2) + return prs, x. + Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ?", + repoID, branch, false, false). + Join("INNER", "issue", "issue.id = pull_request.issue_id"). + Find(&prs) +} + +// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged +// by given base information (repo and branch). +func GetUnmergedPullRequestsByBaseInfo(repoID int64, branch string) ([]*PullRequest, error) { + prs := make([]*PullRequest, 0, 2) + return prs, x. + Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?", + repoID, branch, false, false). + Join("INNER", "issue", "issue.id=pull_request.issue_id"). + Find(&prs) +} + +// PullRequests returns all pull requests for a base Repo by the given conditions +func PullRequests(baseRepoID int64, opts *PullRequestsOptions) ([]*PullRequest, int64, error) { + if opts.Page <= 0 { + opts.Page = 1 + } + + countSession, err := listPullRequestStatement(baseRepoID, opts) + if err != nil { + log.Error("listPullRequestStatement: %v", err) + return nil, 0, err + } + maxResults, err := countSession.Count(new(PullRequest)) + if err != nil { + log.Error("Count PRs: %v", err) + return nil, maxResults, err + } + + prs := make([]*PullRequest, 0, ItemsPerPage) + findSession, err := listPullRequestStatement(baseRepoID, opts) + sortIssuesSession(findSession, opts.SortType) + if err != nil { + log.Error("listPullRequestStatement: %v", err) + return nil, maxResults, err + } + findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage) + return prs, maxResults, findSession.Find(&prs) +} + +// PullRequestList defines a list of pull requests +type PullRequestList []*PullRequest + +func (prs PullRequestList) loadAttributes(e Engine) error { + if len(prs) == 0 { + return nil + } + + // Load issues. + issueIDs := prs.getIssueIDs() + issues := make([]*Issue, 0, len(issueIDs)) + if err := e. + Where("id > 0"). + In("id", issueIDs). + Find(&issues); err != nil { + return fmt.Errorf("find issues: %v", err) + } + + set := make(map[int64]*Issue) + for i := range issues { + set[issues[i].ID] = issues[i] + } + for i := range prs { + prs[i].Issue = set[prs[i].IssueID] + } + return nil +} + +func (prs PullRequestList) getIssueIDs() []int64 { + issueIDs := make([]int64, 0, len(prs)) + for i := range prs { + issueIDs = append(issueIDs, prs[i].IssueID) + } + return issueIDs +} + +// LoadAttributes load all the prs attributes +func (prs PullRequestList) LoadAttributes() error { + return prs.loadAttributes(x) +} + +func (prs PullRequestList) invalidateCodeComments(e Engine, doer *User, repo *git.Repository, branch string) error { + if len(prs) == 0 { + return nil + } + issueIDs := prs.getIssueIDs() + var codeComments []*Comment + if err := e. + Where("type = ? and invalidated = ?", CommentTypeCode, false). + In("issue_id", issueIDs). + Find(&codeComments); err != nil { + return fmt.Errorf("find code comments: %v", err) + } + for _, comment := range codeComments { + if err := comment.CheckInvalidation(repo, doer, branch); err != nil { + return err + } + } + return nil +} + +// InvalidateCodeComments will lookup the prs for code comments which got invalidated by change +func (prs PullRequestList) InvalidateCodeComments(doer *User, repo *git.Repository, branch string) error { + return prs.invalidateCodeComments(x, doer, repo, branch) +} + +// TestPullRequests checks and tests untested patches of pull requests. +// TODO: test more pull requests at same time. +func TestPullRequests() { + prs := make([]*PullRequest, 0, 10) + + err := x.Where("status = ?", PullRequestStatusChecking).Find(&prs) + if err != nil { + log.Error("Find Checking PRs: %v", err) + return + } + + var checkedPRs = make(map[int64]struct{}) + + // Update pull request status. + for _, pr := range prs { + checkedPRs[pr.ID] = struct{}{} + if err := pr.GetBaseRepo(); err != nil { + log.Error("GetBaseRepo: %v", err) + continue + } + if pr.manuallyMerged() { + continue + } + if err := pr.testPatch(x); err != nil { + log.Error("testPatch: %v", err) + continue + } + + pr.checkAndUpdateStatus() + } + + // Start listening on new test requests. + for prID := range pullRequestQueue.Queue() { + log.Trace("TestPullRequests[%v]: processing test task", prID) + pullRequestQueue.Remove(prID) + + id := com.StrTo(prID).MustInt64() + if _, ok := checkedPRs[id]; ok { + continue + } + + pr, err := GetPullRequestByID(id) + if err != nil { + log.Error("GetPullRequestByID[%s]: %v", prID, err) + continue + } else if pr.manuallyMerged() { + continue + } else if err = pr.testPatch(x); err != nil { + log.Error("testPatch[%d]: %v", pr.ID, err) + continue + } + + pr.checkAndUpdateStatus() + } +} + +// InitTestPullRequests runs the task to test all the checking status pull requests +func InitTestPullRequests() { + go TestPullRequests() +} diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index f18b74e3b1..3b4ae38f5a 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -11,7 +11,7 @@ register=Registrieren website=Webseite version=Version page=Seite -template=Vorlage +template=Template language=Sprache notifications=Benachrichtigungen create_new=Erstellen… @@ -702,6 +702,7 @@ editor.preview_changes=Vorschau der Änderungen editor.cannot_edit_lfs_files=LFS-Dateien können im Webinterface nicht bearbeitet werden. editor.cannot_edit_non_text_files=Binärdateien können nicht im Webinterface bearbeitet werden. editor.edit_this_file=Datei bearbeiten +editor.this_file_locked=Datei ist gesperrt editor.must_be_on_a_branch=Du musst dich in einem Branch befinden, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen. editor.fork_before_edit=Du musst dieses Repository forken, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen. editor.delete_this_file=Datei löschen @@ -976,6 +977,7 @@ issues.review.review=Review issues.review.reviewers=Reviewer issues.review.show_outdated=Veraltete anzeigen issues.review.hide_outdated=Veraltete ausblenden +issues.assignee.error=Aufgrund eines unerwarteten Fehlers konnten nicht alle Beauftragten hinzugefügt werden. pulls.desc=Pull-Requests und Code-Reviews aktivieren. pulls.new=Neuer Pull-Request @@ -1334,6 +1336,7 @@ settings.protect_this_branch=Branch-Schutz aktivieren settings.protect_this_branch_desc=Löschen verhindern und „force pushing” von Git auf dieser Branch deaktivieren. settings.protect_whitelist_committers=Push-Whitelist aktivieren settings.protect_whitelist_committers_desc=Erlaube, dass Benutzer oder Teams, die auf der Whitelist stehen, auf diese Branch "pushen" dürfen (aber nicht "force pushen"). +settings.protect_whitelist_deploy_keys=Deploy-Schlüssel mit Schreibzugriff zum Push whitelisten settings.protect_whitelist_users=Nutzer, die pushen dürfen: settings.protect_whitelist_search_users=Benutzer suchen… settings.protect_whitelist_teams=Teams, die pushen dürfen: @@ -1375,6 +1378,20 @@ settings.unarchive.text=Durch das Aufheben der Archivierung kann das Repo wieder settings.unarchive.success=Die Archivierung des Repos wurde erfolgreich wieder rückgängig gemacht. settings.unarchive.error=Beim Versuch, die Archivierung des Repos aufzuheben, ist ein Fehler aufgetreten. Weitere Details finden sich im Log. settings.update_avatar_success=Der Repository-Avatar wurde aktualisiert. +settings.lfs=LFS +settings.lfs_filelist=LFS-Dateien, die in diesem Repository gespeichert sind +settings.lfs_no_lfs_files=In diesem Repository sind keine LFS-Dateien gespeichert +settings.lfs_findcommits=Commits finden +settings.lfs_lfs_file_no_commits=Keine Commits für diese LFS-Datei gefunden +settings.lfs_delete=LFS-Datei mit OID %s löschen +settings.lfs_delete_warning=Das Löschen einer LFS-Datei kann dazu führen, dass 'Objekt existiert nicht'-Fehler beim Checkout auftreten. Bist du sicher? +settings.lfs_findpointerfiles=Pointer-Dateien finden +settings.lfs_pointers.found=%d Blob-Zeiger gefunden - %d assoziiert, %d nicht assoziiert (%d fehlend im Speicher) +settings.lfs_pointers.sha=Blob SHA +settings.lfs_pointers.oid=OID +settings.lfs_pointers.inRepo=Im Repo +settings.lfs_pointers.exists=Existiert im Speicher +settings.lfs_pointers.accessible=Nutzer hat Zugriff diff.browse_source=Quellcode durchsuchen diff.parent=Ursprung