#include "revision.h"
#include "xdiff-interface.h"
#include "strbuf.h"
-#include "log-tree.h"
#include "line-log.h"
#include "setup.h"
#include "strvec.h"
return changed;
}
-int line_log_print(struct rev_info *rev, struct commit *commit)
+void line_log_queue_pairs(struct rev_info *rev, struct commit *commit)
{
- show_log(rev);
- if (!(rev->diffopt.output_format & DIFF_FORMAT_NO_OUTPUT)) {
- struct line_log_data *range = lookup_line_range(rev, commit);
- struct line_log_data *r;
- const char *prefix = diff_line_prefix(&rev->diffopt);
-
- fprintf(rev->diffopt.file, "%s\n", prefix);
-
- for (r = range; r; r = r->next) {
- if (r->pair) {
- struct diff_filepair *p =
- diff_filepair_dup(r->pair);
- p->line_ranges = &r->ranges;
- diff_q(&diff_queued_diff, p);
- }
- }
+ struct line_log_data *range = lookup_line_range(rev, commit);
+ struct line_log_data *r;
- diffcore_std(&rev->diffopt);
- diff_flush(&rev->diffopt);
+ for (r = range; r; r = r->next) {
+ if (r->pair) {
+ struct diff_filepair *p = diff_filepair_dup(r->pair);
+ p->line_ranges = &r->ranges;
+ diff_q(&diff_queued_diff, p);
+ }
}
- return 1;
}
static int bloom_filter_check(struct rev_info *rev,
if (!all_need_diff && !opt->merges_need_diff)
return 0;
+ if (opt->line_level_traverse) {
+ line_log_queue_pairs(opt, commit);
+ log_tree_diff_flush(opt);
+ return !opt->loginfo;
+ }
+
parse_commit_or_die(commit);
oid = get_commit_tree_oid(commit);
opt->loginfo = &log;
opt->diffopt.no_free = 1;
- /* NEEDSWORK: no restoring of no_free? Why? */
- if (opt->line_level_traverse)
- return line_log_print(opt, commit);
-
if (opt->track_linear && !opt->linear && !opt->reverse_output_stage)
fprintf(opt->diffopt.file, "\n%s\n", opt->break_bar);
shown = log_tree_diff(opt, commit, &log);
test_expect_success '-L with --word-diff' '
cat >expect <<-\EOF &&
-
diff --git a/file.c b/file.c
--- a/file.c
+++ b/file.c
{
return [-F2;-]{+F2 + 2;+}
}
-
diff --git a/file.c b/file.c
new file mode 100644
--- /dev/null
null_blob=$(test_oid zero | cut -c1-7) &&
qz_to_tab_space >expect <<-EOF &&
* $head_oid Modify func2() in file.c
- |Z
| diff --git a/file.c b/file.c
| index $head_blob_old..$head_blob_new 100644
| --- a/file.c
| + return F2 + 2;
| }
* $root_oid Add func1() and func2() in file.c
- ZZ
diff --git a/file.c b/file.c
new file mode 100644
index $null_blob..$root_blob
--find-object=$(git rev-parse HEAD:file) >actual
'
-# Commit-level filtering with pickaxe does not yet work for -L.
-# show_log() prints the commit header before diffcore_std() runs
-# pickaxe, so commits cannot be suppressed even when no diff pairs
-# survive filtering. Fixing this would require deferring show_log()
-# until after diffcore_std(), which is a larger restructuring of the
-# log-tree output pipeline.
-test_expect_failure '-L -G should filter commits by pattern' '
+test_expect_success '-L -G should filter commits by pattern' '
git log --format="%s" --no-patch -L 1,1:file -G "nomatch" >actual &&
test_must_be_empty actual
'
-test_expect_failure '-L -S should filter commits by pattern' '
+test_expect_success '-L -S should filter commits by pattern' '
git log --format="%s" --no-patch -L 1,1:file -S "nomatch" >actual &&
test_must_be_empty actual
'
-test_expect_failure '-L --find-object should filter commits by object' '
+test_expect_success '-L --find-object should filter commits by object' '
git log --format="%s" --no-patch -L 1,1:file \
--find-object=$ZERO_OID >actual &&
test_must_be_empty actual
grep "F2 + 2" actual
'
+test_expect_success '-L with --diff-filter=M excludes root commit' '
+ git checkout parent-oids &&
+ git log -L:func2:file.c --diff-filter=M --format=%s --no-patch >actual &&
+ # Root commit is an Add (A), not a Modify (M), so it should
+ # be excluded; only the modification commit remains.
+ echo "Modify func2() in file.c" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '-L with --diff-filter=A shows only root commit' '
+ git checkout parent-oids &&
+ git log -L:func2:file.c --diff-filter=A --format=%s --no-patch >actual &&
+ echo "Add func1() and func2() in file.c" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '-L with -S suppresses non-matching commits' '
+ git checkout parent-oids &&
+ git log -L:func2:file.c -S "F2 + 2" --format=%s --no-patch >actual &&
+ # Only the commit that changes the count of "F2 + 2" should appear.
+ echo "Modify func2() in file.c" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--full-diff is not yet supported with -L' '
+ test_must_fail git log -L1,24:b.c --full-diff 2>err &&
+ test_grep "does not yet support" err
+'
+
+test_expect_success '-L --oneline has no extra blank line before diff' '
+ git checkout parent-oids &&
+ git log --oneline -L:func2:file.c -1 >actual &&
+ # Oneline header on line 1, diff starts immediately on line 2
+ sed -n 2p actual >line2 &&
+ test_grep "^diff --git" line2
+'
+
test_done