Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that all unmerged files are merged when conflict checking (#20528) #20536

Merged
merged 2 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion services/pull/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func (e *errMergeConflict) Error() string {
}

func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, gitRepo *git.Repository) error {
log.Trace("Attempt to merge:\n%v", file)
switch {
case file.stage1 != nil && (file.stage2 == nil || file.stage3 == nil):
// 1. Deleted in one or both:
Expand Down Expand Up @@ -295,7 +296,8 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
var treeHash string
treeHash, _, err = git.NewCommand(ctx, "write-tree").RunStdString(&git.RunOpts{Dir: tmpBasePath})
if err != nil {
return false, err
lsfiles, _, _ := git.NewCommand(ctx, "ls-files", "-u").RunStdString(&git.RunOpts{Dir: tmpBasePath})
return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles)
}
treeHash = strings.TrimSpace(treeHash)
baseTree, err := gitRepo.GetTree("base")
Expand Down
25 changes: 24 additions & 1 deletion services/pull/patch_unmerged.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ func (line *lsFileLine) SameAs(other *lsFileLine) bool {
line.path == other.path
}

// String provides a string representation for logging
func (line *lsFileLine) String() string {
if line == nil {
return "<nil>"
}
if line.err != nil {
return fmt.Sprintf("%d %s %s %s %v", line.stage, line.mode, line.path, line.sha, line.err)
}
return fmt.Sprintf("%d %s %s %s", line.stage, line.mode, line.path, line.sha)
}

// readUnmergedLsFileLines calls git ls-files -u -z and parses the lines into mode-sha-stage-path quadruplets
// it will push these to the provided channel closing it at the end
func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan chan *lsFileLine) {
Expand Down Expand Up @@ -118,6 +129,17 @@ type unmergedFile struct {
err error
}

// String provides a string representation of the an unmerged file for logging
func (u *unmergedFile) String() string {
if u == nil {
return "<nil>"
}
if u.err != nil {
return fmt.Sprintf("error: %v\n%v\n%v\n%v", u.err, u.stage1, u.stage2, u.stage3)
}
return fmt.Sprintf("%v\n%v\n%v", u.stage1, u.stage2, u.stage3)
}

// unmergedFiles will collate the output from readUnstagedLsFileLines in to file triplets and send them
// to the provided channel, closing at the end.
func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmergedFile) {
Expand All @@ -138,6 +160,7 @@ func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmer

next := &unmergedFile{}
for line := range lsFileLineChan {
log.Trace("Got line: %v Current State:\n%v", line, next)
if line.err != nil {
log.Error("Unable to run ls-files -u -z! Error: %v", line.err)
unmerged <- &unmergedFile{err: fmt.Errorf("unable to run ls-files -u -z! Error: %v", line.err)}
Expand All @@ -149,7 +172,7 @@ func unmergedFiles(ctx context.Context, tmpBasePath string, unmerged chan *unmer
case 0:
// Should not happen as this represents successfully merged file - we will tolerate and ignore though
case 1:
if next.stage1 != nil {
if next.stage1 != nil || next.stage2 != nil || next.stage3 != nil {
// We need to handle the unstaged file stage1,stage2,stage3
unmerged <- next
}
Expand Down