Skip to content

Commit bf4bada

Browse files
lunnytechknowlogick
authored andcommitted
Pull request conflict files detection (#5951)
* add conflict detection * test pull request conflict files * fix detection files number * fix comments
1 parent 680a57c commit bf4bada

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

models/pull.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ const (
5454

5555
// PullRequest represents relation between pull request and repositories.
5656
type PullRequest struct {
57-
ID int64 `xorm:"pk autoincr"`
58-
Type PullRequestType
59-
Status PullRequestStatus
57+
ID int64 `xorm:"pk autoincr"`
58+
Type PullRequestType
59+
Status PullRequestStatus
60+
ConflictedFiles []string `xorm:"TEXT JSON"`
6061

6162
IssueID int64 `xorm:"INDEX"`
6263
Issue *Issue `xorm:"-"`
@@ -843,6 +844,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
843844
args = append(args, "--ignore-whitespace")
844845
}
845846
args = append(args, patchPath)
847+
pr.ConflictedFiles = []string{}
846848

847849
_, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID),
848850
[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()},
@@ -851,8 +853,26 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
851853
for i := range patchConflicts {
852854
if strings.Contains(stderr, patchConflicts[i]) {
853855
log.Trace("PullRequest[%d].testPatch (apply): has conflict", pr.ID)
854-
fmt.Println(stderr)
856+
const prefix = "error: patch failed:"
855857
pr.Status = PullRequestStatusConflict
858+
pr.ConflictedFiles = make([]string, 0, 5)
859+
scanner := bufio.NewScanner(strings.NewReader(stderr))
860+
for scanner.Scan() {
861+
line := scanner.Text()
862+
863+
if strings.HasPrefix(line, prefix) {
864+
pr.ConflictedFiles = append(pr.ConflictedFiles, strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0]))
865+
}
866+
// only list 10 conflicted files
867+
if len(pr.ConflictedFiles) >= 10 {
868+
break
869+
}
870+
}
871+
872+
if len(pr.ConflictedFiles) > 0 {
873+
log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles)
874+
}
875+
856876
return nil
857877
}
858878
}
@@ -1375,7 +1395,7 @@ func (pr *PullRequest) checkAndUpdateStatus() {
13751395

13761396
// Make sure there is no waiting test to process before leaving the checking status.
13771397
if !pullRequestQueue.Exist(pr.ID) {
1378-
if err := pr.UpdateCols("status"); err != nil {
1398+
if err := pr.UpdateCols("status, conflicted_files"); err != nil {
13791399
log.Error(4, "Update[%d]: %v", pr.ID, err)
13801400
}
13811401
}
@@ -1396,6 +1416,11 @@ func (pr *PullRequest) IsWorkInProgress() bool {
13961416
return false
13971417
}
13981418

1419+
// IsFilesConflicted determines if the Pull Request has changes conflicting with the target branch.
1420+
func (pr *PullRequest) IsFilesConflicted() bool {
1421+
return len(pr.ConflictedFiles) > 0
1422+
}
1423+
13991424
// GetWorkInProgressPrefix returns the prefix used to mark the pull request as a work in progress.
14001425
// It returns an empty string when none were found
14011426
func (pr *PullRequest) GetWorkInProgressPrefix() string {

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ pulls.has_merged = The pull request has been merged.
872872
pulls.title_wip_desc = `<a href="#">Start the title with <strong>%s</strong></a> to prevent the pull request from being merged accidentally.`
873873
pulls.cannot_merge_work_in_progress = This pull request is marked as a work in progress. Remove the <strong>%s</strong> prefix from the title when it's ready
874874
pulls.data_broken = This pull request is broken due to missing fork information.
875+
pulls.files_conflicted = This pull request has changes conflicting with the target branch.
875876
pulls.is_checking = "Merge conflict checking is in progress. Try again in few moments."
876877
pulls.blocked_by_approvals = "This Pull Request doesn't have enough approvals yet. %d of %d approvals granted."
877878
pulls.can_auto_merge_desc = This pull request can be merged automatically.

routers/repo/pull.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.PullReq
345345
ctx.Data["WorkInProgressPrefix"] = pull.GetWorkInProgressPrefix()
346346
}
347347

348+
if pull.IsFilesConflicted() {
349+
ctx.Data["IsPullFilesConflicted"] = true
350+
ctx.Data["ConflictedFiles"] = pull.ConflictedFiles
351+
}
352+
348353
ctx.Data["NumCommits"] = prInfo.Commits.Len()
349354
ctx.Data["NumFiles"] = prInfo.NumFiles
350355
return prInfo

templates/repo/issue/view_content/pull.tmpl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
{{if .Issue.PullRequest.HasMerged}}purple
3939
{{else if .Issue.IsClosed}}grey
4040
{{else if .IsPullWorkInProgress}}grey
41+
{{else if .IsFilesConflicted}}grey
4142
{{else if .IsPullRequestBroken}}red
4243
{{else if .IsBlockedByApprovals}}red
4344
{{else if .Issue.PullRequest.IsChecking}}yellow
@@ -59,6 +60,14 @@
5960
<div class="item text grey">
6061
{{$.i18n.Tr "repo.pulls.reopen_to_merge"}}
6162
</div>
63+
{{else if .IsPullFilesConflicted}}
64+
<div class="item text grey">
65+
<span class="octicon octicon-x"></span>
66+
{{$.i18n.Tr "repo.pulls.files_conflicted"}}
67+
{{range .ConflictedFiles}}
68+
<div>{{.}}</div>
69+
{{end}}
70+
</div>
6271
{{else if .IsPullRequestBroken}}
6372
<div class="item text red">
6473
<span class="octicon octicon-x"></span>

0 commit comments

Comments
 (0)