summaryrefslogtreecommitdiff
path: root/revision.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-06-09 01:06:26 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-06-09 01:06:26 (GMT)
commitc3a02824cf938597bbbe7c2487db2c712adf5651 (patch)
tree18dbea784f7efd61feeb6be49fe2e11d90149bfa /revision.c
parent20514004ddf1a3528de8933bc32f284e175e1012 (diff)
parentf32dde8c12d941065be848a9f66239df96bde216 (diff)
downloadgit-c3a02824cf938597bbbe7c2487db2c712adf5651.zip
git-c3a02824cf938597bbbe7c2487db2c712adf5651.tar.gz
git-c3a02824cf938597bbbe7c2487db2c712adf5651.tar.bz2
Merge branch 'ds/line-log-on-bloom'
"git log -L..." now takes advantage of the "which paths are touched by this commit?" info stored in the commit-graph system. * ds/line-log-on-bloom: line-log: integrate with changed-path Bloom filters line-log: try to use generation number-based topo-ordering line-log: more responsive, incremental 'git log -L' t4211-line-log: add tests for parent oids line-log: remove unused fields from 'struct line_log_data'
Diffstat (limited to 'revision.c')
-rw-r--r--revision.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/revision.c b/revision.c
index 60cca8c..ebb4d2a 100644
--- a/revision.c
+++ b/revision.c
@@ -39,6 +39,8 @@ static const char *term_good;
implement_shared_commit_slab(revision_sources, char *);
+static inline int want_ancestry(const struct rev_info *revs);
+
void show_object_with_name(FILE *out, struct object *obj, const char *name)
{
const char *p;
@@ -687,6 +689,9 @@ static void prepare_to_use_bloom_filter(struct rev_info *revs)
if (!revs->bloom_filter_settings)
return;
+ if (!revs->pruning.pathspec.nr)
+ return;
+
pi = &revs->pruning.pathspec.items[0];
last_index = pi->len - 1;
@@ -2810,6 +2815,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
if (revs->diffopt.objfind)
revs->simplify_history = 0;
+ if (revs->line_level_traverse) {
+ if (want_ancestry(revs))
+ revs->limited = 1;
+ revs->topo_order = 1;
+ }
+
if (revs->topo_order && !generation_numbers_enabled(the_repository))
revs->limited = 1;
@@ -2829,11 +2840,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
revs->diffopt.abbrev = revs->abbrev;
- if (revs->line_level_traverse) {
- revs->limited = 1;
- revs->topo_order = 1;
- }
-
diff_setup_done(&revs->diffopt);
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
@@ -3521,7 +3527,7 @@ int prepare_revision_walk(struct rev_info *revs)
FOR_EACH_OBJECT_PROMISOR_ONLY);
}
- if (revs->pruning.pathspec.nr == 1 && !revs->reflog_info)
+ if (!revs->reflog_info)
prepare_to_use_bloom_filter(revs);
if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED)
commit_list_sort_by_date(&revs->commits);
@@ -3534,7 +3540,14 @@ int prepare_revision_walk(struct rev_info *revs)
sort_in_topological_order(&revs->commits, revs->sort_order);
} else if (revs->topo_order)
init_topo_walk(revs);
- if (revs->line_level_traverse)
+ if (revs->line_level_traverse && want_ancestry(revs))
+ /*
+ * At the moment we can only do line-level log with parent
+ * rewriting by performing this expensive pre-filtering step.
+ * If parent rewriting is not requested, then we rather
+ * perform the line-level log filtering during the regular
+ * history traversal.
+ */
line_log_filter(revs);
if (revs->simplify_merges)
simplify_merges(revs);
@@ -3745,6 +3758,22 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
return commit_ignore;
if (commit->object.flags & UNINTERESTING)
return commit_ignore;
+ if (revs->line_level_traverse && !want_ancestry(revs)) {
+ /*
+ * In case of line-level log with parent rewriting
+ * prepare_revision_walk() already took care of all line-level
+ * log filtering, and there is nothing left to do here.
+ *
+ * If parent rewriting was not requested, then this is the
+ * place to perform the line-level log filtering. Notably,
+ * this check, though expensive, must come before the other,
+ * cheaper filtering conditions, because the tracked line
+ * ranges must be adjusted even when the commit will end up
+ * being ignored based on other conditions.
+ */
+ if (!line_log_process_ranges_arbitrary_commit(revs, commit))
+ return commit_ignore;
+ }
if (revs->min_age != -1 &&
comparison_date(revs, commit) > revs->min_age)
return commit_ignore;