aboutsummaryrefslogtreecommitdiffstats
path: root/services/pull/patch_unmerged.go
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2022-07-29 15:37:18 +0200
committerGitHub <noreply@github.com>2022-07-29 15:37:18 +0200
commit210b096da72acacbddc28d65f6ce2502772307f1 (patch)
treed78f8ea944c98296960491eec4a3d81fa49756ce /services/pull/patch_unmerged.go
parentd6bc1558c6e2d13e35925239efde4c6a687fbd79 (diff)
downloadgitea-210b096da72acacbddc28d65f6ce2502772307f1.tar.gz
gitea-210b096da72acacbddc28d65f6ce2502772307f1.zip
Ensure that all unmerged files are merged when conflict checking (#20528) (#20536)
There is a subtle bug in the code relating to collating the results of `git ls-files -u -z` in `unmergedFiles()`. The code here makes the mistake of assuming that every unmerged file will always have a stage 1 conflict, and this results in conflicts that occur in stage 3 only being dropped. This PR simply adjusts this code to ensure that any empty unmergedFile will always be passed down the channel. The PR also adds a lot of Trace commands to attempt to help find future bugs in this code. Fix #19527 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: zeripath <art27@cantab.net>
Diffstat (limited to 'services/pull/patch_unmerged.go')
-rw-r--r--services/pull/patch_unmerged.go25
1 files changed, 24 insertions, 1 deletions
diff --git a/services/pull/patch_unmerged.go b/services/pull/patch_unmerged.go
index 3839419142..465465d0da 100644
--- a/services/pull/patch_unmerged.go
+++ b/services/pull/patch_unmerged.go
@@ -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) {
@@ -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) {
@@ -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)}
@@ -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
}