mirror of
https://github.com/git/git.git
synced 2026-03-12 18:09:46 +01:00
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:
@@ -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
52
line.c
@@ -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
2
line.h
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user