Skip to content

Commit 7469e79

Browse files
committed
fix(pull): handle empty pull request files view to allow reviews (#37783)
Backport #37783. Manually adapted for the pre-refactor pull view code (preparePullViewPullInfo / MergeBase).
1 parent a34eac5 commit 7469e79

2 files changed

Lines changed: 54 additions & 34 deletions

File tree

routers/web/repo/pull.go

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ func indexCommit(commits []*git.Commit, commitID string) *git.Commit {
714714

715715
// ViewPullFiles render pull request changed files list page
716716
func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) {
717+
var err error
718+
717719
ctx.Data["PageIsPullList"] = true
718720
ctx.Data["PageIsPullFiles"] = true
719721

@@ -740,43 +742,53 @@ func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) {
740742
}
741743

742744
isSingleCommit := beforeCommitID == "" && afterCommitID != ""
743-
ctx.Data["IsShowingOnlySingleCommit"] = isSingleCommit
745+
// FIXME: when afterCommitID==headCommitID, isSingleCommit and isShowAllCommits can be both true, which doesn't seem right
744746
isShowAllCommits := (beforeCommitID == "" || beforeCommitID == prInfo.MergeBase) && (afterCommitID == "" || afterCommitID == headCommitID)
747+
748+
ctx.Data["IsShowingOnlySingleCommit"] = isSingleCommit
745749
ctx.Data["IsShowingAllCommits"] = isShowAllCommits
746750

747-
if afterCommitID == "" || afterCommitID == headCommitID {
748-
afterCommitID = headCommitID
749-
}
751+
// "commits list" is half-open, half-closed: (base, head]
752+
// * base commit is not in the list
753+
// * if the PR is empty, the list is also empty (head commit is not in the list)
754+
755+
afterCommitID = util.IfZero(afterCommitID, headCommitID)
750756
afterCommit := indexCommit(prInfo.Commits, afterCommitID)
757+
if afterCommit == nil && afterCommitID == headCommitID {
758+
afterCommit, err = gitRepo.GetCommit(afterCommitID)
759+
if err != nil {
760+
ctx.ServerError("GetCommit(afterCommitID)", err)
761+
return
762+
}
763+
}
751764
if afterCommit == nil {
752-
ctx.HTTPError(http.StatusBadRequest, "after commit not found in PR commits")
765+
ctx.NotFound(nil)
753766
return
754767
}
755768

756769
var beforeCommit *git.Commit
757-
if !isSingleCommit {
758-
if beforeCommitID == "" || beforeCommitID == prInfo.MergeBase {
759-
beforeCommitID = prInfo.MergeBase
770+
if isSingleCommit {
771+
beforeCommit, err = afterCommit.Parent(0)
772+
if err != nil {
773+
ctx.ServerError("afterCommit.Parent", err)
774+
return
775+
}
776+
beforeCommitID = beforeCommit.ID.String()
777+
} else {
778+
beforeCommitID = util.IfZero(beforeCommitID, prInfo.MergeBase)
779+
beforeCommit = indexCommit(prInfo.Commits, beforeCommitID)
780+
if beforeCommit == nil && beforeCommitID == prInfo.MergeBase {
760781
// mergebase commit is not in the list of the pull request commits
761782
beforeCommit, err = gitRepo.GetCommit(beforeCommitID)
762783
if err != nil {
763-
ctx.ServerError("GetCommit", err)
784+
ctx.ServerError("GetCommit(beforeCommitID)", err)
764785
return
765786
}
766-
} else {
767-
beforeCommit = indexCommit(prInfo.Commits, beforeCommitID)
768-
if beforeCommit == nil {
769-
ctx.HTTPError(http.StatusBadRequest, "before commit not found in PR commits")
770-
return
771-
}
772-
}
773-
} else {
774-
beforeCommit, err = afterCommit.Parent(0)
775-
if err != nil {
776-
ctx.ServerError("Parent", err)
777-
return
778787
}
779-
beforeCommitID = beforeCommit.ID.String()
788+
}
789+
if beforeCommit == nil {
790+
ctx.NotFound(nil)
791+
return
780792
}
781793

782794
ctx.Data["Username"] = ctx.Repo.Owner.Name

tests/integration/pull_status_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,21 +141,29 @@ func TestPullCreate_EmptyChangesWithDifferentCommits(t *testing.T) {
141141
func TestPullCreate_EmptyChangesWithSameCommits(t *testing.T) {
142142
onGiteaRun(t, func(t *testing.T, u *url.URL) {
143143
session := loginUser(t, "user1")
144-
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
145-
testCreateBranch(t, session, "user1", "repo1", "branch/master", "status1", http.StatusSeeOther)
146-
url := path.Join("user1", "repo1", "compare", "master...status1")
147-
req := NewRequestWithValues(t, "POST", url,
148-
map[string]string{
149-
"title": "pull request from status1",
150-
},
151-
)
152-
session.MakeRequest(t, req, http.StatusOK)
153-
req = NewRequest(t, "GET", "/user1/repo1/pulls/1")
154-
resp := session.MakeRequest(t, req, http.StatusOK)
155-
doc := NewHTMLParser(t, resp.Body)
156144

145+
testCreateBranch(t, session, "user2", "repo1", "branch/master", "empty-pr-branch", http.StatusSeeOther)
146+
resp := testPullCreateDirectly(t, session, createPullRequestOptions{
147+
BaseRepoOwner: "user2",
148+
BaseRepoName: "repo1",
149+
BaseBranch: "master",
150+
HeadBranch: "empty-pr-branch",
151+
Title: "empty pr test",
152+
})
153+
prURL := test.RedirectURL(resp)
154+
155+
// check the "merge box" text
156+
req := NewRequest(t, "GET", prURL)
157+
resp = session.MakeRequest(t, req, http.StatusOK)
158+
doc := NewHTMLParser(t, resp.Body)
157159
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
158160
assert.Contains(t, text, "This branch is already included in the target branch. There is nothing to merge.")
161+
162+
// check the "files" tab content
163+
req = NewRequest(t, "GET", prURL+"/files")
164+
resp = session.MakeRequest(t, req, http.StatusOK)
165+
doc = NewHTMLParser(t, resp.Body)
166+
assert.Equal(t, "Diff Content Not Available", strings.TrimSpace(doc.Find("#diff-container").Text()))
159167
})
160168
}
161169

0 commit comments

Comments
 (0)