diff --git a/docs/content/doc/features/comparison.en-us.md b/docs/content/doc/features/comparison.en-us.md index 2a622a4b39c4..77299404cb65 100644 --- a/docs/content/doc/features/comparison.en-us.md +++ b/docs/content/doc/features/comparison.en-us.md @@ -47,7 +47,7 @@ _Symbols used in table:_ | Built-in Container Registry | [✘](https://github.com/go-gitea/gitea/issues/2316) | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | | External git mirroring | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ | | FIDO U2F (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ | -| Built-in CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ | +| Built-in CI/CD | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ | | Subgroups: groups within groups | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✓ | #### Code management diff --git a/docs/content/doc/installation/on-kubernetes.en-us.md b/docs/content/doc/installation/on-kubernetes.en-us.md new file mode 100644 index 000000000000..025117f64a72 --- /dev/null +++ b/docs/content/doc/installation/on-kubernetes.en-us.md @@ -0,0 +1,27 @@ +--- +date: "2020-03-19T19:27:00+02:00" +title: "Install on Kubernetes" +slug: "install-on-kubernetes" +weight: 10 +toc: true +draft: false +menu: + sidebar: + parent: "installation" + name: "Kubernetes" + weight: 50 + identifier: "install-on-kubernetes" +--- + +# Installation with Helm (on Kubernetes) + +Gitea provides a Helm Chart to allow for installation on kubernetes. + +A non-customized install can be done with: + +``` +helm repo add gitea-charts https://dl.gitea.io/charts/ +helm install gitea gitea-charts/gitea +``` + +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/) diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go index b0031ef33299..b8e513958e84 100644 --- a/integrations/api_helper_for_declarative_test.go +++ b/integrations/api_helper_for_declarative_test.go @@ -235,6 +235,10 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) DecodeJSON(t, resp, &err) assert.EqualValues(t, "Please try again later", err.Message) queue.GetManager().FlushAll(context.Background(), 5*time.Second) + req = NewRequestWithJSON(t, http.MethodPost, urlStr, &auth.MergePullRequestForm{ + MergeMessageField: "doAPIMergePullRequest Merge", + Do: string(models.MergeStyleMerge), + }) resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus) } diff --git a/integrations/repo_branch_test.go b/integrations/repo_branch_test.go index 68806f347bd3..de4e66898797 100644 --- a/integrations/repo_branch_test.go +++ b/integrations/repo_branch_test.go @@ -104,13 +104,12 @@ func testCreateBranches(t *testing.T, giteaURL *url.URL) { { OldRefSubURL: "tag/v1.0.0", NewBranch: "feature/test4", - CreateRelease: "v1.0.0", + CreateRelease: "v1.0.1", ExpectedStatus: http.StatusFound, FlashMessage: i18n.Tr("en", "repo.branch.create_success", "feature/test4"), }, } for _, test := range tests { - defer prepareTestEnv(t)() session := loginUser(t, "user2") if test.CreateRelease != "" { createNewRelease(t, session, "/user2/repo1", test.CreateRelease, test.CreateRelease, false, false) diff --git a/integrations/repo_commits_search_test.go b/integrations/repo_commits_search_test.go index 3cd548e81029..0dc0588297f1 100644 --- a/integrations/repo_commits_search_test.go +++ b/integrations/repo_commits_search_test.go @@ -14,8 +14,6 @@ import ( ) func testRepoCommitsSearch(t *testing.T, query, commit string) { - defer prepareTestEnv(t)() - session := loginUser(t, "user2") // Request repository commits page @@ -28,6 +26,7 @@ func testRepoCommitsSearch(t *testing.T, query, commit string) { } func TestRepoCommitsSearch(t *testing.T) { + defer prepareTestEnv(t)() testRepoCommitsSearch(t, "e8eabd", "") testRepoCommitsSearch(t, "38a9cb", "") testRepoCommitsSearch(t, "6e8e", "6e8eabd9a7") diff --git a/models/issue_comment.go b/models/issue_comment.go index a7e9c049bf30..7bcea40b9300 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -712,6 +712,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err RefAction: opts.RefAction, RefIsPull: opts.RefIsPull, IsForcePush: opts.IsForcePush, + Invalidated: opts.Invalidated, } if _, err = e.Insert(comment); err != nil { return nil, err @@ -878,6 +879,7 @@ type CreateCommentOptions struct { RefAction references.XRefAction RefIsPull bool IsForcePush bool + Invalidated bool } // CreateComment creates comment of issue or commit. @@ -953,6 +955,8 @@ type FindCommentsOptions struct { ReviewID int64 Since int64 Before int64 + Line int64 + TreePath string Type CommentType } @@ -976,6 +980,12 @@ func (opts *FindCommentsOptions) toConds() builder.Cond { if opts.Type != CommentTypeUnknown { cond = cond.And(builder.Eq{"comment.type": opts.Type}) } + if opts.Line > 0 { + cond = cond.And(builder.Eq{"comment.line": opts.Line}) + } + if len(opts.TreePath) > 0 { + cond = cond.And(builder.Eq{"comment.tree_path": opts.TreePath}) + } return cond } @@ -990,6 +1000,8 @@ func findComments(e Engine, opts FindCommentsOptions) ([]*Comment, error) { sess = opts.setSessionPagination(sess) } + // WARNING: If you change this order you will need to fix createCodeComment + return comments, sess. Asc("comment.created_unix"). Asc("comment.id"). diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index cbf8ae87327e..4715f192c157 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -250,6 +250,8 @@ var migrations = []Migration{ NewMigration("fix publisher ID for tag releases", fixPublisherIDforTagReleases), // v157 -> v158 NewMigration("ensure repo topics are up-to-date", fixRepoTopics), + // v158 -> v159 + NewMigration("code comment replies should have the commitID of the review they are replying to", updateCodeCommentReplies), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v158.go b/models/migrations/v158.go new file mode 100644 index 000000000000..a6f2178f8744 --- /dev/null +++ b/models/migrations/v158.go @@ -0,0 +1,110 @@ +// Copyright 2020 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 migrations + +import ( + "fmt" + "strconv" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func updateCodeCommentReplies(x *xorm.Engine) error { + type Comment struct { + ID int64 `xorm:"pk autoincr"` + CommitSHA string `xorm:"VARCHAR(40)"` + Patch string `xorm:"TEXT patch"` + Invalidated bool + + // Not extracted but used in the below query + Type int `xorm:"INDEX"` + Line int64 // - previous line / + proposed line + TreePath string + ReviewID int64 `xorm:"index"` + } + + if err := x.Sync2(new(Comment)); err != nil { + return err + } + + sqlSelect := `SELECT comment.id as id, first.commit_sha as commit_sha, first.patch as patch, first.invalidated as invalidated` + sqlTail := ` FROM comment INNER JOIN ( + SELECT C.id, C.review_id, C.line, C.tree_path, C.patch, C.commit_sha, C.invalidated + FROM comment AS C + WHERE C.type = 21 + AND C.created_unix = + (SELECT MIN(comment.created_unix) + FROM comment + WHERE comment.review_id = C.review_id + AND comment.type = 21 + AND comment.line = C.line + AND comment.tree_path = C.tree_path) + ) AS first + ON comment.review_id = first.review_id + AND comment.tree_path = first.tree_path AND comment.line = first.line + WHERE comment.type = 21 + AND comment.id != first.id + AND comment.commit_sha != first.commit_sha` + + var sqlCmd string + var start = 0 + var batchSize = 100 + sess := x.NewSession() + defer sess.Close() + for { + if err := sess.Begin(); err != nil { + return err + } + + if setting.Database.UseMSSQL { + if _, err := sess.Exec(sqlSelect + " INTO #temp_comments" + sqlTail); err != nil { + log.Error("unable to create temporary table") + return err + } + } + + var comments = make([]*Comment, 0, batchSize) + + switch { + case setting.Database.UseMySQL: + sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + ", " + strconv.Itoa(start) + case setting.Database.UsePostgreSQL: + fallthrough + case setting.Database.UseSQLite3: + sqlCmd = sqlSelect + sqlTail + " LIMIT " + strconv.Itoa(batchSize) + " OFFSET " + strconv.Itoa(start) + case setting.Database.UseMSSQL: + sqlCmd = "SELECT TOP " + strconv.Itoa(batchSize) + " * FROM #temp_comments WHERE " + + "(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id" + default: + return fmt.Errorf("Unsupported database type") + } + + if err := sess.SQL(sqlCmd).Find(&comments); err != nil { + log.Error("failed to select: %v", err) + return err + } + + for _, comment := range comments { + if _, err := sess.Table("comment").ID(comment.ID).Cols("commit_sha", "patch", "invalidated").Update(comment); err != nil { + log.Error("failed to update comment[%d]: %v %v", comment.ID, comment, err) + return err + } + } + + start += len(comments) + + if err := sess.Commit(); err != nil { + return err + } + if len(comments) < batchSize { + break + } + } + + return nil +} diff --git a/modules/references/references.go b/modules/references/references.go index 070c6e566a8e..6e0baefc6e1b 100644 --- a/modules/references/references.go +++ b/modules/references/references.go @@ -235,40 +235,78 @@ func findAllIssueReferencesMarkdown(content string) []*rawReference { return findAllIssueReferencesBytes(bcontent, links) } +func convertFullHTMLReferencesToShortRefs(re *regexp.Regexp, contentBytes *[]byte) { + // We will iterate through the content, rewrite and simplify full references. + // + // We want to transform something like: + // + // this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo + // https://ourgitea.com/git/owner/repo/pulls/123456789 + // + // Into something like: + // + // this is a #123456789, foo + // !123456789 + + pos := 0 + for { + // re looks for something like: (\s|^|\(|\[)https://ourgitea.com/git/(owner/repo)/(issues)/(123456789)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$) + match := re.FindSubmatchIndex((*contentBytes)[pos:]) + if match == nil { + break + } + // match is a bunch of indices into the content from pos onwards so + // to simplify things let's just add pos to all of the indices in match + for i := range match { + match[i] += pos + } + + // match[0]-match[1] is whole string + // match[2]-match[3] is preamble + + // move the position to the end of the preamble + pos = match[3] + + // match[4]-match[5] is owner/repo + // now copy the owner/repo to end of the preamble + endPos := pos + match[5] - match[4] + copy((*contentBytes)[pos:endPos], (*contentBytes)[match[4]:match[5]]) + + // move the current position to the end of the newly copied owner/repo + pos = endPos + + // Now set the issue/pull marker: + // + // match[6]-match[7] == 'issues' + (*contentBytes)[pos] = '#' + if string((*contentBytes)[match[6]:match[7]]) == "pulls" { + (*contentBytes)[pos] = '!' + } + pos++ + + // Then add the issue/pull number + // + // match[8]-match[9] is the number + endPos = pos + match[9] - match[8] + copy((*contentBytes)[pos:endPos], (*contentBytes)[match[8]:match[9]]) + + // Now copy what's left at the end of the string to the new end position + copy((*contentBytes)[endPos:], (*contentBytes)[match[9]:]) + // now we reset the length + + // our new section has length endPos - match[3] + // our old section has length match[9] - match[3] + (*contentBytes) = (*contentBytes)[:len((*contentBytes))-match[9]+endPos] + pos = endPos + } +} + // FindAllIssueReferences returns a list of unvalidated references found in a string. func FindAllIssueReferences(content string) []IssueReference { // Need to convert fully qualified html references to local system to #/! short codes contentBytes := []byte(content) if re := getGiteaIssuePullPattern(); re != nil { - pos := 0 - for { - match := re.FindSubmatchIndex(contentBytes[pos:]) - if match == nil { - break - } - // match[0]-match[1] is whole string - // match[2]-match[3] is preamble - pos += match[3] - // match[4]-match[5] is owner/repo - endPos := pos + match[5] - match[4] - copy(contentBytes[pos:endPos], contentBytes[match[4]:match[5]]) - pos = endPos - // match[6]-match[7] == 'issues' - contentBytes[pos] = '#' - if string(contentBytes[match[6]:match[7]]) == "pulls" { - contentBytes[pos] = '!' - } - pos++ - // match[8]-match[9] is the number - endPos = pos + match[9] - match[8] - copy(contentBytes[pos:endPos], contentBytes[match[8]:match[9]]) - copy(contentBytes[endPos:], contentBytes[match[9]:]) - // now we reset the length - // our new section has length endPos - match[3] - // our old section has length match[9] - match[3] - contentBytes = contentBytes[:len(contentBytes)-match[9]+endPos] - pos = endPos - } + convertFullHTMLReferencesToShortRefs(re, &contentBytes) } else { log.Debug("No GiteaIssuePullPattern pattern") } diff --git a/modules/references/references_test.go b/modules/references/references_test.go index 0c4037f1204a..f51379e4c332 100644 --- a/modules/references/references_test.go +++ b/modules/references/references_test.go @@ -5,6 +5,7 @@ package references import ( + "regexp" "testing" "code.gitea.io/gitea/modules/setting" @@ -29,6 +30,26 @@ type testResult struct { TimeLog string } +func TestConvertFullHTMLReferencesToShortRefs(t *testing.T) { + re := regexp.MustCompile(`(\s|^|\(|\[)` + + regexp.QuoteMeta("https://ourgitea.com/git/") + + `([0-9a-zA-Z-_\.]+/[0-9a-zA-Z-_\.]+)/` + + `((?:issues)|(?:pulls))/([0-9]+)(?:\s|$|\)|\]|[:;,.?!]\s|[:;,.?!]$)`) + test := `this is a https://ourgitea.com/git/owner/repo/issues/123456789, foo +https://ourgitea.com/git/owner/repo/pulls/123456789 + And https://ourgitea.com/git/owner/repo/pulls/123 +` + expect := `this is a owner/repo#123456789, foo +owner/repo!123456789 + And owner/repo!123 +` + + contentBytes := []byte(test) + convertFullHTMLReferencesToShortRefs(re, &contentBytes) + result := string(contentBytes) + assert.EqualValues(t, expect, result) +} + func TestFindAllIssueReferences(t *testing.T) { fixtures := []testFixture{ @@ -106,6 +127,13 @@ func TestFindAllIssueReferences(t *testing.T) { {202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""}, }, }, + { + "This http://gitea.com:3000/user4/repo5/pulls/202 yes. http://gitea.com:3000/user4/repo5/pulls/203 no", + []testResult{ + {202, "user4", "repo5", "202", true, XRefActionNone, nil, nil, ""}, + {203, "user4", "repo5", "203", true, XRefActionNone, nil, nil, ""}, + }, + }, { "This http://GiTeA.COM:3000/user4/repo6/pulls/205 yes.", []testResult{ diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index fb5a9d4d7068..cbdaf686d732 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -796,7 +796,7 @@ tree=Ağaç clear_ref='Geçerli referansı temizle' filter_branch_and_tag=Dal veya biçim imini filtrele branches=Dal -tags=Biçim İmleri +tags=Etiket issues=Konular pulls=Değişiklik İstekleri project_board=Projeler @@ -1055,7 +1055,7 @@ issues.context.edit=Düzenle issues.context.delete=Sil issues.no_content=Henüz bir içerik yok. issues.close_issue=Kapat -issues.pull_merged_at=`%[2]s işlemesini %[3]s %[4]s ile birleştirdi` +issues.pull_merged_at=`%[2]s işlemesini %[3]s ile %[4]s birleştirdi` issues.close_comment_issue=Yorum Yap ve Kapat issues.reopen_issue=Yeniden aç issues.reopen_comment_issue=Yorum Yap ve Yeniden Aç @@ -1144,8 +1144,8 @@ issues.due_date=Bitiş Tarihi issues.invalid_due_date_format=Bitiş tarihinin biçimi 'yyyy-aa-gg' olmalıdır. issues.error_modifying_due_date=Bitiş tarihi değiştirilemedi. issues.error_removing_due_date=Bitiş tarihi silinemedi. -issues.push_commit_1=%d %s işlemesi eklendi -issues.push_commits_n=%d %s işlemesi eklendi +issues.push_commit_1=%d işlemeyi %s ekledi +issues.push_commits_n=%d işlemeyi %s ekledi issues.force_push_codes=`%[1]s %[2]s konumundan %[4]s %[6]s konumuna zorla güncellendi` issues.due_date_form=yyyy-aa-gg issues.due_date_form_add=Bitiş tarihi ekle @@ -1221,7 +1221,7 @@ pulls.nothing_to_compare=Bu dallar eşit. Değişiklik isteği oluşturmaya gere pulls.has_pull_request=`Bu dallar arasında bir değişiklik isteği zaten var: %[2]s#%[3]d` pulls.create=Değişiklik İsteği Oluştur pulls.title_desc=%[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirmek istiyor -pulls.merged_title_desc=%[4]s %[2]s içindeki %[1]d işleme %[3]s ile birleştirdi +pulls.merged_title_desc=%[4]s %[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirdi pulls.change_target_branch_at='hedef dal %s adresinden %s%s adresine değiştirildi' pulls.tab_conversation=Sohbet pulls.tab_commits=İşleme @@ -1263,9 +1263,9 @@ pulls.no_merge_wip=Bu değişiklik isteği birleştirilemez çünkü devam eden pulls.no_merge_not_ready=Bu değişiklik isteği birleştirilmeye hazır değil, inceleme durumunu ve durum kontrollerini kontrol edin. pulls.no_merge_access=Bu değişiklik isteğini birleştirme yetkiniz yok. pulls.merge_pull_request=Değişiklik İsteğini Birleştir -pulls.rebase_merge_pull_request=Rebase ve Merge -pulls.rebase_merge_commit_pull_request=Rebase ve Merge (--no-ff) -pulls.squash_merge_pull_request=Squash ve Merge +pulls.rebase_merge_pull_request=Yeniden Yapılandır ve Birleştir +pulls.rebase_merge_commit_pull_request=Yeniden Yapılandır ve Birleştir (--no-ff) +pulls.squash_merge_pull_request=Ez ve Birleştir pulls.require_signed_wont_sign=Dal imzalı işlemeler gerektiriyor, ancak bu birleştirme imzalanmayacak pulls.invalid_merge_option=Bu değişiklik isteği için bu birleştirme seçeneğini kullanamazsınız. pulls.merge_conflict=Birleştirme Başarısız Oldu: Birleştirme sırasında bir çakışma oldu. İpucu: Farklı bir strateji deneyin @@ -1482,7 +1482,7 @@ settings.pulls.ignore_whitespace=Çakışmalar için Boşlukları Gözardı Et settings.pulls.allow_merge_commits=İşleme Birleştirmeyi Etkinleştir settings.pulls.allow_rebase_merge=İşlemeleri Birleştirmek için Yeniden Yapılandırmayı Etkinleştir settings.pulls.allow_rebase_merge_commit=Açık birleştirme işlemeleri ile Yeniden Yapılandırmayı Etkinleştir (--no-ff) -settings.pulls.allow_squash_commits=İşlemeleri Birleştirmek için Sıkmayı Etkinleştir +settings.pulls.allow_squash_commits=İşlemeleri Birleştirmek için Ezmeyi Etkinleştir settings.projects_desc=Depo Projelerini Etkinleştir settings.admin_settings=Yönetici Ayarları settings.admin_enable_health_check=Depo Sağlık Kontrollerini Etkinleştir (git fsck) diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index f96c2719df02..8d43e0a8cf92 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -820,6 +820,8 @@ audio_not_supported_in_browser=您的瀏覽器不支援 HTML5 'audio' 標籤 stored_lfs=已使用 Git LFS 儲存 symbolic_link=符號連結 commit_graph=提交線圖 +commit_graph.select=選擇分支 +commit_graph.hide_pr_refs=隱藏合併請求 commit_graph.monochrome=單色 commit_graph.color=彩色 blame=Blame diff --git a/services/pull/review.go b/services/pull/review.go index 99afdd73c215..f0ee234a4241 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -122,41 +122,76 @@ func createCodeComment(doer *models.User, repo *models.Repository, issue *models } defer gitRepo.Close() - // FIXME validate treePath - // Get latest commit referencing the commented line - // No need for get commit for base branch changes + invalidated := false + head := pr.GetGitRefName() if line > 0 { - commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line)) - if err == nil { - commitID = commit.ID.String() - } else if !(strings.Contains(err.Error(), "exit status 128 - fatal: no such path") || notEnoughLines.MatchString(err.Error())) { - return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err) + if reviewID != 0 { + first, err := models.FindComments(models.FindCommentsOptions{ + ReviewID: reviewID, + Line: line, + TreePath: treePath, + Type: models.CommentTypeCode, + ListOptions: models.ListOptions{ + PageSize: 1, + Page: 1, + }, + }) + if err == nil && len(first) > 0 { + commitID = first[0].CommitSHA + invalidated = first[0].Invalidated + patch = first[0].Patch + } else if err != nil && !models.IsErrCommentNotExist(err) { + return nil, fmt.Errorf("Find first comment for %d line %d path %s. Error: %v", reviewID, line, treePath, err) + } else { + review, err := models.GetReviewByID(reviewID) + if err == nil && len(review.CommitID) > 0 { + head = review.CommitID + } else if err != nil && !models.IsErrReviewNotExist(err) { + return nil, fmt.Errorf("GetReviewByID %d. Error: %v", reviewID, err) + } + } + } + + if len(commitID) == 0 { + // FIXME validate treePath + // Get latest commit referencing the commented line + // No need for get commit for base branch changes + commit, err := gitRepo.LineBlame(head, gitRepo.Path, treePath, uint(line)) + if err == nil { + commitID = commit.ID.String() + } else if !(strings.Contains(err.Error(), "exit status 128 - fatal: no such path") || notEnoughLines.MatchString(err.Error())) { + return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err) + } } } // Only fetch diff if comment is review comment - if reviewID != 0 { - headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) - if err != nil { - return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) + if len(patch) == 0 && reviewID != 0 { + if len(commitID) == 0 { + commitID, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) + if err != nil { + return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) + } } + patchBuf := new(bytes.Buffer) - if err := git.GetRepoRawDiffForFile(gitRepo, pr.MergeBase, headCommitID, git.RawDiffNormal, treePath, patchBuf); err != nil { - return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath) + if err := git.GetRepoRawDiffForFile(gitRepo, pr.MergeBase, commitID, git.RawDiffNormal, treePath, patchBuf); err != nil { + return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", gitRepo.Path, pr.MergeBase, commitID, treePath, err) } patch = git.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) } return models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeCode, - Doer: doer, - Repo: repo, - Issue: issue, - Content: content, - LineNum: line, - TreePath: treePath, - CommitSHA: commitID, - ReviewID: reviewID, - Patch: patch, + Type: models.CommentTypeCode, + Doer: doer, + Repo: repo, + Issue: issue, + Content: content, + LineNum: line, + TreePath: treePath, + CommitSHA: commitID, + ReviewID: reviewID, + Patch: patch, + Invalidated: invalidated, }) } diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index e960f7fe1751..1b102b11d883 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -37,7 +37,7 @@
- + {{svg "octicon-search" 16}}
*/}} diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index 9ef32d9e907a..a7eafa3874f3 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -18,7 +18,7 @@