3 test_description
='git branch submodule tests'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 TEST_PASSES_SANITIZE_LEAK
=true
10 .
"$TEST_DIRECTORY"/lib-rebase.sh
14 # Creates a clean test environment in "pwd" by copying the repo setup
18 rm -fr sub-sub-upstream
&&
19 rm -fr sub-upstream
&&
23 # Tests that the expected branch does not exist
27 test_must_fail git
-C "$DIR" rev-parse
"$BRANCH_NAME" 2>err
&&
28 grep "ambiguous argument .$BRANCH_NAME." err
31 test_expect_success
'setup superproject and submodule' '
32 git config --global protocol.file.allow always &&
37 test_commit -C super foo &&
38 git init sub-sub-upstream &&
39 test_commit -C sub-sub-upstream foo &&
40 git init sub-upstream &&
41 # Submodule in a submodule
42 git -C sub-upstream submodule add "${pwd}/test_dirs/sub-sub-upstream" sub-sub &&
43 git -C sub-upstream commit -m "add submodule" &&
45 git -C super submodule add "${pwd}/test_dirs/sub-upstream" sub &&
46 # Submodule in a subdirectory
47 git -C super submodule add "${pwd}/test_dirs/sub-sub-upstream" second/sub &&
48 git -C super commit -m "add submodule" &&
49 git -C super config submodule.propagateBranches true &&
50 git -C super/sub submodule update --init
55 # Test the argument parsing
56 test_expect_success
'--recurse-submodules should create branches' '
57 test_when_finished "reset_test" &&
60 git branch --recurse-submodules branch-a &&
61 git rev-parse branch-a &&
62 git -C sub rev-parse branch-a &&
63 git -C sub/sub-sub rev-parse branch-a &&
64 git -C second/sub rev-parse branch-a
68 test_expect_success
'--recurse-submodules should die if submodule.propagateBranches is false' '
69 test_when_finished "reset_test" &&
72 echo "fatal: branch with --recurse-submodules can only be used if submodule.propagateBranches is enabled" >expected &&
73 test_must_fail git -c submodule.propagateBranches=false branch --recurse-submodules branch-a 2>actual &&
74 test_cmp expected actual
78 test_expect_success
'--recurse-submodules should fail when not creating branches' '
79 test_when_finished "reset_test" &&
82 git branch --recurse-submodules branch-a &&
83 echo "fatal: --recurse-submodules can only be used to create branches" >expected &&
84 test_must_fail git branch --recurse-submodules -D branch-a 2>actual &&
85 test_cmp expected actual &&
86 # Assert that the branches were not deleted
87 git rev-parse branch-a &&
88 git -C sub rev-parse branch-a
92 test_expect_success
'should respect submodule.recurse when creating branches' '
93 test_when_finished "reset_test" &&
96 git -c submodule.recurse=true branch branch-a &&
97 git rev-parse branch-a &&
98 git -C sub rev-parse branch-a
102 test_expect_success
'should ignore submodule.recurse when not creating branches' '
103 test_when_finished "reset_test" &&
106 git branch --recurse-submodules branch-a &&
107 git -c submodule.recurse=true branch -D branch-a &&
108 test_no_branch . branch-a &&
109 git -C sub rev-parse branch-a
113 # Test branch creation behavior
114 test_expect_success
'should create branches based off commit id in superproject' '
115 test_when_finished "reset_test" &&
118 git branch --recurse-submodules branch-a &&
119 git checkout --recurse-submodules branch-a &&
120 git -C sub rev-parse HEAD >expected &&
121 # Move the tip of sub:branch-a so that it no longer matches the commit in super:branch-a
122 git -C sub checkout branch-a &&
123 test_commit -C sub bar &&
124 # Create a new branch-b branch with start-point=branch-a
125 git branch --recurse-submodules branch-b branch-a &&
126 git rev-parse branch-b &&
127 git -C sub rev-parse branch-b >actual &&
128 # Assert that the commit id of sub:second-branch matches super:branch-a and not sub:branch-a
129 test_cmp expected actual
133 test_expect_success
'should not create any branches if branch is not valid for all repos' '
134 test_when_finished "reset_test" &&
137 git -C sub branch branch-a &&
138 test_must_fail git branch --recurse-submodules branch-a 2>actual &&
139 test_no_branch . branch-a &&
140 grep "submodule .sub.: fatal: a branch named .branch-a. already exists" actual
144 test_expect_success
'should create branches if branch exists and --force is given' '
145 test_when_finished "reset_test" &&
148 git -C sub rev-parse HEAD >expected &&
149 test_commit -C sub baz &&
150 # branch-a in sub now points to a newer commit.
151 git -C sub branch branch-a HEAD &&
152 git -C sub rev-parse branch-a >actual-old-branch-a &&
153 git branch --recurse-submodules --force branch-a &&
154 git rev-parse branch-a &&
155 git -C sub rev-parse branch-a >actual-new-branch-a &&
156 test_cmp expected actual-new-branch-a &&
157 # assert that branch --force actually moved the sub
159 ! test_cmp expected actual-old-branch-a
163 test_expect_success
'should create branch when submodule is not in HEAD:.gitmodules' '
164 test_when_finished "reset_test" &&
167 git branch branch-a &&
168 git checkout -b branch-b &&
169 git submodule add ../sub-upstream sub2 &&
170 git -C sub2 submodule update --init &&
171 # branch-b now has a committed submodule not in branch-a
172 git commit -m "add second submodule" &&
173 git checkout branch-a &&
174 git branch --recurse-submodules branch-c branch-b &&
175 git checkout --recurse-submodules branch-c &&
176 git -C sub2 rev-parse branch-c &&
177 git -C sub2/sub-sub rev-parse branch-c
181 test_expect_success
'should not create branches in inactive submodules' '
182 test_when_finished "reset_test" &&
183 test_config -C super submodule.sub.active false &&
186 git branch --recurse-submodules branch-a &&
187 git rev-parse branch-a &&
188 test_no_branch sub branch-a
192 test_expect_success
'should set up tracking of local branches with track=always' '
193 test_when_finished "reset_test" &&
196 git -c branch.autoSetupMerge=always branch --recurse-submodules branch-a main &&
197 git -C sub rev-parse main &&
198 test_cmp_config -C sub . branch.branch-a.remote &&
199 test_cmp_config -C sub refs/heads/main branch.branch-a.merge
203 test_expect_success
'should set up tracking of local branches with explicit track' '
204 test_when_finished "reset_test" &&
207 git branch --track --recurse-submodules branch-a main &&
208 git -C sub rev-parse main &&
209 test_cmp_config -C sub . branch.branch-a.remote &&
210 test_cmp_config -C sub refs/heads/main branch.branch-a.merge
214 test_expect_success
'should not set up unnecessary tracking of local branches' '
215 test_when_finished "reset_test" &&
218 git branch --recurse-submodules branch-a main &&
219 git -C sub rev-parse main &&
220 test_cmp_config -C sub "" --default "" branch.branch-a.remote &&
221 test_cmp_config -C sub "" --default "" branch.branch-a.merge
225 reset_remote_test
() {
226 rm -fr super-clone
&&
230 test_expect_success
'setup tests with remotes' '
235 git branch branch-a &&
236 git checkout -b branch-b &&
237 git submodule add ../sub-upstream sub2 &&
238 # branch-b now has a committed submodule not in branch-a
239 git commit -m "add second submodule"
241 git clone --branch main --recurse-submodules super super-clone &&
242 git -C super-clone config submodule.propagateBranches true
247 test_expect_success
'should get fatal error upon branch creation when submodule is not in .git/modules' '
248 test_when_finished "reset_remote_test" &&
251 # This should succeed because super-clone has sub in .git/modules
252 git branch --recurse-submodules branch-a origin/branch-a &&
253 # This should fail because super-clone does not have sub2 .git/modules
254 test_must_fail git branch --recurse-submodules branch-b origin/branch-b 2>actual &&
255 grep "fatal: submodule .sub2.: unable to find submodule" actual &&
256 test_no_branch . branch-b &&
257 test_no_branch sub branch-b &&
258 # User can fix themselves by initializing the submodule
259 git checkout origin/branch-b &&
260 git submodule update --init --recursive &&
261 git branch --recurse-submodules branch-b origin/branch-b
265 test_expect_success
'should set up tracking of remote-tracking branches by default' '
266 test_when_finished "reset_remote_test" &&
269 git branch --recurse-submodules branch-a origin/branch-a &&
270 test_cmp_config origin branch.branch-a.remote &&
271 test_cmp_config refs/heads/branch-a branch.branch-a.merge &&
272 # "origin/branch-a" does not exist for "sub", but it matches the refspec
273 # so tracking should be set up
274 test_cmp_config -C sub origin branch.branch-a.remote &&
275 test_cmp_config -C sub refs/heads/branch-a branch.branch-a.merge &&
276 test_cmp_config -C sub/sub-sub origin branch.branch-a.remote &&
277 test_cmp_config -C sub/sub-sub refs/heads/branch-a branch.branch-a.merge
281 test_expect_success
'should not fail when unable to set up tracking in submodule' '
282 test_when_finished "reset_remote_test" &&
285 git remote rename origin ex-origin &&
286 git branch --recurse-submodules branch-a ex-origin/branch-a &&
287 test_cmp_config ex-origin branch.branch-a.remote &&
288 test_cmp_config refs/heads/branch-a branch.branch-a.merge &&
289 test_cmp_config -C sub "" --default "" branch.branch-a.remote &&
290 test_cmp_config -C sub "" --default "" branch.branch-a.merge
294 test_expect_success
'--track=inherit should set up tracking correctly' '
295 test_when_finished "reset_remote_test" &&
298 git branch --recurse-submodules branch-a origin/branch-a &&
299 # Set this manually instead of using branch --set-upstream-to
300 # to circumvent the "nonexistent upstream" check.
301 git -C sub config branch.branch-a.remote origin &&
302 git -C sub config branch.branch-a.merge refs/heads/sub-branch-a &&
303 git -C sub/sub-sub config branch.branch-a.remote other &&
304 git -C sub/sub-sub config branch.branch-a.merge refs/heads/sub-sub-branch-a &&
306 git branch --recurse-submodules --track=inherit branch-b branch-a &&
307 test_cmp_config origin branch.branch-b.remote &&
308 test_cmp_config refs/heads/branch-a branch.branch-b.merge &&
309 test_cmp_config -C sub origin branch.branch-b.remote &&
310 test_cmp_config -C sub refs/heads/sub-branch-a branch.branch-b.merge &&
311 test_cmp_config -C sub/sub-sub other branch.branch-b.remote &&
312 test_cmp_config -C sub/sub-sub refs/heads/sub-sub-branch-a branch.branch-b.merge
316 test_expect_success
'--no-track should not set up tracking' '
317 test_when_finished "reset_remote_test" &&
320 git branch --recurse-submodules --no-track branch-a origin/branch-a &&
321 test_cmp_config "" --default "" branch.branch-a.remote &&
322 test_cmp_config "" --default "" branch.branch-a.merge &&
323 test_cmp_config -C sub "" --default "" branch.branch-a.remote &&
324 test_cmp_config -C sub "" --default "" branch.branch-a.merge &&
325 test_cmp_config -C sub/sub-sub "" --default "" branch.branch-a.remote &&
326 test_cmp_config -C sub/sub-sub "" --default "" branch.branch-a.merge