summaryrefslogtreecommitdiff
path: root/git.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-12-01 22:09:22 -0800
committerJunio C Hamano <gitster@pobox.com>2008-06-23 22:45:41 -0700
commit7550be0a2bbf47aaa63c806bb5d7fcb8ab197cf8 (patch)
tree6039b53ba7b8b3bbd425113734c0a9996eed4d37 /git.c
parent0a47dc110e042b5bcc63dc94c8d517e67efe9306 (diff)
downloadgit-7550be0a2bbf47aaa63c806bb5d7fcb8ab197cf8.tar.gz
Prepare execv_git_cmd() for removal of builtins from the filesystem
Currently, execv_git_cmd() always try running the dashed form, which means we cannot easily remove the git-foo hardlinks for built-in commands. This updates the function to always exec "git foo" form, and makes sure "git" potty does not infinitely recurse to itself. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git.c')
-rw-r--r--git.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/git.c b/git.c
index 59f0fcc1f2..22ac5226de 100644
--- a/git.c
+++ b/git.c
@@ -384,6 +384,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, "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";
@@ -448,7 +478,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