Pull request conflict files detection (#5951)
* add conflict detection * test pull request conflict files * fix detection files number * fix comments
This commit is contained in:
		
							parent
							
								
									680a57ce92
								
							
						
					
					
						commit
						bf4badad1d
					
				
					 4 changed files with 45 additions and 5 deletions
				
			
		|  | @ -54,9 +54,10 @@ const ( | |||
| 
 | ||||
| // PullRequest represents relation between pull request and repositories.
 | ||||
| type PullRequest struct { | ||||
| 	ID     int64 `xorm:"pk autoincr"` | ||||
| 	Type   PullRequestType | ||||
| 	Status PullRequestStatus | ||||
| 	ID              int64 `xorm:"pk autoincr"` | ||||
| 	Type            PullRequestType | ||||
| 	Status          PullRequestStatus | ||||
| 	ConflictedFiles []string `xorm:"TEXT JSON"` | ||||
| 
 | ||||
| 	IssueID int64  `xorm:"INDEX"` | ||||
| 	Issue   *Issue `xorm:"-"` | ||||
|  | @ -843,6 +844,7 @@ func (pr *PullRequest) testPatch(e Engine) (err error) { | |||
| 		args = append(args, "--ignore-whitespace") | ||||
| 	} | ||||
| 	args = append(args, patchPath) | ||||
| 	pr.ConflictedFiles = []string{} | ||||
| 
 | ||||
| 	_, stderr, err = process.GetManager().ExecDirEnv(-1, "", fmt.Sprintf("testPatch (git apply --check): %d", pr.BaseRepo.ID), | ||||
| 		[]string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()}, | ||||
|  | @ -851,8 +853,26 @@ func (pr *PullRequest) testPatch(e Engine) (err error) { | |||
| 		for i := range patchConflicts { | ||||
| 			if strings.Contains(stderr, patchConflicts[i]) { | ||||
| 				log.Trace("PullRequest[%d].testPatch (apply): has conflict", pr.ID) | ||||
| 				fmt.Println(stderr) | ||||
| 				const prefix = "error: patch failed:" | ||||
| 				pr.Status = PullRequestStatusConflict | ||||
| 				pr.ConflictedFiles = make([]string, 0, 5) | ||||
| 				scanner := bufio.NewScanner(strings.NewReader(stderr)) | ||||
| 				for scanner.Scan() { | ||||
| 					line := scanner.Text() | ||||
| 
 | ||||
| 					if strings.HasPrefix(line, prefix) { | ||||
| 						pr.ConflictedFiles = append(pr.ConflictedFiles, strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])) | ||||
| 					} | ||||
| 					// only list 10 conflicted files
 | ||||
| 					if len(pr.ConflictedFiles) >= 10 { | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				if len(pr.ConflictedFiles) > 0 { | ||||
| 					log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles) | ||||
| 				} | ||||
| 
 | ||||
| 				return nil | ||||
| 			} | ||||
| 		} | ||||
|  | @ -1375,7 +1395,7 @@ func (pr *PullRequest) checkAndUpdateStatus() { | |||
| 
 | ||||
| 	// Make sure there is no waiting test to process before leaving the checking status.
 | ||||
| 	if !pullRequestQueue.Exist(pr.ID) { | ||||
| 		if err := pr.UpdateCols("status"); err != nil { | ||||
| 		if err := pr.UpdateCols("status, conflicted_files"); err != nil { | ||||
| 			log.Error(4, "Update[%d]: %v", pr.ID, err) | ||||
| 		} | ||||
| 	} | ||||
|  | @ -1396,6 +1416,11 @@ func (pr *PullRequest) IsWorkInProgress() bool { | |||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // IsFilesConflicted determines if the  Pull Request has changes conflicting with the target branch.
 | ||||
| func (pr *PullRequest) IsFilesConflicted() bool { | ||||
| 	return len(pr.ConflictedFiles) > 0 | ||||
| } | ||||
| 
 | ||||
| // GetWorkInProgressPrefix returns the prefix used to mark the pull request as a work in progress.
 | ||||
| // It returns an empty string when none were found
 | ||||
| func (pr *PullRequest) GetWorkInProgressPrefix() string { | ||||
|  |  | |||
|  | @ -872,6 +872,7 @@ pulls.has_merged = The pull request has been merged. | |||
| pulls.title_wip_desc = `<a href="#">Start the title with <strong>%s</strong></a> to prevent the pull request from being merged accidentally.` | ||||
| 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 | ||||
| pulls.data_broken = This pull request is broken due to missing fork information. | ||||
| pulls.files_conflicted = This pull request has changes conflicting with the target branch. | ||||
| pulls.is_checking = "Merge conflict checking is in progress. Try again in few moments." | ||||
| pulls.blocked_by_approvals = "This Pull Request doesn't have enough approvals yet. %d of %d approvals granted." | ||||
| pulls.can_auto_merge_desc = This pull request can be merged automatically. | ||||
|  |  | |||
|  | @ -345,6 +345,11 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.PullReq | |||
| 		ctx.Data["WorkInProgressPrefix"] = pull.GetWorkInProgressPrefix() | ||||
| 	} | ||||
| 
 | ||||
| 	if pull.IsFilesConflicted() { | ||||
| 		ctx.Data["IsPullFilesConflicted"] = true | ||||
| 		ctx.Data["ConflictedFiles"] = pull.ConflictedFiles | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["NumCommits"] = prInfo.Commits.Len() | ||||
| 	ctx.Data["NumFiles"] = prInfo.NumFiles | ||||
| 	return prInfo | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ | |||
| 	{{if .Issue.PullRequest.HasMerged}}purple | ||||
| 	{{else if .Issue.IsClosed}}grey | ||||
| 	{{else if .IsPullWorkInProgress}}grey | ||||
| 	{{else if .IsFilesConflicted}}grey | ||||
| 	{{else if .IsPullRequestBroken}}red | ||||
| 	{{else if .IsBlockedByApprovals}}red | ||||
| 	{{else if .Issue.PullRequest.IsChecking}}yellow | ||||
|  | @ -59,6 +60,14 @@ | |||
| 				<div class="item text grey"> | ||||
| 					{{$.i18n.Tr "repo.pulls.reopen_to_merge"}} | ||||
| 				</div> | ||||
| 			{{else if .IsPullFilesConflicted}} | ||||
| 				<div class="item text grey"> | ||||
| 					<span class="octicon octicon-x"></span> | ||||
| 					{{$.i18n.Tr "repo.pulls.files_conflicted"}} | ||||
| 					{{range .ConflictedFiles}} | ||||
| 						<div>{{.}}</div> | ||||
| 					{{end}} | ||||
| 				</div> | ||||
| 			{{else if .IsPullRequestBroken}} | ||||
| 				<div class="item text red"> | ||||
| 					<span class="octicon octicon-x"></span> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue