Skip to content

Commit 718b50e

Browse files
committed
Merge branch 'iw/trace-argv-on-alias'
The alias-expanded command lines are logged to the trace output. * iw/trace-argv-on-alias: run-command: show prepared command Documentation: alias: add notes on shell expansion Documentation: alias: rework notes into points
2 parents 1b76f06 + 291ef5b commit 718b50e

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

Documentation/config/alias.txt

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@ If the alias expansion is prefixed with an exclamation point,
2121
it will be treated as a shell command. For example, defining
2222
`alias.new = !gitk --all --not ORIG_HEAD`, the invocation
2323
`git new` is equivalent to running the shell command
24-
`gitk --all --not ORIG_HEAD`. Note that shell commands will be
25-
executed from the top-level directory of a repository, which may
26-
not necessarily be the current directory.
27-
`GIT_PREFIX` is set as returned by running `git rev-parse --show-prefix`
28-
from the original current directory. See linkgit:git-rev-parse[1].
24+
`gitk --all --not ORIG_HEAD`. Note:
25+
+
26+
* Shell commands will be executed from the top-level directory of a
27+
repository, which may not necessarily be the current directory.
28+
* `GIT_PREFIX` is set as returned by running `git rev-parse --show-prefix`
29+
from the original current directory. See linkgit:git-rev-parse[1].
30+
* Shell command aliases always receive any extra arguments provided to
31+
the Git command-line as positional arguments.
32+
** Care should be taken if your shell alias is a "one-liner" script
33+
with multiple commands (e.g. in a pipeline), references multiple
34+
arguments, or is otherwise not able to handle positional arguments
35+
added at the end. For example: `alias.cmd = "!echo $1 | grep $2"`
36+
called as `git cmd 1 2` will be executed as 'echo $1 | grep $2
37+
1 2', which is not what you want.
38+
** A convenient way to deal with this is to write your script
39+
operations in an inline function that is then called with any
40+
arguments from the command-line. For example `alias.cmd = "!c() {
41+
echo $1 | grep $2 ; }; c" will correctly execute the prior example.
42+
** Setting `GIT_TRACE=1` can help you debug the command being run for
43+
your alias.

run-command.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,8 @@ int start_command(struct child_process *cmd)
746746
goto end_of_spawn;
747747
}
748748

749+
trace_argv_printf(&argv.v[1], "trace: start_command:");
750+
749751
if (pipe(notify_pipe))
750752
notify_pipe[0] = notify_pipe[1] = -1;
751753

@@ -913,6 +915,7 @@ int start_command(struct child_process *cmd)
913915
else if (cmd->use_shell)
914916
cmd->args.v = prepare_shell_cmd(&nargv, sargv);
915917

918+
trace_argv_printf(cmd->args.v, "trace: start_command:");
916919
cmd->pid = mingw_spawnvpe(cmd->args.v[0], cmd->args.v,
917920
(char**) cmd->env.v,
918921
cmd->dir, fhin, fhout, fherr);

t/t0014-alias.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,15 @@ test_expect_success 'run-command formats empty args properly' '
4444
test_cmp expect actual
4545
'
4646

47+
test_expect_success 'tracing a shell alias with arguments shows trace of prepared command' '
48+
cat >expect <<-EOF &&
49+
trace: start_command: SHELL -c ${SQ}echo \$* "\$@"${SQ} ${SQ}echo \$*${SQ} arg
50+
EOF
51+
git config alias.echo "!echo \$*" &&
52+
env GIT_TRACE=1 git echo arg 2>output &&
53+
# redact platform differences
54+
sed -n -e "s/^\(trace: start_command:\) .* -c /\1 SHELL -c /p" output >actual &&
55+
test_cmp expect actual
56+
'
57+
4758
test_done

0 commit comments

Comments
 (0)