summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2013-07-23 12:10:06 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2013-07-23 12:10:06 -0700
commitefc5e5ef8e467ebbdd4f93c23f2269b907fcdc15 (patch)
tree2e30481c590aa53020d8b6fe49c52729a0c803d7
parentgit-log(1): remove --full-line-diff description (diff)
parentline-log: fix "log -LN" crash when N is last line of file (diff)
downloadtgif-efc5e5ef8e467ebbdd4f93c23f2269b907fcdc15.tar.xz
Merge branch 'es/line-log-further-fixes' into tr/line-log
* es/line-log-further-fixes: line-log: fix "log -LN" crash when N is last line of file range-set: satisfy non-empty ranges invariant t4211: demonstrate crash when first -L encountered is empty range t4211: demonstrate empty -L range crash range-set: fix sort_and_merge_range_set() corner case bug range_set: fix coalescing bug when range is a subset of another t4211: fix broken test when one -L range is subset of another
-rw-r--r--line-log.c12
-rwxr-xr-xt/t4211-line-log.sh14
-rw-r--r--t/t4211/expect.multiple-superset134
3 files changed, 153 insertions, 7 deletions
diff --git a/line-log.c b/line-log.c
index 4bbb09be59..c2d01dccc2 100644
--- a/line-log.c
+++ b/line-log.c
@@ -110,13 +110,16 @@ static void range_set_check_invariants(struct range_set *rs)
static void sort_and_merge_range_set(struct range_set *rs)
{
int i;
- int o = 1; /* output cursor */
+ int o = 0; /* output cursor */
qsort(rs->ranges, rs->nr, sizeof(struct range), range_cmp);
- for (i = 1; i < rs->nr; i++) {
- if (rs->ranges[i].start <= rs->ranges[o-1].end) {
- rs->ranges[o-1].end = rs->ranges[i].end;
+ for (i = 0; i < rs->nr; i++) {
+ if (rs->ranges[i].start == rs->ranges[i].end)
+ continue;
+ if (o > 0 && rs->ranges[i].start <= rs->ranges[o-1].end) {
+ if (rs->ranges[o-1].end < rs->ranges[i].end)
+ rs->ranges[o-1].end = rs->ranges[i].end;
} else {
rs->ranges[o].start = rs->ranges[i].start;
rs->ranges[o].end = rs->ranges[i].end;
@@ -296,6 +299,7 @@ static void line_log_data_insert(struct line_log_data **list,
p = xcalloc(1, sizeof(struct line_log_data));
p->path = path;
range_set_append(&p->ranges, begin, end);
+ sort_and_merge_range_set(&p->ranges);
if (ip) {
p->next = ip->next;
ip->next = p;
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index 7776f93e3d..00a850d611 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -64,4 +64,18 @@ test_bad_opts "-L 1,1000:b.c" "has only.*lines"
test_bad_opts "-L :b.c" "argument.*not of the form"
test_bad_opts "-L :foo:b.c" "no match"
+# There is a separate bug when an empty -L range is the first -L encountered,
+# thus to demonstrate this particular bug, the empty -L range must follow a
+# non-empty -L range.
+test_expect_success '-L {empty-range} (any -L)' '
+ n=$(expr $(cat b.c | wc -l) + 1) &&
+ n=$(expr $(wc -l <b.c) + 1) &&
+ git log -L1,1:b.c -L$n:b.c
+'
+
+test_expect_success '-L {empty-range} (first -L)' '
+ n=$(expr $(wc -l <b.c) + 1) &&
+ git log -L$n:b.c
+'
+
test_done
diff --git a/t/t4211/expect.multiple-superset b/t/t4211/expect.multiple-superset
index a1f5bc49c8..d930b6eec4 100644
--- a/t/t4211/expect.multiple-superset
+++ b/t/t4211/expect.multiple-superset
@@ -1,3 +1,100 @@
+commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:43 2013 +0100
+
+ change back to complete line
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,21 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
+\ No newline at end of file
++}
++
++/* incomplete lines are bad! */
+
+commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:48:10 2013 +0100
+
+ change to an incomplete line at end
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -4,19 +4,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+-}
++}
+\ No newline at end of file
+
+commit 39b6eb2d5b706d3322184a169f666f25ed3fbd00
+Author: Thomas Rast <trast@student.ethz.ch>
+Date: Thu Feb 28 10:45:41 2013 +0100
+
+ touch comment
+
+diff --git a/a.c b/a.c
+--- a/a.c
++++ b/a.c
+@@ -3,19 +3,19 @@
+ long f(long x)
+ {
+ int s = 0;
+ while (x) {
+ x >>= 1;
+ s++;
+ }
+ return s;
+ }
+
+ /*
+- * A comment.
++ * This is only an example!
+ */
+
+ int main ()
+ {
+ printf("%ld\n", f(15));
+ return 0;
+ }
+
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
Author: Thomas Rast <trast@student.ethz.ch>
Date: Thu Feb 28 10:45:16 2013 +0100
@@ -7,7 +104,7 @@ Date: Thu Feb 28 10:45:16 2013 +0100
diff --git a/a.c b/a.c
--- a/a.c
+++ b/a.c
-@@ -3,9 +3,9 @@
+@@ -3,19 +3,19 @@
-int f(int x)
+long f(long x)
{
@@ -18,6 +115,17 @@ diff --git a/a.c b/a.c
}
return s;
}
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+- printf("%d\n", f(15));
++ printf("%ld\n", f(15));
+ return 0;
+ }
commit f04fb20f2c77850996cba739709acc6faecc58f7
Author: Thomas Rast <trast@student.ethz.ch>
@@ -28,7 +136,7 @@ Date: Thu Feb 28 10:44:55 2013 +0100
diff --git a/a.c b/a.c
--- a/a.c
+++ b/a.c
-@@ -3,8 +3,9 @@
+@@ -3,18 +3,19 @@
int f(int x)
{
int s = 0;
@@ -38,6 +146,16 @@ diff --git a/a.c b/a.c
}
+ return s;
}
+
+ /*
+ * A comment.
+ */
+
+ int main ()
+ {
+ printf("%d\n", f(15));
+ return 0;
+ }
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
Author: Thomas Rast <trast@student.ethz.ch>
@@ -48,7 +166,7 @@ Date: Thu Feb 28 10:44:48 2013 +0100
diff --git a/a.c b/a.c
--- /dev/null
+++ b/a.c
-@@ -0,0 +3,8 @@
+@@ -0,0 +3,18 @@
+int f(int x)
+{
+ int s = 0;
@@ -57,3 +175,13 @@ diff --git a/a.c b/a.c
+ s++;
+ }
+}
++
++/*
++ * A comment.
++ */
++
++int main ()
++{
++ printf("%d\n", f(15));
++ return 0;
++}