Re: [RFC PATCH 5/5] t: add t9930-delta-islands.sh

2018-07-24 Thread Jeff King
On Sun, Jul 22, 2018 at 07:48:36AM +0200, Christian Couder wrote:

> From: Jeff King 
> 
> Signed-off-by: Jeff King 
> Signed-off-by: Christian Couder 
> ---
>  t/t9930-delta-islands.sh | 143 +++

For topics that I'm not immediately sending upstream, I usually stick
them in the t99xx range, so they don't conflict with upstream tests. But
for upstream, this should probably be in the t53xx range.

-Peff


[RFC PATCH 5/5] t: add t9930-delta-islands.sh

2018-07-21 Thread Christian Couder
From: Jeff King 

Signed-off-by: Jeff King 
Signed-off-by: Christian Couder 
---
 t/t9930-delta-islands.sh | 143 +++
 1 file changed, 143 insertions(+)
 create mode 100755 t/t9930-delta-islands.sh

diff --git a/t/t9930-delta-islands.sh b/t/t9930-delta-islands.sh
new file mode 100755
index 00..fea92a5777
--- /dev/null
+++ b/t/t9930-delta-islands.sh
@@ -0,0 +1,143 @@
+#!/bin/sh
+
+test_description='exercise delta islands'
+. ./test-lib.sh
+
+# returns true iff $1 is a delta based on $2
+is_delta_base () {
+   delta_base=$(echo "$1" | git cat-file --batch-check='%(deltabase)') &&
+   echo >&2 "$1 has base $delta_base" &&
+   test "$delta_base" = "$2"
+}
+
+# generate a commit on branch $1 with a single file, "file", whose
+# content is mostly based on the seed $2, but with a unique bit
+# of content $3 appended. This should allow us to see whether
+# blobs of different refs delta against each other.
+commit() {
+   blob=$({ test-tool genrandom "$2" 10240 && echo "$3"; } |
+  git hash-object -w --stdin) &&
+   tree=$(printf '100644 blob %s\tfile\n' "$blob" | git mktree) &&
+   commit=$(echo "$2-$3" | git commit-tree "$tree" ${4:+-p "$4"}) &&
+   git update-ref "refs/heads/$1" "$commit" &&
+   eval "$1"'=$(git rev-parse $1:file)' &&
+   eval "echo >&2 $1=\$$1"
+}
+
+test_expect_success 'setup commits' '
+   commit one seed 1 &&
+   commit two seed 12
+'
+
+# Note: This is heavily dependent on the "prefer larger objects as base"
+# heuristic.
+test_expect_success 'vanilla repack deltas one against two' '
+   git repack -adf &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'island repack with no island definition is vanilla' '
+   git repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'island repack with no matches is vanilla' '
+   git -c "pack.island=refs/foo" repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'separate islands disallows delta' '
+   git -c "pack.island=refs/heads/(.*)" repack -adfi &&
+   ! is_delta_base $one $two &&
+   ! is_delta_base $two $one
+'
+
+test_expect_success 'same island allows delta' '
+   git -c "pack.island=refs/heads" repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'coalesce same-named islands' '
+   git \
+   -c "pack.island=refs/(.*)/one" \
+   -c "pack.island=refs/(.*)/two" \
+   repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'island restrictions drop reused deltas' '
+   git repack -adfi &&
+   is_delta_base $one $two &&
+   git -c "pack.island=refs/heads/(.*)" repack -adi &&
+   ! is_delta_base $one $two &&
+   ! is_delta_base $two $one
+'
+
+test_expect_success 'island regexes are left-anchored' '
+   git -c "pack.island=heads/(.*)" repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'island regexes follow last-one-wins scheme' '
+   git \
+   -c "pack.island=refs/heads/(.*)" \
+   -c "pack.island=refs/heads/" \
+   repack -adfi &&
+   is_delta_base $one $two
+'
+
+test_expect_success 'setup shared history' '
+   commit root shared root &&
+   commit one shared 1 root &&
+   commit two shared 12-long root
+'
+
+# We know that $two will be preferred as a base from $one,
+# because we can transform it with a pure deletion.
+#
+# We also expect $root as a delta against $two by the "longest is base" rule.
+test_expect_success 'vanilla delta goes between branches' '
+   git repack -adf &&
+   is_delta_base $one $two &&
+   is_delta_base $root $two
+'
+
+# Here we should allow $one to base itself on $root; even though
+# they are in different islands, the objects in $root are in a superset
+# of islands compared to those in $one.
+#
+# Similarly, $two can delta against $root by our rules. And unlike $one,
+# in which we are just allowing it, the island rules actually put $root
+# as a possible base for $two, which it would not otherwise be (due to the size
+# sorting).
+test_expect_success 'deltas allowed against superset islands' '
+   git -c "pack.island=refs/heads/(.*)" repack -adfi &&
+   is_delta_base $one $root &&
+   is_delta_base $two $root
+'
+
+# We are going to test the packfile order here, so we again have to make some
+# assumptions. We assume that "$root", as part of our core "one", must come
+# before "$two". This should be guaranteed by the island code. However, for
+# this test to fail without islands, we are also assuming that it would not
+# otherwise do so. This is true by the current write order, which will put
+# commits (and their contents) before their parents.
+test_expect_success 'island core places core objects first' '
+   cat >expect <<-EOF &&
+   $root
+   $two
+   EOF
+   git -c "pack.island=refs/heads/(.*)" \
+   -c