1045
} else if (!strcmp(arg, "--topo-order")) {
1046
revs->lifo = 1;
1047
revs->topo_order = 1;
1048
+ } else if (!strcmp(arg, "--simplify-merges")) {
1049
+ revs->simplify_merges = 1;
1050
+ revs->rewrite_parents = 1;
1051
+ revs->simplify_history = 0;
1052
+ revs->limited = 1;
1053
} else if (!strcmp(arg, "--date-order")) {
1054
revs->lifo = 0;
1055
revs->topo_order = 1;
1383
l->next = add_decoration(&revs->children, &parent->object, l);
1384
}
1385
1386
+static int remove_duplicate_parents(struct commit *commit)
1387
+{
1388
+ struct commit_list **pp, *p;
1389
+ int surviving_parents;
1390
+
1391
+ /* Examine existing parents while marking ones we have seen... */
1392
+ pp = &commit->parents;
1393
+ while ((p = *pp) != NULL) {
1394
+ struct commit *parent = p->item;
1395
+ if (parent->object.flags & TMP_MARK) {
1396
+ *pp = p->next;
1397
+ continue;
1398
+ }
1399
+ parent->object.flags |= TMP_MARK;
1400
+ pp = &p->next;
1401
+ }
1402
+ /* count them while clearing the temporary mark */
1403
+ surviving_parents = 0;
1404
+ for (p = commit->parents; p; p = p->next) {
1405
+ p->item->object.flags &= ~TMP_MARK;
1406
+ surviving_parents++;
1407
+ }
1408
+ return surviving_parents;
1409
+}
1410
+
1411
+static struct commit_list **simplify_one(struct commit *commit, struct commit_list **tail)
1412
+{
1413
+ struct commit_list *p;
1414
+ int cnt;
1415
+
1416
+ /*
1417
+ * We store which commit each one simplifies to in its util field.
1418
+ * Have we handled this one?
1419
+ */
1420
+ if (commit->util)
1421
+ return tail;
1422
+
1423
+ /*
1424
+ * An UNINTERESTING commit simplifies to itself, so does a
1425
+ * root commit. We do not rewrite parents of such commit
1426
+ * anyway.
1427
+ */
1428
+ if ((commit->object.flags & UNINTERESTING) || !commit->parents) {
1429
+ commit->util = commit;
1430
+ return tail;
1431
+ }
1432
+
1433
+ /*
1434
+ * Do we know what commit all of our parents should be rewritten to?
1435
+ * Otherwise we are not ready to rewrite this one yet.
1436
+ */
1437
+ for (cnt = 0, p = commit->parents; p; p = p->next) {
1438
+ if (!p->item->util) {
1439
+ tail = &commit_list_insert(p->item, tail)->next;
1440
+ cnt++;
1441
+ }
1442
+ }
1443
+ if (cnt)
1444
+ return tail;
1445
+
1446
+ /*
1447
+ * Rewrite our list of parents.
1448
+ */
1449
+ for (p = commit->parents; p; p = p->next)
1450
+ p->item = p->item->util;
1451
+ cnt = remove_duplicate_parents(commit);
1452
+
1453
+ /*
1454
+ * It is possible that we are a merge and one side branch
1455
+ * does not have any commit that touches the given paths;
1456
+ * in such a case, the immediate parents will be rewritten
1457
+ * to different commits.
1458
+ *
1459
+ * o----X X: the commit we are looking at;
1460
+ * / / o: a commit that touches the paths;
1461
+ * ---o----'
1462
+ *
1463
+ * Further reduce the parents by removing redundant parents.
1464
+ */
1465
+ if (1 < cnt) {
1466
+ struct commit_list *h = reduce_heads(commit->parents);
1467
+ cnt = commit_list_count(h);
1468
+ free_commit_list(commit->parents);
1469
+ commit->parents = h;
1470
+ }
1471
+
1472
+ /*
1473
+ * A commit simplifies to itself if it is a root, if it is
1474
+ * UNINTERESTING, if it touches the given paths, or if it is a
1475
+ * merge and its parents simplifies to more than one commits
1476
+ * (the first two cases are already handled at the beginning of
1477
+ * this function).
1478
+ *
1479
+ * Otherwise, it simplifies to what its sole parent simplifies to.
1480
+ */
1481
+ if (!cnt ||
1482
+ (commit->object.flags & UNINTERESTING) ||
1483
+ !(commit->object.flags & TREESAME) ||
1484
+ (1 < cnt))
1485
+ commit->util = commit;
1486
+ else
1487
+ commit->util = commit->parents->item->util;
1488
+ return tail;
1489
+}
1490
+
1491
+static void simplify_merges(struct rev_info *revs)
1492
+{
1493
+ struct commit_list *list;
1494
+ struct commit_list *yet_to_do, **tail;
1495
+
1496
+ /* feed the list reversed */
1497
+ yet_to_do = NULL;
1498
+ for (list = revs->commits; list; list = list->next)
1499
+ commit_list_insert(list->item, &yet_to_do);
1500
+ while (yet_to_do) {
1501
+ list = yet_to_do;
1502
+ yet_to_do = NULL;
1503
+ tail = &yet_to_do;
1504
+ while (list) {
1505
+ struct commit *commit = list->item;
1506
+ struct commit_list *next = list->next;
1507
+ free(list);
1508
+ list = next;
1509
+ tail = simplify_one(commit, tail);
1510
+ }
1511
+ }
1512
+
1513
+ /* clean up the result, removing the simplified ones */
1514
+ list = revs->commits;
1515
+ revs->commits = NULL;
1516
+ tail = &revs->commits;
1517
+ while (list) {
1518
+ struct commit *commit = list->item;
1519
+ struct commit_list *next = list->next;
1520
+ free(list);
1521
+ list = next;
1522
+ if (commit->util == commit)
1523
+ tail = &commit_list_insert(commit, tail)->next;
1524
+ }
1525
+
1526
+ /* sort topologically at the end */
1527
+ sort_in_topological_order(&revs->commits, revs->lifo);
1528
+}
1529
+
1530
static void set_children(struct rev_info *revs)
1531
{
1532
struct commit_list *l;
1567
return -1;
1568
if (revs->topo_order)
1569
sort_in_topological_order(&revs->commits, revs->lifo);
1570
+ if (revs->simplify_merges)
1571
+ simplify_merges(revs);
1572
if (revs->children.name)
1573
set_children(revs);
1574
return 0;
1601
}
1602
}
1603
1453
-static void remove_duplicate_parents(struct commit *commit)
1454
-{
1455
- struct commit_list **pp, *p;
1456
-
1457
- /* Examine existing parents while marking ones we have seen... */
1458
- pp = &commit->parents;
1459
- while ((p = *pp) != NULL) {
1460
- struct commit *parent = p->item;
1461
- if (parent->object.flags & TMP_MARK) {
1462
- *pp = p->next;
1463
- continue;
1464
- }
1465
- parent->object.flags |= TMP_MARK;
1466
- pp = &p->next;
1467
- }
1468
- /* ... and clear the temporary mark */
1469
- for (p = commit->parents; p; p = p->next)
1470
- p->item->object.flags &= ~TMP_MARK;
1471
-}
1472
-
1604
static int rewrite_parents(struct rev_info *revs, struct commit *commit)
1605
{
1606
struct commit_list **pp = &commit->parents;