rebase: use correct base for --keep-base when a branch is given
[alt-git.git] / t / t5572-pull-submodule.sh
blobfa6b4cca65c8c687bf83f9eaf0ecb5568c9373f6
1 #!/bin/sh
3 test_description='pull can handle submodules'
5 GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1
6 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
8 . ./test-lib.sh
9 . "$TEST_DIRECTORY"/lib-submodule-update.sh
11 reset_branch_to_HEAD () {
12 git branch -D "$1" &&
13 git checkout -b "$1" HEAD &&
14 git branch --set-upstream-to="origin/$1" "$1"
17 git_pull () {
18 reset_branch_to_HEAD "$1" &&
19 may_only_be_test_must_fail "$2" &&
20 $2 git pull
23 # pulls without conflicts
24 test_submodule_switch_func "git_pull"
26 git_pull_ff () {
27 reset_branch_to_HEAD "$1" &&
28 may_only_be_test_must_fail "$2" &&
29 $2 git pull --ff
32 test_submodule_switch_func "git_pull_ff"
34 git_pull_ff_only () {
35 reset_branch_to_HEAD "$1" &&
36 may_only_be_test_must_fail "$2" &&
37 $2 git pull --ff-only
40 test_submodule_switch_func "git_pull_ff_only"
42 git_pull_noff () {
43 reset_branch_to_HEAD "$1" &&
44 may_only_be_test_must_fail "$2" &&
45 $2 git pull --no-ff
48 if test "$GIT_TEST_MERGE_ALGORITHM" != ort
49 then
50 KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
51 KNOWN_FAILURE_NOFF_MERGE_ATTEMPTS_TO_MERGE_REMOVED_SUBMODULE_FILES=1
53 test_submodule_switch_func "git_pull_noff"
55 test_expect_success 'pull --recurse-submodule setup' '
56 test_create_repo child &&
57 test_commit -C child bar &&
59 test_create_repo parent &&
60 test_commit -C child foo &&
62 git -C parent submodule add ../child sub &&
63 git -C parent commit -m "add submodule" &&
65 git clone --recurse-submodules parent super
68 test_expect_success 'recursive pull updates working tree' '
69 test_commit -C child merge_strategy &&
70 git -C parent submodule update --remote &&
71 git -C parent add sub &&
72 git -C parent commit -m "update submodule" &&
74 git -C super pull --no-rebase --recurse-submodules &&
75 test_path_is_file super/sub/merge_strategy.t
78 test_expect_success "submodule.recurse option triggers recursive pull" '
79 test_commit -C child merge_strategy_2 &&
80 git -C parent submodule update --remote &&
81 git -C parent add sub &&
82 git -C parent commit -m "update submodule" &&
84 git -C super -c submodule.recurse pull --no-rebase &&
85 test_path_is_file super/sub/merge_strategy_2.t
88 test_expect_success " --[no-]recurse-submodule and submodule.recurse" '
89 test_commit -C child merge_strategy_3 &&
90 git -C parent submodule update --remote &&
91 git -C parent add sub &&
92 git -C parent commit -m "update submodule" &&
94 git -C super -c submodule.recurse pull --no-recurse-submodules --no-rebase &&
95 test_path_is_missing super/sub/merge_strategy_3.t &&
96 git -C super -c submodule.recurse=false pull --recurse-submodules --no-rebase &&
97 test_path_is_file super/sub/merge_strategy_3.t &&
99 test_commit -C child merge_strategy_4 &&
100 git -C parent submodule update --remote &&
101 git -C parent add sub &&
102 git -C parent commit -m "update submodule" &&
104 git -C super -c submodule.recurse=false pull --no-recurse-submodules --no-rebase &&
105 test_path_is_missing super/sub/merge_strategy_4.t &&
106 git -C super -c submodule.recurse=true pull --recurse-submodules --no-rebase &&
107 test_path_is_file super/sub/merge_strategy_4.t
110 test_expect_success 'pull --rebase --recurse-submodules (remote superproject submodule changes, local submodule changes)' '
111 # This tests the following scenario :
112 # - local submodule has new commits
113 # - local superproject does not have new commits
114 # - upstream superproject has new commits that change the submodule pointer
116 # change upstream
117 test_commit -C child rebase_strategy &&
118 git -C parent submodule update --remote &&
119 git -C parent add sub &&
120 git -C parent commit -m "update submodule" &&
122 # also have local commits
123 test_commit -C super/sub local_stuff &&
125 git -C super pull --rebase --recurse-submodules &&
126 test_path_is_file super/sub/rebase_strategy.t &&
127 test_path_is_file super/sub/local_stuff.t
130 test_expect_success 'pull --rebase --recurse-submodules fails if both sides record submodule changes' '
131 # This tests the following scenario :
132 # - local superproject has new commits that change the submodule pointer
133 # - upstream superproject has new commits that change the submodule pointer
135 # local changes in submodule recorded in superproject:
136 test_commit -C super/sub local_stuff_2 &&
137 git -C super add sub &&
138 git -C super commit -m "local update submodule" &&
140 # and in the remote as well:
141 test_commit -C child important_upstream_work &&
142 git -C parent submodule update --remote &&
143 git -C parent add sub &&
144 git -C parent commit -m "remote update submodule" &&
146 # Unfortunately we fail here, despite no conflict in the
147 # submodule itself, but the merge strategy in submodules
148 # does not support rebase:
149 test_must_fail git -C super pull --rebase --recurse-submodules 2>err &&
150 test_i18ngrep "locally recorded submodule modifications" err
153 test_expect_success 'pull --rebase --recurse-submodules (no submodule changes, no fork-point)' '
154 # This tests the following scenario :
155 # - local submodule does not have new commits
156 # - local superproject has new commits that *do not* change the submodule pointer
157 # - upstream superproject has new commits that *do not* change the submodule pointer
158 # - local superproject branch has no fork-point with its remote-tracking counter-part
160 # create upstream superproject
161 test_create_repo submodule &&
162 test_commit -C submodule first_in_sub &&
164 test_create_repo superprojet &&
165 test_commit -C superprojet first_in_super &&
166 git -C superprojet submodule add ../submodule &&
167 git -C superprojet commit -m "add submodule" &&
168 test_commit -C superprojet third_in_super &&
170 # clone superproject
171 git clone --recurse-submodules superprojet superclone &&
173 # add commits upstream
174 test_commit -C superprojet fourth_in_super &&
176 # create topic branch in clone, not based on any remote-tracking branch
177 git -C superclone checkout -b feat HEAD~1 &&
178 test_commit -C superclone first_on_feat &&
179 git -C superclone pull --rebase --recurse-submodules origin HEAD
182 # NOTE:
184 # This test is particular because there is only a single commit in the upstream superproject
185 # 'parent' (which adds the submodule 'a-submodule'). The clone of the superproject
186 # ('child') hard-resets its branch to a new root commit with the same tree as the one
187 # from the upstream superproject, so that its branch has no merge-base with its
188 # remote-tracking counterpart, and then calls 'git pull --recurse-submodules --rebase'.
189 # The result is that the local branch is reset to the remote-tracking branch (as it was
190 # originally before the hard-reset).
192 # The only commit in the range generated by 'submodule.c::submodule_touches_in_range' and
193 # passed to 'submodule.c::collect_changed_submodules' is the new (regenerated) initial commit,
194 # which adds the submodule.
195 # However, 'submodule_touches_in_range' does not error (even though this commit adds the submodule)
196 # because 'combine-diff.c::diff_tree_combined' returns early, as the initial commit has no parents.
197 test_expect_success 'branch has no merge base with remote-tracking counterpart' '
198 rm -rf parent child &&
200 test_create_repo a-submodule &&
201 test_commit -C a-submodule foo &&
203 test_create_repo parent &&
204 git -C parent submodule add "$(pwd)/a-submodule" &&
205 git -C parent commit -m foo &&
207 git clone parent child &&
209 # Reset the current branch so that it has no merge base with
210 # the remote-tracking branch.
211 OTHER=$(git -C child commit-tree -m bar \
212 $(git -C child rev-parse HEAD^{tree})) &&
213 git -C child reset --hard "$OTHER" &&
215 git -C child pull --recurse-submodules --rebase
218 test_done