Hook line history into cmd_log, ensuring a topo-ordered walk

To correctly track the line ranges over several branches,
we must make sure that we have processed all children before
reaching the commit itself.

Thus we introduce a first pass in cmd_line_log that runs
prepare_revision_walk to achieve the topological ordering.

Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Bo Yang
2010-08-11 23:03:35 +08:00
committed by Junio C Hamano
parent fdf5ea61f3
commit db26ae04da
4 changed files with 64 additions and 1 deletions

View File

@@ -615,7 +615,10 @@ int cmd_log(int argc, const char **argv, const char *prefix)
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
cmd_log_init(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
if (rev.line_level_traverse)
return cmd_line_log_walk(&rev);
else
return cmd_log_walk(&rev);
}
/* format-patch */

52
line.c
View File

@@ -1243,3 +1243,55 @@ static void line_log_flush(struct rev_info *rev, struct commit *c)
range = range->next;
}
}
int cmd_line_log_walk(struct rev_info *rev)
{
struct commit *commit;
struct commit_list *list = NULL;
struct diff_line_range *r = NULL;
if (prepare_revision_walk(rev))
die("revision walk prepare failed");
list = rev->commits;
if (list) {
list->item->object.flags |= RANGE_UPDATE;
list = list->next;
}
/* Clear the flags */
while (list) {
list->item->object.flags &= ~(RANGE_UPDATE | EVIL_MERGE | NEED_PRINT);
list = list->next;
}
list = rev->commits;
while (list) {
struct commit_list *need_free = list;
commit = list->item;
if (commit->object.flags & RANGE_UPDATE)
assign_parents_range(rev, commit);
if (commit->object.flags & NEED_PRINT)
line_log_flush(rev, commit);
r = lookup_line_range(rev, commit);
if (r) {
cleanup(r);
r = NULL;
add_line_range(rev, commit, r);
}
r = lookup_decoration(&rev->nontrivial_merge, &commit->object);
if (r) {
cleanup(r);
r = NULL;
add_decoration(&rev->nontrivial_merge, &commit->object, r);
}
list = list->next;
free(need_free);
}
return 0;
}

2
line.h
View File

@@ -134,4 +134,6 @@ extern struct diff_line_range *lookup_line_range(struct rev_info *revs,
const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
void *data, long lines, long begin, long *ret);
extern int cmd_line_log_walk(struct rev_info *rev);
#endif

View File

@@ -1637,6 +1637,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
if (revs->combine_merges)
revs->ignore_merges = 0;
revs->diffopt.abbrev = revs->abbrev;
if (revs->line_level_traverse) {
revs->limited = 1;
revs->topo_order = 1;
}
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");