git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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;

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).