248
return 0;
249
}
250
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.
283
* it appears simpler -- because it takes up less (or as many) lines --
284
* if the lines are moved into the conflicts.
285
*/
269
-static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m)
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
300
begin = m->i1 + m->chg1;
301
end = next_m->i1;
302
285
- if (m->mode != 0 || next_m->mode != 0 || end - begin > 3)
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;
287
- else {
308
+ } else {
309
result++;
310
xdl_merge_two_conflicts(m);
311
}
316
* level == 0: mark all overlapping changes as conflict
317
* level == 1: mark overlapping changes as conflict only if not identical
318
* 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
321
*
322
* returns < 0 on error, == 0 for no conflicts, else number of conflicts
323
*/
423
/* refine conflicts */
424
if (level > 1 &&
425
(xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 ||
403
- xdl_simplify_non_conflicts(xe1, changes) < 0)) {
426
+ xdl_simplify_non_conflicts(xe1, changes, level > 2) < 0)) {
427
xdl_cleanup_merge(changes);
428
return -1;
429
}