@@ -248,10 +248,76 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
248248 return 0 ;
249249}
250250
251+ static int line_contains_alnum (const char * ptr , long size )
252+ {
253+ while (size -- )
254+ if (isalnum (* (ptr ++ )))
255+ return 1 ;
256+ return 0 ;
257+ }
258+
259+ static int lines_contain_alnum (xdfenv_t * xe , int i , int chg )
260+ {
261+ for (; chg ; chg -- , i ++ )
262+ if (line_contains_alnum (xe -> xdf2 .recs [i ]-> ptr ,
263+ xe -> xdf2 .recs [i ]-> size ))
264+ return 1 ;
265+ return 0 ;
266+ }
267+
268+ /*
269+ * This function merges m and m->next, marking everything between those hunks
270+ * as conflicting, too.
271+ */
272+ static void xdl_merge_two_conflicts (xdmerge_t * m )
273+ {
274+ xdmerge_t * next_m = m -> next ;
275+ m -> chg1 = next_m -> i1 + next_m -> chg1 - m -> i1 ;
276+ m -> chg2 = next_m -> i2 + next_m -> chg2 - m -> i2 ;
277+ m -> next = next_m -> next ;
278+ free (next_m );
279+ }
280+
281+ /*
282+ * If there are less than 3 non-conflicting lines between conflicts,
283+ * it appears simpler -- because it takes up less (or as many) lines --
284+ * if the lines are moved into the conflicts.
285+ */
286+ static int xdl_simplify_non_conflicts (xdfenv_t * xe1 , xdmerge_t * m ,
287+ int simplify_if_no_alnum )
288+ {
289+ int result = 0 ;
290+
291+ if (!m )
292+ return result ;
293+ for (;;) {
294+ xdmerge_t * next_m = m -> next ;
295+ int begin , end ;
296+
297+ if (!next_m )
298+ return result ;
299+
300+ begin = m -> i1 + m -> chg1 ;
301+ end = next_m -> i1 ;
302+
303+ if (m -> mode != 0 || next_m -> mode != 0 ||
304+ (end - begin > 3 &&
305+ (!simplify_if_no_alnum ||
306+ lines_contain_alnum (xe1 , begin , end - begin )))) {
307+ m = next_m ;
308+ } else {
309+ result ++ ;
310+ xdl_merge_two_conflicts (m );
311+ }
312+ }
313+ }
314+
251315/*
252316 * level == 0: mark all overlapping changes as conflict
253317 * level == 1: mark overlapping changes as conflict only if not identical
254318 * level == 2: analyze non-identical changes for minimal conflict set
319+ * level == 3: analyze non-identical changes for minimal conflict set, but
320+ * treat hunks not containing any letter or number as conflicting
255321 *
256322 * returns < 0 on error, == 0 for no conflicts, else number of conflicts
257323 */
@@ -355,7 +421,9 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
355421 if (!changes )
356422 changes = c ;
357423 /* refine conflicts */
358- if (level > 1 && xdl_refine_conflicts (xe1 , xe2 , changes , xpp ) < 0 ) {
424+ if (level > 1 &&
425+ (xdl_refine_conflicts (xe1 , xe2 , changes , xpp ) < 0 ||
426+ xdl_simplify_non_conflicts (xe1 , changes , level > 2 ) < 0 )) {
359427 xdl_cleanup_merge (changes );
360428 return -1 ;
361429 }
0 commit comments