Merge branch 'es/line-log-further-fixes' into tr/line-log
authorJunio C Hamano <gitster@pobox.com>
Tue, 23 Jul 2013 19:10:06 +0000 (12:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 23 Jul 2013 19:10:06 +0000 (12:10 -0700)
* 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

line-log.c
t/t4211-line-log.sh
t/t4211/expect.multiple-superset
index 4bbb09be59e561b519f63c3685fb790de9e70ded..c2d01dccc2a12a767c442de58ed78df130699d74 100644 (file)
@@ -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;
index 7776f93e3dfe1b6f822d5ee6f206bed5ba38c75c..00a850d61166aae6caaa61385b826cba73519b90 100755 (executable)
@@ -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
index a1f5bc49c879e427f132f86c98134d0564005709..d930b6eec4c46930c0190912f33be5b32eb6ff36 100644 (file)
@@ -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;
++}