Raw
1 #!/bin/sh
2
3 test_description='git command aliasing'
4
5 . ./test-lib.sh
6
7 test_expect_success 'nested aliases - internal execution' '
8 git config alias.nested-internal-1 nested-internal-2 &&
9 git config alias.nested-internal-2 status &&
10 git nested-internal-1 >output &&
11 test_grep "^On branch " output
12 '
13
14 test_expect_success 'nested aliases - mixed execution' '
15 git config alias.nested-external-1 nested-external-2 &&
16 git config alias.nested-external-2 "!git nested-external-3" &&
17 git config alias.nested-external-3 status &&
18 git nested-external-1 >output &&
19 test_grep "^On branch " output
20 '
21
22 test_expect_success 'looping aliases - internal execution' '
23 git config alias.loop-internal-1 loop-internal-2 &&
24 git config alias.loop-internal-2 loop-internal-3 &&
25 git config alias.loop-internal-3 loop-internal-2 &&
26 test_must_fail git loop-internal-1 2>output &&
27 test_grep "^fatal: alias loop detected: expansion of" output
28 '
29
30 test_expect_success 'detect deprecated commands' '
31 git --list-cmds=deprecated >deprecated &&
32 if read deprecated1 && read deprecated2
33 then
34 test_set_prereq HAVE_DEPRECATED
35 fi <deprecated
36 '
37
38 test_expect_success HAVE_DEPRECATED 'looping aliases - deprecated builtins' '
39 test_config alias.$deprecated1 $deprecated2 &&
40 test_config alias.$deprecated2 $deprecated1 &&
41 cat >expect <<-EOF &&
42 ${SQ}$deprecated1${SQ} is aliased to ${SQ}$deprecated2${SQ}
43 ${SQ}$deprecated2${SQ} is aliased to ${SQ}$deprecated1${SQ}
44 fatal: alias loop detected: expansion of ${SQ}$deprecated1${SQ} does not terminate:
45 $deprecated1 <==
46 $deprecated2 ==>
47 EOF
48 test_must_fail git $deprecated1 -h 2>actual &&
49 test_cmp expect actual
50 '
51
52 # This test is disabled until external loops are fixed, because would block
53 # the test suite for a full minute.
54 #
55 #test_expect_failure 'looping aliases - mixed execution' '
56 # git config alias.loop-mixed-1 loop-mixed-2 &&
57 # git config alias.loop-mixed-2 "!git loop-mixed-1" &&
58 # test_must_fail git loop-mixed-1 2>output &&
59 # test_grep "^fatal: alias loop detected: expansion of" output
60 #'
61
62 test_expect_success 'run-command formats empty args properly' '
63 test_must_fail env GIT_TRACE=1 git frotz a "" b " " c 2>actual.raw &&
64 sed -ne "/run_command:/s/.*trace: run_command: //p" actual.raw >actual &&
65 echo "git-frotz a '\'''\'' b '\'' '\'' c" >expect &&
66 test_cmp expect actual
67 '
68
69 test_expect_success 'tracing a shell alias with arguments shows trace of prepared command' '
70 cat >expect <<-EOF &&
71 trace: start_command: SHELL -c ${SQ}echo \$* "\$@"${SQ} ${SQ}echo \$*${SQ} arg
72 EOF
73 git config alias.echo "!echo \$*" &&
74 env GIT_TRACE=1 git echo arg 2>output &&
75 # redact platform differences
76 sed -n -e "s/^\(trace: start_command:\) .* -c /\1 SHELL -c /p" output >actual &&
77 test_cmp expect actual
78 '
79
80 can_alias_deprecated_builtin () {
81 cmd="$1" &&
82 # some git(1) commands will fail for `-h` (the case for
83 # git-status as of 2025-09-07)
84 test_might_fail git status -h >expect &&
85 test_file_not_empty expect &&
86 test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual &&
87 test_cmp expect actual
88 }
89
90 test_expect_success 'can alias-shadow deprecated builtins' '
91 for cmd in $(git --list-cmds=deprecated)
92 do
93 can_alias_deprecated_builtin "$cmd" || return 1
94 done
95 '
96
97 test_expect_success HAVE_DEPRECATED 'can alias-shadow via two deprecated builtins' '
98 # some git(1) commands will fail... (see above)
99 test_might_fail git status -h >expect &&
100 test_file_not_empty expect &&
101 test_might_fail git -c alias.$deprecated1=$deprecated2 \
102 -c alias.$deprecated2=status $deprecated1 -h >actual &&
103 test_cmp expect actual
104 '
105
106 cannot_alias_regular_builtin () {
107 cmd="$1" &&
108 # some git(1) commands will fail... (see above)
109 test_might_fail git "$cmd" -h >expect &&
110 test_file_not_empty expect &&
111 test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual &&
112 test_cmp expect actual
113 }
114
115 test_expect_success 'cannot alias-shadow a sample of regular builtins' '
116 for cmd in grep check-ref-format interpret-trailers \
117 checkout-index fast-import diagnose rev-list prune
118 do
119 cannot_alias_regular_builtin "$cmd" || return 1
120 done
121 '
122
123 test_expect_success 'alias without value reports error' '
124 test_when_finished "git config --unset alias.noval" &&
125 cat >>.git/config <<-\EOF &&
126 [alias]
127 noval
128 EOF
129 test_must_fail git noval 2>error &&
130 test_grep "alias.noval" error
131 '
132
133 test_expect_success 'subsection syntax works' '
134 test_config alias.testnew.command "!echo ran-subsection" &&
135 git testnew >output &&
136 test_grep "ran-subsection" output
137 '
138
139 test_expect_success 'simple dotted alias syntax still works' '
140 test_config alias.simple.dotted "!echo ran-simple-dotted" &&
141 git simple.dotted >output &&
142 test_grep "ran-simple-dotted" output
143 '
144
145 test_expect_success 'subsection syntax only accepts command key' '
146 test_config alias.invalid.notcommand value &&
147 test_must_fail git invalid 2>error &&
148 test_grep -i "not a git command" error
149 '
150
151 test_expect_success 'subsection syntax requires value for command' '
152 test_when_finished "git config --remove-section alias.noval" &&
153 cat >>.git/config <<-\EOF &&
154 [alias "noval"]
155 command
156 EOF
157 test_must_fail git noval 2>error &&
158 test_grep "alias.noval.command" error
159 '
160
161 test_expect_success 'simple syntax is case-insensitive' '
162 test_config alias.LegacyCase "!echo ran-legacy" &&
163 git legacycase >output &&
164 test_grep "ran-legacy" output
165 '
166
167 test_expect_success 'subsection syntax is case-sensitive' '
168 test_config alias.SubCase.command "!echo ran-upper" &&
169 test_config alias.subcase.command "!echo ran-lower" &&
170 git SubCase >upper.out &&
171 git subcase >lower.out &&
172 test_grep "ran-upper" upper.out &&
173 test_grep "ran-lower" lower.out
174 '
175
176 test_expect_success 'UTF-8 alias with Swedish characters' '
177 test_config alias."förgrena".command "!echo ran-swedish" &&
178 git förgrena >output &&
179 test_grep "ran-swedish" output
180 '
181
182 test_expect_success 'UTF-8 alias with CJK characters' '
183 test_config alias."分支".command "!echo ran-cjk" &&
184 git 分支 >output &&
185 test_grep "ran-cjk" output
186 '
187
188 test_expect_success 'alias with spaces in name' '
189 test_config alias."test name".command "!echo ran-spaces" &&
190 git "test name" >output &&
191 test_grep "ran-spaces" output
192 '
193
194 test_expect_success 'subsection aliases listed in help -a' '
195 test_config alias."förgrena".command "!echo test" &&
196 git help -a >output &&
197 test_grep "förgrena" output
198 '
199
200 test_expect_success 'simple dotted aliases listed in help -a' '
201 test_config alias.simple.listed "!echo test" &&
202 git help -a >output &&
203 test_grep "simple.listed" output
204 '
205
206 test_expect_success 'empty subsection treated as no subsection' '
207 test_config "alias..something" "!echo foobar" &&
208 git something >actual &&
209 echo foobar >expect &&
210 test_cmp expect actual
211 '
212
213 test_expect_success 'alias with leading dot via subsection syntax' '
214 test_config alias.".something".command "!echo foobar" &&
215 git .something >actual &&
216 echo foobar >expect &&
217 test_cmp expect actual
218 '
219
220 test_done