Merge branch 'ab/remote-write-config-in-camel-case'
[git] / t / t1305-config-include.sh
1 #!/bin/sh
2
3 test_description='test config file include directives'
4 . ./test-lib.sh
5
6 # Force setup_explicit_git_dir() to run until the end. This is needed
7 # by some tests to make sure real_path() is called on $GIT_DIR. The
8 # caller needs to make sure git commands are run from a subdirectory
9 # though or real_path() will not be called.
10 force_setup_explicit_git_dir() {
11     GIT_DIR="$(pwd)/.git"
12     GIT_WORK_TREE="$(pwd)"
13     export GIT_DIR GIT_WORK_TREE
14 }
15
16 test_expect_success 'include file by absolute path' '
17         echo "[test]one = 1" >one &&
18         echo "[include]path = \"$(pwd)/one\"" >.gitconfig &&
19         echo 1 >expect &&
20         git config test.one >actual &&
21         test_cmp expect actual
22 '
23
24 test_expect_success 'include file by relative path' '
25         echo "[test]one = 1" >one &&
26         echo "[include]path = one" >.gitconfig &&
27         echo 1 >expect &&
28         git config test.one >actual &&
29         test_cmp expect actual
30 '
31
32 test_expect_success 'chained relative paths' '
33         mkdir subdir &&
34         echo "[test]three = 3" >subdir/three &&
35         echo "[include]path = three" >subdir/two &&
36         echo "[include]path = subdir/two" >.gitconfig &&
37         echo 3 >expect &&
38         git config test.three >actual &&
39         test_cmp expect actual
40 '
41
42 test_expect_success 'include paths get tilde-expansion' '
43         echo "[test]one = 1" >one &&
44         echo "[include]path = ~/one" >.gitconfig &&
45         echo 1 >expect &&
46         git config test.one >actual &&
47         test_cmp expect actual
48 '
49
50 test_expect_success 'include options can still be examined' '
51         echo "[test]one = 1" >one &&
52         echo "[include]path = one" >.gitconfig &&
53         echo one >expect &&
54         git config include.path >actual &&
55         test_cmp expect actual
56 '
57
58 test_expect_success 'listing includes option and expansion' '
59         echo "[test]one = 1" >one &&
60         echo "[include]path = one" >.gitconfig &&
61         cat >expect <<-\EOF &&
62         include.path=one
63         test.one=1
64         EOF
65         git config --list >actual.full &&
66         grep -v -e ^core -e ^extensions actual.full >actual &&
67         test_cmp expect actual
68 '
69
70 test_expect_success 'single file lookup does not expand includes by default' '
71         echo "[test]one = 1" >one &&
72         echo "[include]path = one" >.gitconfig &&
73         test_must_fail git config -f .gitconfig test.one &&
74         test_must_fail git config --global test.one &&
75         echo 1 >expect &&
76         git config --includes -f .gitconfig test.one >actual &&
77         test_cmp expect actual
78 '
79
80 test_expect_success 'single file list does not expand includes by default' '
81         echo "[test]one = 1" >one &&
82         echo "[include]path = one" >.gitconfig &&
83         echo "include.path=one" >expect &&
84         git config -f .gitconfig --list >actual &&
85         test_cmp expect actual
86 '
87
88 test_expect_success 'writing config file does not expand includes' '
89         echo "[test]one = 1" >one &&
90         echo "[include]path = one" >.gitconfig &&
91         git config test.two 2 &&
92         echo 2 >expect &&
93         git config --no-includes test.two >actual &&
94         test_cmp expect actual &&
95         test_must_fail git config --no-includes test.one
96 '
97
98 test_expect_success 'config modification does not affect includes' '
99         echo "[test]one = 1" >one &&
100         echo "[include]path = one" >.gitconfig &&
101         git config test.one 2 &&
102         echo 1 >expect &&
103         git config -f one test.one >actual &&
104         test_cmp expect actual &&
105         cat >expect <<-\EOF &&
106         1
107         2
108         EOF
109         git config --get-all test.one >actual &&
110         test_cmp expect actual
111 '
112
113 test_expect_success 'missing include files are ignored' '
114         cat >.gitconfig <<-\EOF &&
115         [include]path = non-existent
116         [test]value = yes
117         EOF
118         echo yes >expect &&
119         git config test.value >actual &&
120         test_cmp expect actual
121 '
122
123 test_expect_success 'absolute includes from command line work' '
124         echo "[test]one = 1" >one &&
125         echo 1 >expect &&
126         git -c include.path="$(pwd)/one" config test.one >actual &&
127         test_cmp expect actual
128 '
129
130 test_expect_success 'relative includes from command line fail' '
131         echo "[test]one = 1" >one &&
132         test_must_fail git -c include.path=one config test.one
133 '
134
135 test_expect_success 'absolute includes from blobs work' '
136         echo "[test]one = 1" >one &&
137         echo "[include]path=$(pwd)/one" >blob &&
138         blob=$(git hash-object -w blob) &&
139         echo 1 >expect &&
140         git config --blob=$blob test.one >actual &&
141         test_cmp expect actual
142 '
143
144 test_expect_success 'relative includes from blobs fail' '
145         echo "[test]one = 1" >one &&
146         echo "[include]path=one" >blob &&
147         blob=$(git hash-object -w blob) &&
148         test_must_fail git config --blob=$blob test.one
149 '
150
151 test_expect_success 'absolute includes from stdin work' '
152         echo "[test]one = 1" >one &&
153         echo 1 >expect &&
154         echo "[include]path=\"$(pwd)/one\"" |
155         git config --file - test.one >actual &&
156         test_cmp expect actual
157 '
158
159 test_expect_success 'relative includes from stdin line fail' '
160         echo "[test]one = 1" >one &&
161         echo "[include]path=one" |
162         test_must_fail git config --file - test.one
163 '
164
165 test_expect_success 'conditional include, both unanchored' '
166         git init foo &&
167         (
168                 cd foo &&
169                 echo "[includeIf \"gitdir:foo/\"]path=bar" >>.git/config &&
170                 echo "[test]one=1" >.git/bar &&
171                 echo 1 >expect &&
172                 git config test.one >actual &&
173                 test_cmp expect actual
174         )
175 '
176
177 test_expect_success 'conditional include, $HOME expansion' '
178         (
179                 cd foo &&
180                 echo "[includeIf \"gitdir:~/foo/\"]path=bar2" >>.git/config &&
181                 echo "[test]two=2" >.git/bar2 &&
182                 echo 2 >expect &&
183                 git config test.two >actual &&
184                 test_cmp expect actual
185         )
186 '
187
188 test_expect_success 'conditional include, full pattern' '
189         (
190                 cd foo &&
191                 echo "[includeIf \"gitdir:**/foo/**\"]path=bar3" >>.git/config &&
192                 echo "[test]three=3" >.git/bar3 &&
193                 echo 3 >expect &&
194                 git config test.three >actual &&
195                 test_cmp expect actual
196         )
197 '
198
199 test_expect_success 'conditional include, relative path' '
200         echo "[includeIf \"gitdir:./foo/.git\"]path=bar4" >>.gitconfig &&
201         echo "[test]four=4" >bar4 &&
202         (
203                 cd foo &&
204                 echo 4 >expect &&
205                 git config test.four >actual &&
206                 test_cmp expect actual
207         )
208 '
209
210 test_expect_success 'conditional include, both unanchored, icase' '
211         (
212                 cd foo &&
213                 echo "[includeIf \"gitdir/i:FOO/\"]path=bar5" >>.git/config &&
214                 echo "[test]five=5" >.git/bar5 &&
215                 echo 5 >expect &&
216                 git config test.five >actual &&
217                 test_cmp expect actual
218         )
219 '
220
221 test_expect_success 'conditional include, early config reading' '
222         (
223                 cd foo &&
224                 echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config &&
225                 echo "[test]six=6" >.git/bar6 &&
226                 echo 6 >expect &&
227                 test-tool config read_early_config test.six >actual &&
228                 test_cmp expect actual
229         )
230 '
231
232 test_expect_success 'conditional include with /**/' '
233         REPO=foo/bar/repo &&
234         git init $REPO &&
235         cat >>$REPO/.git/config <<-\EOF &&
236         [includeIf "gitdir:**/foo/**/bar/**"]
237         path=bar7
238         EOF
239         echo "[test]seven=7" >$REPO/.git/bar7 &&
240         echo 7 >expect &&
241         git -C $REPO config test.seven >actual &&
242         test_cmp expect actual
243 '
244
245 test_expect_success SYMLINKS 'conditional include, set up symlinked $HOME' '
246         mkdir real-home &&
247         ln -s real-home home &&
248         (
249                 HOME="$TRASH_DIRECTORY/home" &&
250                 export HOME &&
251                 cd "$HOME" &&
252
253                 git init foo &&
254                 cd foo &&
255                 mkdir sub
256         )
257 '
258
259 test_expect_success SYMLINKS 'conditional include, $HOME expansion with symlinks' '
260         (
261                 HOME="$TRASH_DIRECTORY/home" &&
262                 export HOME &&
263                 cd "$HOME"/foo &&
264
265                 echo "[includeIf \"gitdir:~/foo/\"]path=bar2" >>.git/config &&
266                 echo "[test]two=2" >.git/bar2 &&
267                 echo 2 >expect &&
268                 force_setup_explicit_git_dir &&
269                 git -C sub config test.two >actual &&
270                 test_cmp expect actual
271         )
272 '
273
274 test_expect_success SYMLINKS 'conditional include, relative path with symlinks' '
275         echo "[includeIf \"gitdir:./foo/.git\"]path=bar4" >home/.gitconfig &&
276         echo "[test]four=4" >home/bar4 &&
277         (
278                 HOME="$TRASH_DIRECTORY/home" &&
279                 export HOME &&
280                 cd "$HOME"/foo &&
281
282                 echo 4 >expect &&
283                 force_setup_explicit_git_dir &&
284                 git -C sub config test.four >actual &&
285                 test_cmp expect actual
286         )
287 '
288
289 test_expect_success SYMLINKS 'conditional include, gitdir matching symlink' '
290         ln -s foo bar &&
291         (
292                 cd bar &&
293                 echo "[includeIf \"gitdir:bar/\"]path=bar7" >>.git/config &&
294                 echo "[test]seven=7" >.git/bar7 &&
295                 echo 7 >expect &&
296                 git config test.seven >actual &&
297                 test_cmp expect actual
298         )
299 '
300
301 test_expect_success SYMLINKS 'conditional include, gitdir matching symlink, icase' '
302         (
303                 cd bar &&
304                 echo "[includeIf \"gitdir/i:BAR/\"]path=bar8" >>.git/config &&
305                 echo "[test]eight=8" >.git/bar8 &&
306                 echo 8 >expect &&
307                 git config test.eight >actual &&
308                 test_cmp expect actual
309         )
310 '
311
312 test_expect_success 'conditional include, onbranch' '
313         echo "[includeIf \"onbranch:foo-branch\"]path=bar9" >>.git/config &&
314         echo "[test]nine=9" >.git/bar9 &&
315         git checkout -b main &&
316         test_must_fail git config test.nine &&
317         git checkout -b foo-branch &&
318         echo 9 >expect &&
319         git config test.nine >actual &&
320         test_cmp expect actual
321 '
322
323 test_expect_success 'conditional include, onbranch, wildcard' '
324         echo "[includeIf \"onbranch:?oo-*/**\"]path=bar10" >>.git/config &&
325         echo "[test]ten=10" >.git/bar10 &&
326         git checkout -b not-foo-branch/a &&
327         test_must_fail git config test.ten &&
328
329         echo 10 >expect &&
330         git checkout -b foo-branch/a/b/c &&
331         git config test.ten >actual &&
332         test_cmp expect actual &&
333
334         git checkout -b moo-bar/a &&
335         git config test.ten >actual &&
336         test_cmp expect actual
337 '
338
339 test_expect_success 'conditional include, onbranch, implicit /** for /' '
340         echo "[includeIf \"onbranch:foo-dir/\"]path=bar11" >>.git/config &&
341         echo "[test]eleven=11" >.git/bar11 &&
342         git checkout -b not-foo-dir/a &&
343         test_must_fail git config test.eleven &&
344
345         echo 11 >expect &&
346         git checkout -b foo-dir/a/b/c &&
347         git config test.eleven >actual &&
348         test_cmp expect actual
349 '
350
351 test_expect_success 'include cycles are detected' '
352         git init --bare cycle &&
353         git -C cycle config include.path cycle &&
354         git config -f cycle/cycle include.path config &&
355         test_must_fail git -C cycle config --get-all test.value 2>stderr &&
356         grep "exceeded maximum include depth" stderr
357 '
358
359 test_done