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
This commit is contained in:
Junio C Hamano
2024-06-10 10:30:38 -07:00
3 changed files with 34 additions and 5 deletions

View File

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

View File

@ -746,6 +746,8 @@ fail_pipe:
goto end_of_spawn;
}
trace_argv_printf(&argv.v[1], "trace: start_command:");
if (pipe(notify_pipe))
notify_pipe[0] = notify_pipe[1] = -1;
@ -913,6 +915,7 @@ end_of_spawn:
else if (cmd->use_shell)
cmd->args.v = prepare_shell_cmd(&nargv, sargv);
trace_argv_printf(cmd->args.v, "trace: start_command:");
cmd->pid = mingw_spawnvpe(cmd->args.v[0], cmd->args.v,
(char**) cmd->env.v,
cmd->dir, fhin, fhout, fherr);

View File

@ -44,4 +44,15 @@ test_expect_success 'run-command formats empty args properly' '
test_cmp expect actual
'
test_expect_success 'tracing a shell alias with arguments shows trace of prepared command' '
cat >expect <<-EOF &&
trace: start_command: SHELL -c ${SQ}echo \$* "\$@"${SQ} ${SQ}echo \$*${SQ} arg
EOF
git config alias.echo "!echo \$*" &&
env GIT_TRACE=1 git echo arg 2>output &&
# redact platform differences
sed -n -e "s/^\(trace: start_command:\) .* -c /\1 SHELL -c /p" output >actual &&
test_cmp expect actual
'
test_done