Git fork
at reftables-rust 263 lines 9.1 kB view raw
1#!/bin/sh 2 3test_description='pull can handle submodules' 4 5GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 6export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB 7 8. ./test-lib.sh 9. "$TEST_DIRECTORY"/lib-submodule-update.sh 10 11reset_branch_to_HEAD () { 12 git branch -D "$1" && 13 git checkout -b "$1" HEAD && 14 git branch --set-upstream-to="origin/$1" "$1" 15} 16 17git_pull () { 18 reset_branch_to_HEAD "$1" && 19 may_only_be_test_must_fail "$2" && 20 $2 git pull 21} 22 23# pulls without conflicts 24test_submodule_switch_func "git_pull" 25 26git_pull_ff () { 27 reset_branch_to_HEAD "$1" && 28 may_only_be_test_must_fail "$2" && 29 $2 git pull --ff 30} 31 32test_submodule_switch_func "git_pull_ff" 33 34git_pull_ff_only () { 35 reset_branch_to_HEAD "$1" && 36 may_only_be_test_must_fail "$2" && 37 $2 git pull --ff-only 38} 39 40test_submodule_switch_func "git_pull_ff_only" 41 42git_pull_noff () { 43 reset_branch_to_HEAD "$1" && 44 may_only_be_test_must_fail "$2" && 45 $2 git pull --no-ff 46} 47 48test_submodule_switch_func "git_pull_noff" 49 50test_expect_success 'setup' ' 51 git config --global protocol.file.allow always 52' 53 54test_expect_success 'pull --recurse-submodule setup' ' 55 test_create_repo child && 56 test_commit -C child bar && 57 58 test_create_repo parent && 59 test_commit -C child foo && 60 61 git -C parent submodule add ../child sub && 62 git -C parent commit -m "add submodule" && 63 64 git clone --recurse-submodules parent super 65' 66 67test_expect_success 'recursive pull updates working tree' ' 68 test_commit -C child merge_strategy && 69 git -C parent submodule update --remote && 70 git -C parent add sub && 71 git -C parent commit -m "update submodule" && 72 73 git -C super pull --no-rebase --recurse-submodules && 74 test_path_is_file super/sub/merge_strategy.t 75' 76 77test_expect_success "submodule.recurse option triggers recursive pull" ' 78 test_commit -C child merge_strategy_2 && 79 git -C parent submodule update --remote && 80 git -C parent add sub && 81 git -C parent commit -m "update submodule" && 82 83 git -C super -c submodule.recurse pull --no-rebase && 84 test_path_is_file super/sub/merge_strategy_2.t 85' 86 87test_expect_success " --[no-]recurse-submodule and submodule.recurse" ' 88 test_commit -C child merge_strategy_3 && 89 git -C parent submodule update --remote && 90 git -C parent add sub && 91 git -C parent commit -m "update submodule" && 92 93 git -C super -c submodule.recurse pull --no-recurse-submodules --no-rebase && 94 test_path_is_missing super/sub/merge_strategy_3.t && 95 git -C super -c submodule.recurse=false pull --recurse-submodules --no-rebase && 96 test_path_is_file super/sub/merge_strategy_3.t && 97 98 test_commit -C child merge_strategy_4 && 99 git -C parent submodule update --remote && 100 git -C parent add sub && 101 git -C parent commit -m "update submodule" && 102 103 git -C super -c submodule.recurse=false pull --no-recurse-submodules --no-rebase && 104 test_path_is_missing super/sub/merge_strategy_4.t && 105 git -C super -c submodule.recurse=true pull --recurse-submodules --no-rebase && 106 test_path_is_file super/sub/merge_strategy_4.t 107' 108 109test_expect_success "fetch.recurseSubmodules option triggers recursive fetch (but not recursive update)" ' 110 test_commit -C child merge_strategy_5 && 111 # Omit the parent commit, otherwise this passes with the 112 # default "pull" behavior. 113 114 git -C super -c fetch.recursesubmodules=true pull --no-rebase && 115 # Check that the submodule commit was fetched 116 sub_oid=$(git -C child rev-parse HEAD) && 117 git -C super/sub cat-file -e $sub_oid && 118 # Check that the submodule worktree did not update 119 test_path_is_missing super/sub/merge_strategy_5.t 120' 121 122test_expect_success "fetch.recurseSubmodules takes precedence over submodule.recurse" ' 123 test_commit -C child merge_strategy_6 && 124 # Omit the parent commit, otherwise this passes with the 125 # default "pull" behavior. 126 127 git -C super -c submodule.recurse=false -c fetch.recursesubmodules=true pull --no-rebase && 128 # Check that the submodule commit was fetched 129 sub_oid=$(git -C child rev-parse HEAD) && 130 git -C super/sub cat-file -e $sub_oid && 131 # Check that the submodule worktree did not update 132 test_path_is_missing super/sub/merge_strategy_6.t 133' 134 135test_expect_success 'pull --rebase --recurse-submodules (remote superproject submodule changes, local submodule changes)' ' 136 # This tests the following scenario : 137 # - local submodule has new commits 138 # - local superproject does not have new commits 139 # - upstream superproject has new commits that change the submodule pointer 140 141 # change upstream 142 test_commit -C child rebase_strategy && 143 git -C parent submodule update --remote && 144 git -C parent add sub && 145 git -C parent commit -m "update submodule" && 146 147 # also have local commits 148 test_commit -C super/sub local_stuff && 149 150 git -C super pull --rebase --recurse-submodules && 151 test_path_is_file super/sub/rebase_strategy.t && 152 test_path_is_file super/sub/local_stuff.t 153' 154 155test_expect_success 'pull --rebase --recurse-submodules fails if both sides record submodule changes' ' 156 # This tests the following scenario : 157 # - local superproject has new commits that change the submodule pointer 158 # - upstream superproject has new commits that change the submodule pointer 159 160 # local changes in submodule recorded in superproject: 161 test_commit -C super/sub local_stuff_2 && 162 git -C super add sub && 163 git -C super commit -m "local update submodule" && 164 165 # and in the remote as well: 166 test_commit -C child important_upstream_work && 167 git -C parent submodule update --remote && 168 git -C parent add sub && 169 git -C parent commit -m "remote update submodule" && 170 171 # Unfortunately we fail here, despite no conflict in the 172 # submodule itself, but the merge strategy in submodules 173 # does not support rebase: 174 test_must_fail git -C super pull --rebase --recurse-submodules 2>err && 175 test_grep "locally recorded submodule modifications" err 176' 177 178test_expect_success 'pull --rebase --recurse-submodules (no submodule changes, no fork-point)' ' 179 # This tests the following scenario : 180 # - local submodule does not have new commits 181 # - local superproject has new commits that *do not* change the submodule pointer 182 # - upstream superproject has new commits that *do not* change the submodule pointer 183 # - local superproject branch has no fork-point with its remote-tracking counter-part 184 185 # create upstream superproject 186 test_create_repo submodule && 187 test_commit -C submodule first_in_sub && 188 189 test_create_repo superprojet && 190 test_commit -C superprojet first_in_super && 191 git -C superprojet submodule add ../submodule && 192 git -C superprojet commit -m "add submodule" && 193 test_commit -C superprojet third_in_super && 194 195 # clone superproject 196 git clone --recurse-submodules superprojet superclone && 197 198 # add commits upstream 199 test_commit -C superprojet fourth_in_super && 200 201 # create topic branch in clone, not based on any remote-tracking branch 202 git -C superclone checkout -b feat HEAD~1 && 203 test_commit -C superclone first_on_feat && 204 git -C superclone pull --rebase --recurse-submodules origin HEAD 205' 206 207# NOTE: 208# 209# This test is particular because there is only a single commit in the upstream superproject 210# 'parent' (which adds the submodule 'a-submodule'). The clone of the superproject 211# ('child') hard-resets its branch to a new root commit with the same tree as the one 212# from the upstream superproject, so that its branch has no merge-base with its 213# remote-tracking counterpart, and then calls 'git pull --recurse-submodules --rebase'. 214# The result is that the local branch is reset to the remote-tracking branch (as it was 215# originally before the hard-reset). 216 217# The only commit in the range generated by 'submodule.c::submodule_touches_in_range' and 218# passed to 'submodule.c::collect_changed_submodules' is the new (regenerated) initial commit, 219# which adds the submodule. 220# However, 'submodule_touches_in_range' does not error (even though this commit adds the submodule) 221# because 'combine-diff.c::diff_tree_combined' returns early, as the initial commit has no parents. 222test_expect_success 'branch has no merge base with remote-tracking counterpart' ' 223 rm -rf parent child && 224 225 test_create_repo a-submodule && 226 test_commit -C a-submodule foo && 227 test_commit -C a-submodule bar && 228 229 test_create_repo parent && 230 git -C parent submodule add "$(pwd)/a-submodule" && 231 git -C parent commit -m foo && 232 233 git clone parent child && 234 235 # Reset the current branch so that it has no merge base with 236 # the remote-tracking branch. 237 OTHER=$(git -C child commit-tree -m bar \ 238 $(git -C child rev-parse HEAD^{tree})) && 239 git -C child reset --hard "$OTHER" && 240 241 git -C child pull --recurse-submodules --rebase 242' 243 244test_expect_success 'fetch submodule remote of different name from superproject' ' 245 git -C child remote rename origin o1 && 246 git -C child submodule update --init && 247 248 # Needs to create unreachable commit from current master branch. 249 git -C a-submodule checkout -b newmain HEAD^ && 250 test_commit -C a-submodule echo && 251 test_commit -C a-submodule moreecho && 252 subc=$(git -C a-submodule rev-parse --short HEAD) && 253 254 git -C parent/a-submodule fetch && 255 git -C parent/a-submodule checkout "$subc" && 256 git -C parent commit -m "update submodule" a-submodule && 257 git -C a-submodule reset --hard HEAD^^ && 258 259 git -C child pull --no-recurse-submodules && 260 git -C child submodule update 261' 262 263test_done