@@ -376,7 +376,7 @@ fn compute_diff3(mine: &[u8], older: &[u8], yours: &[u8], params: &Diff3Params)
376376 let diff_older_yours: Vec < _ > = diff:: slice ( older_lines, yours_lines) ;
377377 let diff_mine_yours: Vec < _ > = diff:: slice ( mine_lines, yours_lines) ;
378378
379- let has_conflicts = detect_conflicts (
379+ let _has_conflicts = detect_conflicts (
380380 & diff_mine_older,
381381 & diff_older_yours,
382382 & diff_mine_yours,
@@ -395,6 +395,61 @@ fn compute_diff3(mine: &[u8], older: &[u8], yours: &[u8], params: &Diff3Params)
395395 yours_lines,
396396 ) ;
397397
398+ // Determine the appropriate exit code based on format and output mode
399+ let should_report_conflict = match params. format {
400+ Diff3Format :: Ed => {
401+ // -e mode: conflicts are auto-resolved by choosing "yours", so return 0
402+ // unless we're in ShowOverlapEd mode which needs manual resolution
403+ match params. output_mode {
404+ Diff3OutputMode :: ShowOverlapEd => {
405+ // -E mode: return 1 if there are overlapping conflicts
406+ regions
407+ . iter ( )
408+ . any ( |r| r. conflict == ConflictType :: OverlappingConflict )
409+ }
410+ _ => false , // -e mode always succeeds
411+ }
412+ }
413+ Diff3Format :: ShowOverlap => {
414+ // -E mode: return 1 if there are overlapping conflicts
415+ regions
416+ . iter ( )
417+ . any ( |r| r. conflict == ConflictType :: OverlappingConflict )
418+ }
419+ Diff3Format :: Normal => {
420+ // Normal format: return 1 only if both sides changed differently
421+ match params. output_mode {
422+ Diff3OutputMode :: EasyOnly => {
423+ // -3: showing easy conflicts doesn't count as failure (exit 0)
424+ false
425+ }
426+ Diff3OutputMode :: OverlapOnly | Diff3OutputMode :: OverlapOnlyMarked => {
427+ // -x or -X: return 1 if there are overlapping conflicts
428+ regions
429+ . iter ( )
430+ . any ( |r| r. conflict == ConflictType :: OverlappingConflict )
431+ }
432+ _ => {
433+ // Default: return 1 only if there are overlapping conflicts
434+ // (both sides changed differently)
435+ regions
436+ . iter ( )
437+ . any ( |r| r. conflict == ConflictType :: OverlappingConflict )
438+ }
439+ }
440+ }
441+ Diff3Format :: Merged => {
442+ // Merged format: return 1 if there are ANY conflicts needing resolution
443+ // This includes both easy conflicts (one side changed) and overlapping (both changed)
444+ regions. iter ( ) . any ( |r| {
445+ matches ! (
446+ r. conflict,
447+ ConflictType :: EasyConflict | ConflictType :: OverlappingConflict
448+ )
449+ } )
450+ }
451+ } ;
452+
398453 match params. format {
399454 Diff3Format :: Normal => (
400455 generate_normal_output (
@@ -407,7 +462,7 @@ fn compute_diff3(mine: &[u8], older: &[u8], yours: &[u8], params: &Diff3Params)
407462 & regions,
408463 params,
409464 ) ,
410- has_conflicts ,
465+ should_report_conflict ,
411466 ) ,
412467 Diff3Format :: Merged => (
413468 generate_merged_output (
@@ -420,7 +475,7 @@ fn compute_diff3(mine: &[u8], older: &[u8], yours: &[u8], params: &Diff3Params)
420475 & regions,
421476 params,
422477 ) ,
423- has_conflicts ,
478+ should_report_conflict ,
424479 ) ,
425480 Diff3Format :: Ed | Diff3Format :: ShowOverlap => (
426481 generate_ed_script (
@@ -433,7 +488,7 @@ fn compute_diff3(mine: &[u8], older: &[u8], yours: &[u8], params: &Diff3Params)
433488 & regions,
434489 params,
435490 ) ,
436- has_conflicts ,
491+ should_report_conflict ,
437492 ) ,
438493 }
439494}
0 commit comments