| 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2009, Red Hat Inc, Author: Michael S. Tsirkin (mst@redhat.com) |
| 4 | # |
| 5 | |
| 6 | test_description='test clone --reference' |
| 7 | |
| 8 | . ./test-lib.sh |
| 9 | |
| 10 | base_dir=$(pwd) |
| 11 | |
| 12 | test_alternate_is_used () { |
| 13 | alternates_file="$1" && |
| 14 | working_dir="$2" && |
| 15 | test_line_count = 1 "$alternates_file" && |
| 16 | echo "0 objects, 0 kilobytes" >expect && |
| 17 | git -C "$working_dir" count-objects >actual && |
| 18 | test_cmp expect actual |
| 19 | } |
| 20 | |
| 21 | test_expect_success 'setup' ' |
| 22 | git config --global protocol.file.allow always |
| 23 | ' |
| 24 | |
| 25 | test_expect_success 'preparing first repository' ' |
| 26 | test_create_repo A && |
| 27 | ( |
| 28 | cd A && |
| 29 | echo first >file1 && |
| 30 | git add file1 && |
| 31 | git commit -m A-initial |
| 32 | ) |
| 33 | ' |
| 34 | |
| 35 | test_expect_success 'preparing second repository' ' |
| 36 | git clone A B && |
| 37 | ( |
| 38 | cd B && |
| 39 | echo second >file2 && |
| 40 | git add file2 && |
| 41 | git commit -m B-addition && |
| 42 | git repack -a -d && |
| 43 | git prune |
| 44 | ) |
| 45 | ' |
| 46 | |
| 47 | test_expect_success 'preparing superproject' ' |
| 48 | test_create_repo super && |
| 49 | ( |
| 50 | cd super && |
| 51 | echo file >file && |
| 52 | git add file && |
| 53 | git commit -m B-super-initial |
| 54 | ) |
| 55 | ' |
| 56 | |
| 57 | test_expect_success 'submodule add --reference uses alternates' ' |
| 58 | ( |
| 59 | cd super && |
| 60 | git submodule add --reference ../B "file://$base_dir/A" sub && |
| 61 | git commit -m B-super-added && |
| 62 | git repack -ad |
| 63 | ) && |
| 64 | test_alternate_is_used super/.git/modules/sub/objects/info/alternates super/sub |
| 65 | ' |
| 66 | |
| 67 | test_expect_success 'submodule add --reference with --dissociate does not use alternates' ' |
| 68 | ( |
| 69 | cd super && |
| 70 | git submodule add --reference ../B --dissociate "file://$base_dir/A" sub-dissociate && |
| 71 | git commit -m B-super-added && |
| 72 | git repack -ad |
| 73 | ) && |
| 74 | test_path_is_missing super/.git/modules/sub-dissociate/objects/info/alternates |
| 75 | ' |
| 76 | |
| 77 | test_expect_success 'that reference gets used with add' ' |
| 78 | ( |
| 79 | cd super/sub && |
| 80 | echo "0 objects, 0 kilobytes" >expected && |
| 81 | git count-objects >current && |
| 82 | diff expected current |
| 83 | ) |
| 84 | ' |
| 85 | |
| 86 | # The tests up to this point, and repositories created by them |
| 87 | # (A, B, super and super/sub), are about setting up the stage |
| 88 | # for subsequent tests and meant to be kept throughout the |
| 89 | # remainder of the test. |
| 90 | # Tests from here on, if they create their own test repository, |
| 91 | # are expected to clean after themselves. |
| 92 | |
| 93 | test_expect_success 'updating superproject keeps alternates' ' |
| 94 | test_when_finished "rm -rf super-clone" && |
| 95 | git clone super super-clone && |
| 96 | git -C super-clone submodule update --init --reference ../B && |
| 97 | test_alternate_is_used super-clone/.git/modules/sub/objects/info/alternates super-clone/sub |
| 98 | ' |
| 99 | |
| 100 | test_expect_success 'updating superproject with --dissociate does not keep alternates' ' |
| 101 | test_when_finished "rm -rf super-clone" && |
| 102 | git clone super super-clone && |
| 103 | git -C super-clone submodule update --init --reference ../B --dissociate && |
| 104 | test_path_is_missing super-clone/.git/modules/sub/objects/info/alternates |
| 105 | ' |
| 106 | |
| 107 | test_expect_success 'submodules use alternates when cloning a superproject' ' |
| 108 | test_when_finished "rm -rf super-clone" && |
| 109 | git clone --reference super --recursive super super-clone && |
| 110 | ( |
| 111 | cd super-clone && |
| 112 | # test superproject has alternates setup correctly |
| 113 | test_alternate_is_used .git/objects/info/alternates . && |
| 114 | # test submodule has correct setup |
| 115 | test_alternate_is_used .git/modules/sub/objects/info/alternates sub |
| 116 | ) |
| 117 | ' |
| 118 | |
| 119 | test_expect_success 'missing submodule alternate fails clone and submodule update' ' |
| 120 | test_when_finished "rm -rf super-clone" && |
| 121 | git clone super super2 && |
| 122 | test_must_fail git clone --recursive --reference super2 super2 super-clone && |
| 123 | ( |
| 124 | cd super-clone && |
| 125 | # test superproject has alternates setup correctly |
| 126 | test_alternate_is_used .git/objects/info/alternates . && |
| 127 | # update of the submodule succeeds |
| 128 | test_must_fail git submodule update --init && |
| 129 | # and we have no alternates: |
| 130 | test_path_is_missing .git/modules/sub/objects/info/alternates && |
| 131 | test_path_is_missing sub/file1 |
| 132 | ) |
| 133 | ' |
| 134 | |
| 135 | test_expect_success 'ignoring missing submodule alternates passes clone and submodule update' ' |
| 136 | test_when_finished "rm -rf super-clone" && |
| 137 | git clone --reference-if-able super2 --recursive super2 super-clone && |
| 138 | ( |
| 139 | cd super-clone && |
| 140 | # test superproject has alternates setup correctly |
| 141 | test_alternate_is_used .git/objects/info/alternates . && |
| 142 | # update of the submodule succeeds |
| 143 | git submodule update --init && |
| 144 | # and we have no alternates: |
| 145 | test_path_is_missing .git/modules/sub/objects/info/alternates && |
| 146 | test_path_is_file sub/file1 |
| 147 | ) |
| 148 | ' |
| 149 | |
| 150 | test_expect_success 'preparing second superproject with a nested submodule plus partial clone' ' |
| 151 | test_create_repo supersuper && |
| 152 | ( |
| 153 | cd supersuper && |
| 154 | echo "I am super super." >file && |
| 155 | git add file && |
| 156 | git commit -m B-super-super-initial && |
| 157 | git submodule add "file://$base_dir/super" subwithsub && |
| 158 | git commit -m B-super-super-added && |
| 159 | git submodule update --init --recursive && |
| 160 | git repack -ad |
| 161 | ) && |
| 162 | git clone supersuper supersuper2 && |
| 163 | ( |
| 164 | cd supersuper2 && |
| 165 | git submodule update --init |
| 166 | ) |
| 167 | ' |
| 168 | |
| 169 | # At this point there are three root-level positories: A, B, super and super2 |
| 170 | |
| 171 | test_expect_success 'nested submodule alternate in works and is actually used' ' |
| 172 | test_when_finished "rm -rf supersuper-clone" && |
| 173 | git clone --recursive --reference supersuper supersuper supersuper-clone && |
| 174 | ( |
| 175 | cd supersuper-clone && |
| 176 | # test superproject has alternates setup correctly |
| 177 | test_alternate_is_used .git/objects/info/alternates . && |
| 178 | # immediate submodule has alternate: |
| 179 | test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub && |
| 180 | # nested submodule also has alternate: |
| 181 | test_alternate_is_used .git/modules/subwithsub/modules/sub/objects/info/alternates subwithsub/sub |
| 182 | ) |
| 183 | ' |
| 184 | |
| 185 | check_that_two_of_three_alternates_are_used() { |
| 186 | test_alternate_is_used .git/objects/info/alternates . && |
| 187 | # immediate submodule has alternate: |
| 188 | test_alternate_is_used .git/modules/subwithsub/objects/info/alternates subwithsub && |
| 189 | # but nested submodule has no alternate: |
| 190 | test_path_is_missing .git/modules/subwithsub/modules/sub/objects/info/alternates |
| 191 | } |
| 192 | |
| 193 | |
| 194 | test_expect_success 'missing nested submodule alternate fails clone and submodule update' ' |
| 195 | test_when_finished "rm -rf supersuper-clone" && |
| 196 | test_must_fail git clone --recursive --reference supersuper2 supersuper2 supersuper-clone && |
| 197 | ( |
| 198 | cd supersuper-clone && |
| 199 | check_that_two_of_three_alternates_are_used && |
| 200 | # update of the submodule fails |
| 201 | cat >expect <<-\EOF && |
| 202 | fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist |
| 203 | Failed to clone '\''sub'\''. Retry scheduled |
| 204 | fatal: submodule '\''sub-dissociate'\'' cannot add alternate: path ... does not exist |
| 205 | Failed to clone '\''sub-dissociate'\''. Retry scheduled |
| 206 | fatal: submodule '\''sub'\'' cannot add alternate: path ... does not exist |
| 207 | Failed to clone '\''sub'\'' a second time, aborting |
| 208 | fatal: Failed to recurse into submodule path ... |
| 209 | EOF |
| 210 | test_must_fail git submodule update --init --recursive 2>err && |
| 211 | grep -e fatal: -e ^Failed err >actual.raw && |
| 212 | sed -e "s/path $SQ[^$SQ]*$SQ/path .../" <actual.raw >actual && |
| 213 | test_cmp expect actual |
| 214 | ) |
| 215 | ' |
| 216 | |
| 217 | test_expect_success 'missing nested submodule alternate in --reference-if-able mode' ' |
| 218 | test_when_finished "rm -rf supersuper-clone" && |
| 219 | git clone --recursive --reference-if-able supersuper2 supersuper2 supersuper-clone && |
| 220 | ( |
| 221 | cd supersuper-clone && |
| 222 | check_that_two_of_three_alternates_are_used && |
| 223 | # update of the submodule succeeds |
| 224 | git submodule update --init --recursive |
| 225 | ) |
| 226 | ' |
| 227 | |
| 228 | test_done |