* Check for symmetric-difference arguments, and if present, arrange * everything we need to know to handle them correctly. As a bonus, * weed out all bogus range-based revision specifications, e.g., * "git diff A..B C..D" or "git diff A..B C" get rejected. * * For an actual symmetric diff, *symdiff is set this way: * * - its skip is non-NULL and marks *all* rev->pending.objects[i] * i
| 315 | * sym->warn is cleared. The remaining fields are not set. |
| 316 | */ |
| 317 | static void symdiff_prepare(struct rev_info *rev, struct symdiff *sym) |
| 318 | { |
| 319 | int i, is_symdiff = 0, basecount = 0, othercount = 0; |
| 320 | int lpos = -1, rpos = -1, basepos = -1; |
| 321 | struct bitmap *map = NULL; |
| 322 | |
| 323 | /* |
| 324 | * Use the whence fields to find merge bases and left and |
| 325 | * right parts of symmetric difference, so that we do not |
| 326 | * depend on the order that revisions are parsed. If there |
| 327 | * are any revs that aren't from these sources, we have a |
| 328 | * "git diff C A...B" or "git diff A...B C" case. Or we |
| 329 | * could even get "git diff A...B C...E", for instance. |
| 330 | * |
| 331 | * If we don't have just one merge base, we pick one |
| 332 | * at random. |
| 333 | * |
| 334 | * NB: REV_CMD_LEFT, REV_CMD_RIGHT are also used for A..B, |
| 335 | * so we must check for SYMMETRIC_LEFT too. The two arrays |
| 336 | * rev->pending.objects and rev->cmdline.rev are parallel. |
| 337 | */ |
| 338 | for (i = 0; i < rev->cmdline.nr; i++) { |
| 339 | struct object *obj = rev->pending.objects[i].item; |
| 340 | switch (rev->cmdline.rev[i].whence) { |
| 341 | case REV_CMD_MERGE_BASE: |
| 342 | if (basepos < 0) |
| 343 | basepos = i; |
| 344 | basecount++; |
| 345 | break; /* do mark all bases */ |
| 346 | case REV_CMD_LEFT: |
| 347 | if (lpos >= 0) |
| 348 | usage(builtin_diff_usage); |
| 349 | lpos = i; |
| 350 | if (obj->flags & SYMMETRIC_LEFT) { |
| 351 | is_symdiff = 1; |
| 352 | break; /* do mark A */ |
| 353 | } |
| 354 | continue; |
| 355 | case REV_CMD_RIGHT: |
| 356 | if (rpos >= 0) |
| 357 | usage(builtin_diff_usage); |
| 358 | rpos = i; |
| 359 | continue; /* don't mark B */ |
| 360 | case REV_CMD_PARENTS_ONLY: |
| 361 | case REV_CMD_REF: |
| 362 | case REV_CMD_REV: |
| 363 | othercount++; |
| 364 | continue; |
| 365 | } |
| 366 | if (!map) |
| 367 | map = bitmap_new(); |
| 368 | bitmap_set(map, i); |
| 369 | } |
| 370 | |
| 371 | /* |
| 372 | * Forbid any additional revs for both A...B and A..B. |
| 373 | */ |
| 374 | if (lpos >= 0 && othercount > 0) |
no test coverage detected