{"thread":{"id":"4666","subject":"[RFC] git --trace: trace command execution","startedAt":"2006-06-25T10:57:09Z","lastAt":"2006-06-29T18:06:21Z","messageCount":10,"participants":["Matthias Lederhofer","Junio C Hamano","Johannes Schindelin","Petr Baudis","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"22543","messageId":"E1FuSIf-0004jK-Tp@moooo.ath.cx","threadId":"4666","inReplyTo":null,"subject":"[RFC] git --trace: trace command execution","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T10:57:09Z","receivedAt":"2006-06-25T10:57:09Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Show parameters to execve/builtin-cmds before executing them. This\nversion does not yet have a parameter --trace to git to enable this I\njust want to get feedback first :)\n\nI think this is quite useful to debug what is going on since a command\nmay be another program (shell/python/perl/.. script etc) or just an\nalias for a internal command. Before that many commands became\nbuilt-ins this was quite easy to do with strace.\n\nExample:\n% git repo-config alias.showtag\ntrace: exec: /home/matled/local/stow/git/bin/git-repo-config\nalias.showtag\n% git showtag v1.4.1-rc1 > /dev/null\ntrace: exec: /home/matled/local/stow/git/bin/git-showtag v1.4.1-rc1\ntrace: exec failed: No such file or directory\ntrace: built-in command: git cat-file tag v1.4.1-rc1\n% git showtag 'a b \"c\" `d` $e \\f'\ntrace: exec: /home/matled/local/stow/git/bin/git-showtag \"a b \\\"c\\\" \\`d\\` \\$e \\\\f\"\ntrace: exec failed: No such file or directory\ntrace: built-in command: git cat-file tag \"a b \\\"c\\\" \\`d\\` \\$e \\\\f\"\nfatal: Not a valid object name a b \"c\" `d` $e \\f\n% git cat-file tag \"a b \\\"c\\\" \\`d\\` \\$e \\\\f\"\ntrace: built-in command: git cat-file tag \"a b \\\"c\\\" \\`d\\` \\$e \\\\f\"\nfatal: Not a valid object name a b \"c\" `d` $e \\f\n\nprint_shell_escape will escape the arguments to be used as strings in\nthe shell to prevent ambiguity with spaces and other special\ncharacters and make them copy-and-pastable.\n\n---\n exec_cmd.c |   42 ++++++++++++++++++++++++++++++++++++++++++\n exec_cmd.h |    1 +\n git.c      |   10 ++++++++++\n 3 files changed, 53 insertions(+), 0 deletions(-)\n\ndiff --git a/exec_cmd.c b/exec_cmd.c\nindex c1539d1..85afbf3 100644\n--- a/exec_cmd.c\n+++ b/exec_cmd.c\n@@ -87,6 +87,16 @@ int execv_git_cmd(const char **argv)\n \t\t\tbreak;\n \t\t}\n \n+\t\tfprintf(stderr, \"trace: exec: \");\n+\t\tprint_shell_escape(stderr, git_command);\n+\t\tconst char **p = argv;\n+\t\twhile (*(++p)) {\n+\t\t\tputc(' ', stderr);\n+\t\t\tprint_shell_escape(stderr, *p);\n+\t\t}\n+\t\tputc('\\n', stderr);\n+\t\tfflush(stderr);\n+\n \t\t/* argv[0] must be the git command, but the argv array\n \t\t * belongs to the caller, and my be reused in\n \t\t * subsequent loop iterations. Save argv[0] and\n@@ -98,6 +108,8 @@ int execv_git_cmd(const char **argv)\n \n \t\t/* execve() can only ever return if it fails */\n \t\texecve(git_command, (char **)argv, environ);\n+\t\tfprintf(stderr, \"trace: exec failed: %s\\n\", strerror(errno));\n+\t\tfflush(stderr);\n \n \t\targv[0] = tmp;\n \t}\n@@ -128,3 +140,33 @@ int execl_git_cmd(const char *cmd,...)\n \targv[argc] = NULL;\n \treturn execv_git_cmd(argv);\n }\n+\n+void print_shell_escape(FILE *stream, const char *s)\n+{\n+\tconst char *c = s;\n+\tshort int quote = 0;\n+\twhile (*c) {\n+\t\tif (*c == '\"' || *c == '`' || *c == '$' || *c == '\\\\' ||\n+\t\t\tisspace(*c))\n+\t\t{\n+\t\t\tquote = 1;\n+\t\t\tbreak;\n+\t\t}\n+\t\t++c;\n+\t}\n+\n+\tif (!quote) {\n+\t\tfputs(s, stream);\n+\t\treturn;\n+\t}\n+\n+\tputc('\"', stream);\n+\tc = s;\n+\twhile (*c) {\n+\t\tif (*c == '\"' || *c == '`' || *c == '$' || *c == '\\\\')\n+\t\t\tputc('\\\\', stream);\n+\t\tputc(*c, stream);\n+\t\t++c;\n+\t}\n+\tputc('\"', stream);\n+}\ndiff --git a/exec_cmd.h b/exec_cmd.h\nindex 989621f..8b237fa 100644\n--- a/exec_cmd.h\n+++ b/exec_cmd.h\n@@ -5,6 +5,7 @@ extern void git_set_exec_path(const char\n extern const char* git_exec_path(void);\n extern int execv_git_cmd(const char **argv); /* NULL terminated */\n extern int execl_git_cmd(const char *cmd, ...);\n+extern void print_shell_escape(FILE *stream, const char *s);\n \n \n #endif /* __GIT_EXEC_CMD_H_ */\ndiff --git a/git.c b/git.c\nindex 94e9a4a..361fb25 100644\n--- a/git.c\n+++ b/git.c\n@@ -198,6 +198,16 @@ static void handle_internal_command(int \n \t\tstruct cmd_struct *p = commands+i;\n \t\tif (strcmp(p->cmd, cmd))\n \t\t\tcontinue;\n+\n+\t\tfprintf(stderr, \"trace: built-in command: git\");\n+\t\tint i;\n+\t\tfor (i = 0; i < argc; ++i) {\n+\t\t\tputc(' ', stderr);\n+\t\t\tprint_shell_escape(stderr, argv[i]);\n+\t\t}\n+\t\tputc('\\n', stderr);\n+\t\tfflush(stderr);\n+\n \t\texit(p->fn(argc, argv, envp));\n \t}\n }\n-- \n1.4.GIT\n"},{"id":"22550","messageId":"7v3bdtv4h3.fsf@assigned-by-dhcp.cox.net","threadId":"4666","inReplyTo":"E1FuSIf-0004jK-Tp@moooo.ath.cx","subject":"Re: [RFC] git --trace: trace command execution","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-25T11:50:48Z","receivedAt":"2006-06-25T11:50:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> Show parameters to execve/builtin-cmds before executing them. This\n> version does not yet have a parameter --trace to git to enable this I\n> just want to get feedback first :)\n>\n> I think this is quite useful to debug what is going on since a command\n> may be another program (shell/python/perl/.. script etc) or just an\n> alias for a internal command. Before that many commands became\n> built-ins this was quite easy to do with strace.\n\nInteresting.  Debugging one's alias entries would be helped with\nthis I would imagine, and for that you would want something like\nthis:\n\n> Example:\n> % git showtag v1.4.1-rc1 > /dev/null\n> trace: exec: /home/matled/local/stow/git/bin/git-showtag v1.4.1-rc1\n> trace: exec failed: No such file or directory\n* trace: expanded alias \"showtag\" => \"cat-file tag\"\n> trace: built-in command: git cat-file tag v1.4.1-rc1\n\nBy the way \"git cat-file -p\" or \"git verify-tag -v\" might be\nmore pleasant to view a tag since they make the tagger timestamp\nhuman readable.\n\n> print_shell_escape will escape the arguments to be used as strings in\n> the shell to prevent ambiguity with spaces and other special\n> characters and make them copy-and-pastable.\n\nMight be worth reusing quote.c::sq_quote(), perhaps?\n"},{"id":"22554","messageId":"E1FuU5a-0000u3-Bc@moooo.ath.cx","threadId":"4666","inReplyTo":"7v3bdtv4h3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] git --trace: trace command execution","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T12:51:46Z","receivedAt":"2006-06-25T12:51:46Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> Interesting.  Debugging one's alias entries would be helped with\n> this I would imagine, and for that you would want something like\n> this:\n> \n> > Example:\n> > % git showtag v1.4.1-rc1 > /dev/null\n> > trace: exec: /home/matled/local/stow/git/bin/git-showtag v1.4.1-rc1\n> > trace: exec failed: No such file or directory\n> * trace: expanded alias \"showtag\" => \"cat-file tag\"\nThat's a good idea, I'll integrate that.\n\n> By the way \"git cat-file -p\" or \"git verify-tag -v\" might be\n> more pleasant to view a tag since they make the tagger timestamp\n> human readable.\nOk, yesterday I was searching for something to see the annotation of a\ntag. verify-tag -v looks quite much like that, is there any other way\nto read this? Or in general: how do I work with tags? I want to build\na version tagged as v1.2 so currently I'll do\n> git checkout -b 1.2 v1.2\nand built it. But then I've to type the version number twice (typing\nit once is annoying enough :)) and I've to type it once more to get\nthe tag annotation.\n\n> Might be worth reusing quote.c::sq_quote(), perhaps?\nOh, sure, did not know about this. This would result in a loop of\nmalloc'ing memory for the buffer. Is this ok? Or should I add a\nfunction like sq_quote which takes a stream and writes to it?\n\nSo for the --trace part I think an environment variable GIT_TRACE is\nmore suitable for this because children inherit this. So running git\nstatus will show what internal commands the shell script uses.\nOtherwise I see no way to pass the --trace option down because an\nextern program like git-status, git-annotate etc will not accept\nparameters which can be passed to `git'.\n"},{"id":"22558","messageId":"E1FuV62-0004Jd-Ve@moooo.ath.cx","threadId":"4666","inReplyTo":"7v3bdtv4h3.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T13:56:18Z","receivedAt":"2006-06-25T13:56:18Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"With the environment variable GIT_TRACE set git will show\n - alias expansion\n - built-in command execution\n - external command execution\non stderr.\n\nSigned-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nExamples:\n% GIT_TRACE=1 git status > /dev/null\ntrace: exec: '/home/matled/local/stow/git/bin/git-status'\ntrace: built-in: git 'rev-parse' '--git-dir'\ntrace: built-in: git 'rev-parse' '--show-cdup'\ntrace: built-in: git 'update-index' '-q' '--unmerged' '--refresh'\ntrace: built-in: git 'diff-index' '-M' '--cached' '--name-status' \\\n    '--diff-filter=MDTCRA' 'HEAD'\ntrace: built-in: git 'diff-files' '--name-status'\ntrace: built-in: git 'ls-files' '-z' '--others' '--directory' \\\n    '--no-empty-directory' '--exclude-from=.git/info/exclude' \\\n    '--exclude-per-directory=.gitignore'\n\nThis seems to be quite useful to find out how tools do things and for\ndebugging.\n\n% GIT_TRACE=1 git showtag v1.4.0 > /dev/null\ntrace: exec: '/home/matled/local/stow/git/bin/git-showtag' 'v1.4.0'\ntrace: exec failed: No such file or directory\ntrace: alias expansion: showtag => 'cat-file' 'tag'\ntrace: built-in: git 'cat-file' 'tag' 'v1.4.0'\n\n% GIT_TRACE=1 git l > /dev/null\ntrace: exec: '/home/matled/local/stow/git/bin/git-l'\ntrace: exec failed: No such file or directory\ntrace: alias expansion: l => 'log' '-p'\ntrace: built-in: git 'log' '-p'\n\n Documentation/git.txt |    7 +++++++\n exec_cmd.c            |   19 +++++++++++++++++++\n git.c                 |   25 +++++++++++++++++++++++++\n quote.c               |   17 +++++++++++++++++\n quote.h               |    1 +\n 5 files changed, 69 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex 51f20c6..603c474 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -615,6 +615,13 @@ git Diffs\n \tgitlink:git-diff-files[1];\n \tgitlink:git-diff-tree[1]\n \n+other\n+~~~~~\n+'GIT_TRACE'::\n+\tIf this variable is set git will print `trace:` messages on\n+\tstderr telling about alias expansion, built-in command\n+\texecution and external command execution.\n+\n Discussion[[Discussion]]\n ------------------------\n include::README[]\ndiff --git a/exec_cmd.c b/exec_cmd.c\nindex c1539d1..f2133ec 100644\n--- a/exec_cmd.c\n+++ b/exec_cmd.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"exec_cmd.h\"\n+#include \"quote.h\"\n #define MAX_ARGS\t32\n \n extern char **environ;\n@@ -96,9 +97,27 @@ int execv_git_cmd(const char **argv)\n \t\ttmp = argv[0];\n \t\targv[0] = git_command;\n \n+\t\tif (getenv(\"GIT_TRACE\")) {\n+\t\t\tfputs(\"trace: exec:\", stderr);\n+\t\t\tconst char **p = argv;\n+\t\t\twhile (*p) {\n+\t\t\t\tfputc(' ', stderr);\n+\t\t\t\tsq_quote_print(stderr, *p);\n+\t\t\t\t++p;\n+\t\t\t}\n+\t\t\tputc('\\n', stderr);\n+\t\t\tfflush(stderr);\n+\t\t}\n+\n \t\t/* execve() can only ever return if it fails */\n \t\texecve(git_command, (char **)argv, environ);\n \n+\t\tif (getenv(\"GIT_TRACE\")) {\n+\t\t\tfprintf(stderr, \"trace: exec failed: %s\\n\",\n+\t\t\t\tstrerror(errno));\n+\t\t\tfflush(stderr);\n+\t\t}\n+\n \t\targv[0] = tmp;\n \t}\n \treturn -1;\ndiff --git a/git.c b/git.c\nindex 94e9a4a..8b060e8 100644\n--- a/git.c\n+++ b/git.c\n@@ -11,6 +11,7 @@ #include <stdarg.h>\n #include \"git-compat-util.h\"\n #include \"exec_cmd.h\"\n #include \"cache.h\"\n+#include \"quote.h\"\n \n #include \"builtin.h\"\n \n@@ -119,6 +120,18 @@ static int handle_alias(int *argcp, cons\n \t\t\tif (!strcmp(alias_command, new_argv[0]))\n \t\t\t\tdie(\"recursive alias: %s\", alias_command);\n \n+\t\t\tif (getenv(\"GIT_TRACE\")) {\n+\t\t\t\tint i;\n+\t\t\t\tfprintf(stderr, \"trace: alias expansion: %s =>\",\n+\t\t\t\t\talias_command);\n+\t\t\t\tfor (i = 0; i < count; ++i) {\n+\t\t\t\t\tfputc(' ', stderr);\n+\t\t\t\t\tsq_quote_print(stderr, new_argv[i]);\n+\t\t\t\t}\n+\t\t\t\tfputc('\\n', stderr);\n+\t\t\t\tfflush(stderr);\n+\t\t\t}\n+\n \t\t\t/* insert after command name */\n \t\t\tif (*argcp > 1) {\n \t\t\t\tnew_argv = realloc(new_argv, sizeof(char*) *\n@@ -198,6 +211,18 @@ static void handle_internal_command(int \n \t\tstruct cmd_struct *p = commands+i;\n \t\tif (strcmp(p->cmd, cmd))\n \t\t\tcontinue;\n+\n+\t\tif (getenv(\"GIT_TRACE\")) {\n+\t\t\tint i;\n+\t\t\tfprintf(stderr, \"trace: built-in: git\");\n+\t\t\tfor (i = 0; i < argc; ++i) {\n+\t\t\t\tfputc(' ', stderr);\n+\t\t\t\tsq_quote_print(stderr, argv[i]);\n+\t\t\t}\n+\t\t\tputc('\\n', stderr);\n+\t\t\tfflush(stderr);\n+\t\t}\n+\n \t\texit(p->fn(argc, argv, envp));\n \t}\n }\ndiff --git a/quote.c b/quote.c\nindex dcc2326..2ca18e8 100644\n--- a/quote.c\n+++ b/quote.c\n@@ -45,6 +45,23 @@ size_t sq_quote_buf(char *dst, size_t n,\n \treturn len;\n }\n \n+void sq_quote_print(FILE *stream, const char *src)\n+{\n+\tchar c;\n+\n+\tfputc('\\'', stream);\n+\twhile ((c = *src++)) {\n+\t\tif (need_bs_quote(c)) {\n+\t\t\tfputs(\"'\\\\\", stream);\n+\t\t\tfputc(c, stream);\n+\t\t\tfputc('\\'', stream);\n+\t\t} else {\n+\t\t\tfputc(c, stream);\n+\t\t}\n+\t}\n+\tfputc('\\'', stream);\n+}\n+\n char *sq_quote(const char *src)\n {\n \tchar *buf;\ndiff --git a/quote.h b/quote.h\nindex c1ab378..fc5481e 100644\n--- a/quote.h\n+++ b/quote.h\n@@ -29,6 +29,7 @@ #include <stdio.h>\n  */\n \n extern char *sq_quote(const char *src);\n+extern void sq_quote_print(FILE *stream, const char *src);\n extern size_t sq_quote_buf(char *dst, size_t n, const char *src);\n \n /* This unwraps what sq_quote() produces in place, but returns\n-- \n1.4.1.rc1.gfa6c9-dirty\n"},{"id":"22561","messageId":"Pine.LNX.4.63.0606251607090.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4666","inReplyTo":"E1FuV62-0004Jd-Ve@moooo.ath.cx","subject":"Re: [PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-25T14:11:48Z","receivedAt":"2006-06-25T14:11:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 25 Jun 2006, Matthias Lederhofer wrote:\n\n> With the environment variable GIT_TRACE set git will show\n>  - alias expansion\n>  - built-in command execution\n>  - external command execution\n> on stderr.\n\nNice.\n\nCiao,\nDscho\n\nP.S.: Now we only have to convert all \"git-\" invocations in the scripts to\n\"git \" invocations so we can benefit from it. But that would mean two \nforks instead of one for the non-builtins. Hmm.\n"},{"id":"22562","messageId":"20060625142203.GF21864@pasky.or.cz","threadId":"4666","inReplyTo":"Pine.LNX.4.63.0606251607090.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-25T14:22:03Z","receivedAt":"2006-06-25T14:22:03Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"  Hi,\n\nDear diary, on Sun, Jun 25, 2006 at 04:11:48PM CEST, I got a letter\nwhere Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...\n> P.S.: Now we only have to convert all \"git-\" invocations in the scripts to\n> \"git \" invocations so we can benefit from it. But that would mean two \n> forks instead of one for the non-builtins. Hmm.\n\n  actually this is a myth - not two fork()s since 'git' has no reason to\nfork; only two execve()s in line after a single fork().\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nA person is just about as big as the things that make them angry.\n"},{"id":"22570","messageId":"E1FuXBk-0001SG-3n@moooo.ath.cx","threadId":"4666","inReplyTo":"Pine.LNX.4.63.0606251607090.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T16:10:20Z","receivedAt":"2006-06-25T16:10:20Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> Hi,\n> \n> On Sun, 25 Jun 2006, Matthias Lederhofer wrote:\n> \n> > With the environment variable GIT_TRACE set git will show\n> >  - alias expansion\n> >  - built-in command execution\n> >  - external command execution\n> > on stderr.\n> \n> Nice.\nThanks :)\n\n> P.S.: Now we only have to convert all \"git-\" invocations in the scripts to\n> \"git \" invocations so we can benefit from it. But that would mean two \n> forks instead of one for the non-builtins. Hmm.\n\nWhy do we not use this policy:\n\ngit-* is guaranteed to be the normal command without any strange alias\nexpansion, default parameters or something else a script does not like\nto be changed in the commands. So all scripts use git-*, this will\nprevent a double exec. The path to git-* should be obtained using git\n--exec-path in the beginnig.\n\ngit <command> is to be used by the user if he wants aliases, default\nparameters and other fancy stuff.\n\nUsing this policy the user can always get the normal behaviour and it\nis possible to shadown built-in commands etc.\n"},{"id":"22581","messageId":"Pine.LNX.4.63.0606260129410.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4666","inReplyTo":"E1FuXBk-0001SG-3n@moooo.ath.cx","subject":"Re: [PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-25T23:30:42Z","receivedAt":"2006-06-25T23:30:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 25 Jun 2006, Matthias Lederhofer wrote:\n\n> > P.S.: Now we only have to convert all \"git-\" invocations in the scripts to\n> > \"git \" invocations so we can benefit from it. But that would mean two \n> > forks instead of one for the non-builtins. Hmm.\n> \n> Why do we not use this policy:\n> \n> git-* is guaranteed to be the normal command without any strange alias\n> expansion, default parameters or something else a script does not like\n> to be changed in the commands. So all scripts use git-*, this will\n> prevent a double exec. The path to git-* should be obtained using git\n> --exec-path in the beginnig.\n\nThat still leaves my problem: GIT_TRACE=1 on scripts is incomplete.\n\nCiao,\nDscho\n"},{"id":"22748","messageId":"E1Fveg1-0006u8-D7@moooo.ath.cx","threadId":"4666","inReplyTo":"Pine.LNX.4.63.0606260129410.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] GIT_TRACE: show which built-in/external commands are executed","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-28T18:22:13Z","receivedAt":"2006-06-28T18:22:13Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> That still leaves my problem: GIT_TRACE=1 on scripts is incomplete.\nOk, I see what you mean.\n\nThis actually affects all scripts which are called as git-foo instead\nof git foo (but built-in commands show up anyway). So I'd add a\nwarning to the documentation in which cases GIT_TRACE will not show\nthat a command is executed.\nIn the git repository I found 47 shell scripts (git-* without the\nheader file) which would be affected. Searching for all occurences of\ngit-(one of those shell-scripts) I found 50 lines of code which use\nit. If there is any interest in changing this I can try to change\nthis.\n"},{"id":"22810","messageId":"e814qm$sa$1@sea.gmane.org","threadId":"4666","inReplyTo":"7v3bdtv4h3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC] git --trace: trace command execution","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-06-29T18:06:21Z","receivedAt":"2006-06-29T18:06:21Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> By the way \"git cat-file -p\" or \"git verify-tag -v\" might be\n> more pleasant to view a tag since they make the tagger timestamp\n> human readable.\n\nInteresting, -p makes tagger timestamp human readable, but not author or\ncommiter:\n\n$ git cat-file -p `cat .git/refs/tags/v1.4.0`\ntagger Junio C Hamano <junkio@cox.net> Sat Jun 10 12:43:37 2006 -0700\n\n$ git cat-file -p `cat .git/refs/heads/origin`\nauthor Johannes Schindelin <Johannes.Schindelin@gmx.de> 1151491527 +0200\ncommitter Junio C Hamano <junkio@cox.net> 1151492136 -0700\n\nIs it intended, or a bug/missing feature (git 1.4.0)?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"}]}