@matheusbsbs / matheus-bagliano / commits / f35f5603f4
Fork 0

revision traversal: --children option

This adds a new --children option to the revision machinery. In addition to the list of parents, child commits of each commit are computed and stored as a decoration to each commit. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Apr 3, 2008 at 02:12 UTC f35f5603f4f07c939754743b2a6cf61bb3a4694e
2 files changed +38 -3
revision.c
+37 -3
@@ -9,6 +9,7 @@
9 #include "grep.h"
10 #include "reflog-walk.h"
11 #include "patch-ids.h"
12 +#include "decorate.h"
13
14 volatile show_early_output_fn_t show_early_output;
15
@@ -1310,6 +1311,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
1311 revs->no_walk = 0;
1312 continue;
1313 }
1314 + if (!strcmp(arg, "--children")) {
1315 + revs->children.name = "children";
1316 + revs->limited = 1;
1317 + continue;
1318 + }
1319
1320 opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
1321 if (opts > 0) {
@@ -1395,10 +1401,31 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
1401
1402 if (revs->reverse && revs->reflog_info)
1403 die("cannot combine --reverse with --walk-reflogs");
1398 -
1404 + if (revs->parents && revs->children.name)
1405 + die("cannot combine --parents and --children");
1406 return left;
1407 }
1408
1409 +static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
1410 +{
1411 + struct commit_list *l = xcalloc(1, sizeof(*l));
1412 +
1413 + l->item = child;
1414 + l->next = add_decoration(&revs->children, &parent->object, l);
1415 +}
1416 +
1417 +static void set_children(struct rev_info *revs)
1418 +{
1419 + struct commit_list *l;
1420 + for (l = revs->commits; l; l = l->next) {
1421 + struct commit *commit = l->item;
1422 + struct commit_list *p;
1423 +
1424 + for (p = commit->parents; p; p = p->next)
1425 + add_child(revs, p->item, commit);
1426 + }
1427 +}
1428 +
1429 int prepare_revision_walk(struct rev_info *revs)
1430 {
1431 int nr = revs->pending.nr;
@@ -1427,6 +1454,8 @@ int prepare_revision_walk(struct rev_info *revs)
1454 return -1;
1455 if (revs->topo_order)
1456 sort_in_topological_order(&revs->commits, revs->lifo);
1457 + if (revs->children.name)
1458 + set_children(revs);
1459 return 0;
1460 }
1461
@@ -1504,6 +1533,11 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
1533 commit->buffer, strlen(commit->buffer));
1534 }
1535
1536 +static inline int want_ancestry(struct rev_info *revs)
1537 +{
1538 + return (revs->parents || revs->children.name);
1539 +}
1540 +
1541 enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
1542 {
1543 if (commit->object.flags & SHOWN)
@@ -1524,13 +1558,13 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
1558 /* Commit without changes? */
1559 if (commit->object.flags & TREESAME) {
1560 /* drop merges unless we want parenthood */
1527 - if (!revs->parents)
1561 + if (!want_ancestry(revs))
1562 return commit_ignore;
1563 /* non-merge - always ignore it */
1564 if (!commit->parents || !commit->parents->next)
1565 return commit_ignore;
1566 }
1533 - if (revs->parents && rewrite_parents(revs, commit) < 0)
1567 + if (want_ancestry(revs) && rewrite_parents(revs, commit) < 0)
1568 return commit_error;
1569 }
1570 return commit_show;
revision.h
+1
@@ -98,6 +98,7 @@ struct rev_info {
98 struct diff_options pruning;
99
100 struct reflog_walk_info *reflog_info;
101 + struct decoration children;
102 };
103
104 #define REV_TREE_SAME 0