From: Junio C Hamano <gitster@pobox.com>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: Eyvind Bernhardsen <eyvind-git-list@orakel.ntnu.no>,
Nicolas Pitre <nico@cam.org>,
Nguyen Thai Ngoc Duy <pclouds@gmail.com>, Jan Hudec <bulb@ucw.cz>,
git@vger.kernel.org
Subject: Re: [PATCH 0/3] Call builtin functions directly, was Re: [PATCH] transport.c: call dash-less form of receive-pack and upload-pack on remote
Date: Sat, 01 Dec 2007 21:19:54 -0800 [thread overview]
Message-ID: <7v3aul1xmt.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: Pine.LNX.4.64.0712020146240.27959@racer.site
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Okay, I bit the apple and tried to move the builtins into the library, and
> rename handle_internal_command into execv_git_builtin(), moving it into
> exec-cmd.c.
>
> Big mistake.
I really feel this should not go in. Anything called exec _should_
assure the callers that the new command will start from a clean slate,
and the way to give that assurance is by actually doing exec(), not
introducing "clean-up" functions for random things we can think of (like
cached objects) and risking of forgetting some others. I do not think
the complexity is worth it.
The first step we have decided to take is to move git-foo form out of
users' PATH. This would reduce the cluttered PATH problem, and it means
not all of external commands have to become built-ins on a single flag
day. I also think it has always been a nice touch that we allowed users
to drop their own custom git-foo script to their path and call "git foo"
as if it is part of the official git suite, so spawning commands in
git-foo form needs to be supported via GIT_EXEC_PATH even if everything
eventually becomes built-in.
So I would prefer doing something like this instead for v1.5.5 (see
the top of updated release notes for 1.5.4 for deprecation notice).
* execv_git_cmd() function will exec "git" with the given subcommand
and its arguments;
* The command dispatcher of git potty itself will first try the
built-ins, and then try externals in dash form (which cannot be done
with execv_git_cmd() anymore), and then aliases.
* Just to be nice, we allow git-shell to treat "git foo arg" as if
"git-foo arg" was given, but it continues to use execv_git_cmd(), and
starts from a clean slate.
---
exec_cmd.c | 31 ++++++++++++-------------------
git.c | 32 +++++++++++++++++++++++++++++++-
shell.c | 26 +++++++++++++++-----------
3 files changed, 58 insertions(+), 31 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index 2d0a758..10b2908 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -65,32 +65,25 @@ void setup_path(const char *cmd_path)
int execv_git_cmd(const char **argv)
{
- struct strbuf cmd;
- const char *tmp;
-
- strbuf_init(&cmd, 0);
- strbuf_addf(&cmd, "git-%s", argv[0]);
+ int argc;
+ const char **nargv;
- /*
- * argv[0] must be the git command, but the argv array
- * belongs to the caller, and may be reused in
- * subsequent loop iterations. Save argv[0] and
- * restore it on error.
- */
- tmp = argv[0];
- argv[0] = cmd.buf;
+ for (argc = 0; argv[argc]; argc++)
+ ; /* just counting */
+ nargv = xmalloc(sizeof(*nargv) * (argc + 2));
- trace_argv_printf(argv, -1, "trace: exec:");
+ nargv[0] = "git";
+ for (argc = 0; argv[argc]; argc++)
+ nargv[argc + 1] = argv[argc];
+ nargv[argc + 1] = NULL;
+ trace_argv_printf(nargv, -1, "trace: exec:");
/* execvp() can only ever return if it fails */
- execvp(cmd.buf, (char **)argv);
+ execvp("git", (char **)nargv);
trace_printf("trace: exec failed: %s\n", strerror(errno));
- argv[0] = tmp;
-
- strbuf_release(&cmd);
-
+ free(nargv);
return -1;
}
diff --git a/git.c b/git.c
index 01bbbc7..d690426 100644
--- a/git.c
+++ b/git.c
@@ -382,6 +382,36 @@ static void handle_internal_command(int argc, const char **argv)
}
}
+static void execv_dashed_external(const char **argv)
+{
+ struct strbuf cmd;
+ const char *tmp;
+
+ strbuf_init(&cmd, 0);
+ strbuf_addf(&cmd, "git-%s", argv[0]);
+
+ /*
+ * argv[0] must be the git command, but the argv array
+ * belongs to the caller, and may be reused in
+ * subsequent loop iterations. Save argv[0] and
+ * restore it on error.
+ */
+ tmp = argv[0];
+ argv[0] = cmd.buf;
+
+ trace_argv_printf(argv, -1, "trace: exec:");
+
+ /* execvp() can only ever return if it fails */
+ execvp(cmd.buf, (char **)argv);
+
+ trace_printf("trace: exec failed: %s\n", strerror(errno));
+
+ argv[0] = tmp;
+
+ strbuf_release(&cmd);
+}
+
+
int main(int argc, const char **argv)
{
const char *cmd = argv[0] ? argv[0] : "git-help";
@@ -445,7 +475,7 @@ int main(int argc, const char **argv)
handle_internal_command(argc, argv);
/* .. then try the external ones */
- execv_git_cmd(argv);
+ execv_dashed_external(argv);
/* It could be an alias -- this works around the insanity
* of overriding "git log" with "git show" by having
diff --git a/shell.c b/shell.c
index 9826109..729797c 100644
--- a/shell.c
+++ b/shell.c
@@ -19,17 +19,13 @@ static int do_generic_cmd(const char *me, char *arg)
return execv_git_cmd(my_argv);
}
-static int do_cvs_cmd(const char *me, char *arg)
+static int do_cvs_cmd(void)
{
const char *cvsserver_argv[3] = {
"cvsserver", "server", NULL
};
- if (!arg || strcmp(arg, "server"))
- die("git-cvsserver only handles server: %s", arg);
-
setup_path(NULL);
-
return execv_git_cmd(cvsserver_argv);
}
@@ -40,7 +36,6 @@ static struct commands {
} cmd_list[] = {
{ "git-receive-pack", do_generic_cmd },
{ "git-upload-pack", do_generic_cmd },
- { "cvs", do_cvs_cmd },
{ NULL },
};
@@ -49,15 +44,24 @@ int main(int argc, char **argv)
char *prog;
struct commands *cmd;
+ /*
+ * Special hack to pretend to be a CVS server
+ */
if (argc == 2 && !strcmp(argv[1], "cvs server"))
- argv--;
- /* We want to see "-c cmd args", and nothing else */
- else if (argc != 3 || strcmp(argv[1], "-c"))
+ exit(do_cvs_cmd());
+
+ /*
+ * We do not accept anything but "-c" followed by "cmd arg",
+ * where "cmd" is a very limited subset of git commands.
+ */
+ if (argc != 3 || strcmp(argv[1], "-c"))
die("What do you think I am? A shell?");
prog = argv[2];
- argv += 2;
- argc -= 2;
+ if (!strncmp(prog, "git", 3) && isspace(prog[3]))
+ /* Accept "git foo" as if the caller said "git-foo". */
+ prog[3] = '-';
+
for (cmd = cmd_list ; cmd->name ; cmd++) {
int len = strlen(cmd->name);
char *arg;
next prev parent reply other threads:[~2007-12-02 5:20 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-27 15:02 [PATCH RFC] Move all dashed form git commands to libexecdir Nguyễn Thái Ngọc Duy
2007-11-27 15:12 ` Johannes Schindelin
2007-11-27 15:25 ` Nicolas Pitre
2007-11-27 16:04 ` [PATCH] " Nguyễn Thái Ngoc Duy
2007-11-27 16:18 ` Johannes Schindelin
2007-11-28 0:07 ` Jan Hudec
2007-11-28 1:13 ` Junio C Hamano
2007-11-28 8:18 ` Jan Hudec
2007-11-28 8:36 ` Nguyen Thai Ngoc Duy
2007-11-28 23:14 ` Junio C Hamano
2007-11-28 23:40 ` Johannes Schindelin
2007-11-28 23:48 ` Junio C Hamano
2007-11-29 0:01 ` Johannes Schindelin
2007-11-29 0:59 ` A Large Angry SCM
2007-11-29 1:02 ` Junio C Hamano
2007-11-29 3:17 ` Nguyen Thai Ngoc Duy
2007-11-29 14:09 ` Nicolas Pitre
2007-11-29 22:36 ` Junio C Hamano
2007-11-30 7:32 ` Wincent Colaiuta
2007-11-30 11:28 ` Eyvind Bernhardsen
2007-11-30 12:08 ` [PATCH] transport.c: call dash-less form of receive-pack and upload-pack on remote Johannes Schindelin
2007-12-01 2:36 ` Junio C Hamano
2007-12-01 10:17 ` Johannes Schindelin
2007-12-01 19:30 ` Junio C Hamano
2007-12-01 23:03 ` Johannes Schindelin
2007-12-01 23:15 ` Johannes Schindelin
2007-12-02 1:57 ` Junio C Hamano
2007-12-02 2:52 ` [PATCH 0/3] Call builtin functions directly, was " Johannes Schindelin
2007-12-02 2:54 ` [PATCH 1/3] Introduce release_all_objects() Johannes Schindelin
2007-12-02 2:54 ` [PATCH 2/3] Include the objects needed for the builtin functions into libgit.a Johannes Schindelin
2007-12-02 2:55 ` [PATCH 3/3] Introduce execv_git_builtin() and use it Johannes Schindelin
2007-12-02 3:04 ` Johannes Schindelin
2007-12-02 3:16 ` [REPLACEMENT PATCH " Johannes Schindelin
2007-12-02 5:19 ` Junio C Hamano [this message]
2007-12-02 11:35 ` [PATCH 0/3] Call builtin functions directly, was Re: [PATCH] transport.c: call dash-less form of receive-pack and upload-pack on remote Johannes Schindelin
2007-11-30 12:19 ` [PATCH] Move all dashed form git commands to libexecdir Nguyen Thai Ngoc Duy
2007-11-30 13:35 ` Johannes Schindelin
2007-11-29 15:08 ` Jeff King
2007-11-29 20:05 ` Nguyen Thai Ngoc Duy
2007-11-29 21:14 ` Jeff King
2007-11-29 22:19 ` Johannes Schindelin
2007-11-29 23:14 ` Jeff King
2007-11-29 23:30 ` Linus Torvalds
2007-11-30 0:13 ` Junio C Hamano
2007-11-30 0:35 ` Jeff King
2007-11-30 0:49 ` Junio C Hamano
2007-11-30 0:58 ` Jeff King
2007-11-30 1:13 ` Nicolas Pitre
2007-11-30 1:17 ` Jeff King
2007-11-30 5:42 ` Steffen Prohaska
2007-11-30 7:18 ` Andreas Ericsson
2007-11-30 15:09 ` Jeff King
2007-11-30 20:01 ` Junio C Hamano
2007-11-30 21:25 ` Jeff King
2007-11-30 23:10 ` Johannes Schindelin
2007-12-02 15:02 ` Wincent Colaiuta
2007-12-02 16:39 ` Johannes Schindelin
2007-12-02 16:56 ` Pascal Obry
2007-12-02 17:23 ` Johannes Schindelin
2007-12-01 2:37 ` Junio C Hamano
2007-12-01 4:17 ` Jeff King
2007-11-30 2:29 ` Linus Torvalds
2007-11-30 2:55 ` Nicolas Pitre
2007-11-30 5:51 ` Steffen Prohaska
2007-11-30 15:12 ` Jeff King
2007-11-30 15:28 ` Santi Béjar
2007-11-30 15:29 ` Jeff King
2007-11-30 15:50 ` Linus Torvalds
2007-11-30 16:22 ` Jeff King
2007-11-30 18:28 ` Johannes Schindelin
2007-11-30 18:37 ` Jeff King
2007-11-30 23:05 ` Johannes Schindelin
2007-11-30 23:21 ` Jeff King
2007-11-30 23:38 ` Johannes Schindelin
[not found] ` <fcaeb9bf0711302234l32460a1fqbf9825fc8055f99d@mail.gmail.com>
2007-12-01 19:32 ` Junio C Hamano
2007-12-01 21:26 ` Jeff King
2007-12-02 5:50 ` Nguyen Thai Ngoc Duy
2007-11-30 0:52 ` Nicolas Pitre
2007-11-30 1:00 ` Jeff King
2007-11-30 1:19 ` Nicolas Pitre
2007-11-30 1:25 ` Jeff King
2007-11-30 1:33 ` Nicolas Pitre
2007-11-30 1:53 ` Jeff King
2007-11-30 2:23 ` A Large Angry SCM
2007-11-30 0:40 ` Nguyen Thai Ngoc Duy
2007-11-30 0:51 ` A Large Angry SCM
2007-11-30 0:54 ` Johannes Schindelin
2007-11-30 2:03 ` A Large Angry SCM
2007-11-30 1:01 ` Nicolas Pitre
2007-11-30 2:17 ` A Large Angry SCM
2007-11-30 2:27 ` Nicolas Pitre
2007-11-29 0:14 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7v3aul1xmt.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=bulb@ucw.cz \
--cc=eyvind-git-list@orakel.ntnu.no \
--cc=git@vger.kernel.org \
--cc=nico@cam.org \
--cc=pclouds@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.