{"thread":{"id":"18072","subject":"[PATCH 1/4] Refactor list of environment variables to be sanitized","startedAt":"2009-03-01T00:03:39Z","lastAt":"2009-03-06T01:37:17Z","messageCount":43,"participants":["Junio C Hamano","Jeff King","Shawn O. Pearce","Jay Soffian","Theodore Tso","Johannes Schindelin","Daniel Barkalow","Matthieu Moy","Miles Bader"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"106562","messageId":"1235865822-14625-1-git-send-email-gitster@pobox.com","threadId":"18072","inReplyTo":null,"subject":"[PATCH 1/4] Refactor list of environment variables to be sanitized","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T00:03:39Z","receivedAt":"2009-03-01T00:03:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When local process-to-process pipe transport spawns a subprocess,\nit cleans up various git related variables to give the new process\na fresh environment.  The list of variables to cleanse is useful\nin other places.\n---\n cache.h   |    2 ++\n connect.c |   26 +++++++++++++++-----------\n 2 files changed, 17 insertions(+), 11 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 189151d..b72434f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -389,6 +389,8 @@ extern void set_git_work_tree(const char *tree);\n \n #define ALTERNATE_DB_ENVIRONMENT \"GIT_ALTERNATE_OBJECT_DIRECTORIES\"\n \n+extern const char *sanitize_git_env[];\n+\n extern const char **get_pathspec(const char *prefix, const char **pathspec);\n extern void setup_work_tree(void);\n extern const char *setup_git_directory_gently(int *);\ndiff --git a/connect.c b/connect.c\nindex 2f23ab3..b4705ff 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -6,6 +6,20 @@\n #include \"run-command.h\"\n #include \"remote.h\"\n \n+/*\n+ * When spawning a subprocess in a fresh environment,\n+ * these variables may need to be cleared\n+ */\n+const char *sanitize_git_env[] = {\n+\tALTERNATE_DB_ENVIRONMENT,\n+\tDB_ENVIRONMENT,\n+\tGIT_DIR_ENVIRONMENT,\n+\tGIT_WORK_TREE_ENVIRONMENT,\n+\tGRAFT_ENVIRONMENT,\n+\tINDEX_ENVIRONMENT,\n+\tNULL\n+};\n+\n static char *server_capabilities;\n \n static int check_ref(const char *name, int len, unsigned int flags)\n@@ -625,17 +639,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,\n \t\t*arg++ = host;\n \t}\n \telse {\n-\t\t/* remove these from the environment */\n-\t\tconst char *env[] = {\n-\t\t\tALTERNATE_DB_ENVIRONMENT,\n-\t\t\tDB_ENVIRONMENT,\n-\t\t\tGIT_DIR_ENVIRONMENT,\n-\t\t\tGIT_WORK_TREE_ENVIRONMENT,\n-\t\t\tGRAFT_ENVIRONMENT,\n-\t\t\tINDEX_ENVIRONMENT,\n-\t\t\tNULL\n-\t\t};\n-\t\tconn->env = env;\n+\t\tconn->env = sanitize_git_env;\n \t\t*arg++ = \"sh\";\n \t\t*arg++ = \"-c\";\n \t}\n-- \n1.6.2.rc2.99.g9f3bb\n"},{"id":"106566","messageId":"1235865822-14625-2-git-send-email-gitster@pobox.com","threadId":"18072","inReplyTo":"1235865822-14625-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/4] git-init: inject some sanity to the option parser","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T00:03:40Z","receivedAt":"2009-03-01T00:03:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The parsing loop was a mess full of side effects.\n\nThis commit separates the loop that parses and understand the options\ngiven, and the part that makes side effects based on given options.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-init-db.c |   35 ++++++++++++++++++++++++-----------\n 1 files changed, 24 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex ee3911f..9628803 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -377,27 +377,40 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \tconst char *git_dir;\n \tconst char *template_dir = NULL;\n \tunsigned int flags = 0;\n+\tconst char *shared_given = NULL;\n+\tint bare_given = 0;\n \tint i;\n \n-\tfor (i = 1; i < argc; i++, argv++) {\n-\t\tconst char *arg = argv[1];\n+\t/* Parse without side effects that is hard to undo or unparse */\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n \t\tif (!prefixcmp(arg, \"--template=\"))\n-\t\t\ttemplate_dir = arg+11;\n-\t\telse if (!strcmp(arg, \"--bare\")) {\n-\t\t\tstatic char git_dir[PATH_MAX+1];\n-\t\t\tis_bare_repository_cfg = 1;\n-\t\t\tsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir,\n-\t\t\t\t\t\tsizeof(git_dir)), 0);\n-\t\t} else if (!strcmp(arg, \"--shared\"))\n-\t\t\tinit_shared_repository = PERM_GROUP;\n+\t\t\ttemplate_dir = arg + 11;\n+\t\telse if (!strcmp(arg, \"--bare\"))\n+\t\t\tbare_given = 1;\n+\t\telse if (!strcmp(arg, \"--shared\"))\n+\t\t\tshared_given = \"\";\n \t\telse if (!prefixcmp(arg, \"--shared=\"))\n-\t\t\tinit_shared_repository = git_config_perm(\"arg\", arg+9);\n+\t\t\tshared_given = arg + 9;\n \t\telse if (!strcmp(arg, \"-q\") || !strcmp(arg, \"--quiet\"))\n \t\t\tflags |= INIT_DB_QUIET;\n \t\telse\n \t\t\tusage(init_db_usage);\n \t}\n \n+\tif (bare_given) {\n+\t\tstatic char git_dir[PATH_MAX+1];\n+\t\tis_bare_repository_cfg = 1;\n+\t\tsetenv(GIT_DIR_ENVIRONMENT,\n+\t\t       getcwd(git_dir, sizeof(git_dir)), 0);\n+\t}\n+\n+\tif (shared_given)\n+\t\tinit_shared_repository =\n+\t\t\t((!*shared_given)\n+\t\t\t ? PERM_GROUP\n+\t\t\t : git_config_perm(\"arg\", shared_given));\n+\n \t/*\n \t * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR\n \t * without --bare.  Catch the error early.\n-- \n1.6.2.rc2.99.g9f3bb\n"},{"id":"106563","messageId":"1235865822-14625-3-git-send-email-gitster@pobox.com","threadId":"18072","inReplyTo":"1235865822-14625-2-git-send-email-gitster@pobox.com","subject":"[PATCH 3/4] Add init-serve, the remote side of \"git init --remote=host:path\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T00:03:41Z","receivedAt":"2009-03-01T00:03:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This still has a few NEEDSWORK, but should be good enough to start\ndeveloping and testing the requesting side of the protocol pair.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Makefile             |    1 +\n builtin-init-serve.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++\n builtin.h            |    1 +\n git.c                |    1 +\n 4 files changed, 142 insertions(+), 0 deletions(-)\n create mode 100644 builtin-init-serve.c\n\ndiff --git a/Makefile b/Makefile\nindex 0675c43..c0d0cfd 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -544,6 +544,7 @@ BUILTIN_OBJS += builtin-gc.o\n BUILTIN_OBJS += builtin-grep.o\n BUILTIN_OBJS += builtin-help.o\n BUILTIN_OBJS += builtin-init-db.o\n+BUILTIN_OBJS += builtin-init-serve.o\n BUILTIN_OBJS += builtin-log.o\n BUILTIN_OBJS += builtin-ls-files.o\n BUILTIN_OBJS += builtin-ls-remote.o\ndiff --git a/builtin-init-serve.c b/builtin-init-serve.c\nnew file mode 100644\nindex 0000000..2a06631\n--- /dev/null\n+++ b/builtin-init-serve.c\n@@ -0,0 +1,139 @@\n+#include \"cache.h\"\n+#include \"builtin.h\"\n+#include \"pkt-line.h\"\n+#include \"run-command.h\"\n+#include \"strbuf.h\"\n+\n+/*\n+ * Notice any command line argument that we may not want to invoke\n+ * \"git init\" with when we are doing this remotely, and reject the\n+ * request.\n+ */\n+static int forbidden_arg(const char *arg)\n+{\n+\tif (!prefixcmp(arg, \"--shared=\") ||\n+\t    !strcmp(arg, \"--shared\") ||\n+\t    !strcmp(arg, \"--bare\"))\n+\t\treturn 0;\n+\treturn 1;\n+}\n+\n+/*\n+ * The other end gives the command line arguments to \"git init\" one by\n+ * one over pkt-line protocol, and then expects a message back.\n+ *\n+ * We need to read them all, even when we know we will reject the\n+ * request before responding.\n+ */\n+static int serve(const char *errmsg)\n+{\n+\tint argc = 0;\n+\tconst char *argv[64];\n+\n+\targv[argc++] = \"git\";\n+\targv[argc++] = \"init\";\n+\tfor (;;) {\n+\t\tstatic char err[1000];\n+\t\tchar line[1000];\n+\t\tint len;\n+\n+\t\tlen = packet_read_line(0, line, sizeof(line));\n+\t\tif (!len)\n+\t\t\tbreak;\n+\t\tif (*errmsg)\n+\t\t\tcontinue; /* just read and discard */\n+\n+\t\tif (line[len - 1] == '\\n')\n+\t\t\tline[--len] = '\\0';\n+\n+\t\tif (!prefixcmp(line, \"arg \")) {\n+\t\t\tconst char *cmd = line + 4;\n+\t\t\tif (forbidden_arg(cmd)) {\n+\t\t\t\tsnprintf(err, sizeof(err),\n+\t\t\t\t\t \"forbidden option to 'git init': '%s'\",\n+\t\t\t\t\t cmd);\n+\t\t\t\terrmsg = err;\n+\t\t\t} else if (argc + 1 < ARRAY_SIZE(argv))\n+\t\t\t\targv[argc++] = xstrdup(cmd);\n+\t\t\telse\n+\t\t\t\terrmsg = \"arg list too long\";\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Possible protocol extensions here... */\n+\t\tsnprintf(err, sizeof(err),\n+\t\t\t \"unrecognized protocol extension: %s\", line);\n+\t\terrmsg = err;\n+\n+\t\t/* Do not break out of the loop here */\n+\t}\n+\n+\tif (!*errmsg) {\n+\t\tstruct child_process child;\n+\n+\t\targv[argc] = NULL;\n+\t\tmemset(&child, 0, sizeof(child));\n+\t\tchild.argv = argv;\n+\t\tchild.env = sanitize_git_env;\n+\n+\t\t/*\n+\t\t * NEEDSWORK: I do not currently think it is worth it,\n+\t\t * but this might want to set up and use the sideband\n+\t\t * to capture and send output from the child back to\n+\t\t * the requestor.  At least this comment needs to be removed\n+\t\t * once we make the decision.\n+\t\t */\n+\t\tchild.stdout_to_stderr = 1;\n+\n+\t\t/*\n+\t\t * NEEDSWORK: we might want to distinguish various\n+\t\t * error codes from run_command() and return different\n+\t\t * messages back.  I am too lazy to be bothered.\n+\t\t */\n+\t\tif (run_command(&child))\n+\t\t\terrmsg = \"bad\";\n+\t}\n+\n+\tif (*errmsg)\n+\t\tpacket_write(1, \"ng init %s\\n\", errmsg);\n+\telse\n+\t\tpacket_write(1, \"ok init\\n\");\n+\n+\treturn !!*errmsg;\n+}\n+\n+int cmd_init_serve(int argc, const char **argv, const char *prefix)\n+{\n+\tconst char *dir;\n+\tstruct strbuf errmsg = STRBUF_INIT;\n+\tchar here[PATH_MAX];\n+\tint must_rmdir = 0;\n+\n+\tif (argc != 2)\n+\t\treturn serve(\"usage: init /p/a/th\");\n+\tdir = argv[1];\n+\n+\tif (!getcwd(here, sizeof(here)))\n+\t\treturn serve(\"init cannot determine the $cwd\");\n+\n+\t/*\n+\t * Perhaps lift avoid_alias() from daemon.c and check\n+\t * dir with it, as programs like gitosis may\n+\t * want to restrict the arguments to this service.\n+\t */\n+\tif (mkdir(dir, 0777))\n+\t\tstrbuf_addf(&errmsg,\n+\t\t\t    \"cannot mkdir('%s'): %s\", dir, strerror(errno));\n+\telse {\n+\t\tmust_rmdir = 1;\n+\t\tif (chdir(dir))\n+\t\t\tstrbuf_addf(&errmsg,\n+\t\t\t\t    \"cannot chdir('%s'): %s\", dir, strerror(errno));\n+\t}\n+\tif (serve(errmsg.buf)) {\n+\t\tif (must_rmdir && !chdir(here))\n+\t\t\trmdir(dir);\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/builtin.h b/builtin.h\nindex 1495cf6..e9f9ffb 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -59,6 +59,7 @@ extern int cmd_grep(int argc, const char **argv, const char *prefix);\n extern int cmd_help(int argc, const char **argv, const char *prefix);\n extern int cmd_http_fetch(int argc, const char **argv, const char *prefix);\n extern int cmd_init_db(int argc, const char **argv, const char *prefix);\n+extern int cmd_init_serve(int argc, const char **argv, const char *prefix);\n extern int cmd_log(int argc, const char **argv, const char *prefix);\n extern int cmd_log_reflog(int argc, const char **argv, const char *prefix);\n extern int cmd_ls_files(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex c2b181e..1df8584 100644\n--- a/git.c\n+++ b/git.c\n@@ -311,6 +311,7 @@ static void handle_internal_command(int argc, const char **argv)\n #endif\n \t\t{ \"init\", cmd_init_db },\n \t\t{ \"init-db\", cmd_init_db },\n+\t\t{ \"init-serve\", cmd_init_serve },\n \t\t{ \"log\", cmd_log, RUN_SETUP | USE_PAGER },\n \t\t{ \"ls-files\", cmd_ls_files, RUN_SETUP },\n \t\t{ \"ls-tree\", cmd_ls_tree, RUN_SETUP },\n-- \n1.6.2.rc2.99.g9f3bb\n"},{"id":"106565","messageId":"1235865822-14625-4-git-send-email-gitster@pobox.com","threadId":"18072","inReplyTo":"1235865822-14625-3-git-send-email-gitster@pobox.com","subject":"[PATCH 4/4] \"git init --remote=host:path\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T00:03:42Z","receivedAt":"2009-03-01T00:03:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This implements the requesting side of the pair.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-init-db.c |   44 ++++++++++++++++++++++++++++++++++++++++++++\n t/t0001-init.sh   |   12 ++++++++++++\n 2 files changed, 56 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 9628803..18754d7 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -6,6 +6,7 @@\n #include \"cache.h\"\n #include \"builtin.h\"\n #include \"exec_cmd.h\"\n+#include \"pkt-line.h\"\n \n #ifndef DEFAULT_GIT_TEMPLATE_DIR\n #define DEFAULT_GIT_TEMPLATE_DIR \"/usr/share/git-core/templates\"\n@@ -363,6 +364,37 @@ static int guess_repository_type(const char *git_dir)\n \treturn 1;\n }\n \n+static int remote_init(const char *remote, const char *init_serve,\n+\t\t       int argc, const char **argv)\n+{\n+\tstruct child_process *child;\n+\tint fd[2], i, len, status;\n+\tchar line[1000];\n+\n+\tif (!init_serve)\n+\t\tinit_serve = \"git init-serve\";\n+\tchild = git_connect(fd, remote, init_serve, 0);\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\t\tif (!prefixcmp(arg, \"--remote=\") ||\n+\t\t    !prefixcmp(arg, \"--exec=\"))\n+\t\t\tcontinue;\n+\t\tpacket_write(fd[1], \"arg %s\\n\", argv[i]);\n+\t}\n+\tpacket_flush(fd[1]);\n+\n+\tstatus = 0;\n+\tlen = packet_read_line(fd[0], line, sizeof(line));\n+\tif (len < 3 ||\n+\t    (memcmp(line, \"ok \", 3) && memcmp(line, \"ng \", 3)))\n+\t\tdie(\"protocol error: %s\\n\", line);\n+\n+\tif (line[0] != 'o')\n+\t\tstatus = error(\"%s\", line);\n+\tstatus |= finish_connect(child);\n+\treturn status;\n+}\n+\n static const char init_db_usage[] =\n \"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]\";\n \n@@ -378,6 +410,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \tconst char *template_dir = NULL;\n \tunsigned int flags = 0;\n \tconst char *shared_given = NULL;\n+\tconst char *remote_given = NULL;\n+\tconst char *exec_given = NULL;\n \tint bare_given = 0;\n \tint i;\n \n@@ -394,10 +428,20 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\t\tshared_given = arg + 9;\n \t\telse if (!strcmp(arg, \"-q\") || !strcmp(arg, \"--quiet\"))\n \t\t\tflags |= INIT_DB_QUIET;\n+\t\telse if (!prefixcmp(arg, \"--remote=\"))\n+\t\t\tremote_given = arg + 9;\n+\t\telse if (!prefixcmp(arg, \"--exec=\"))\n+\t\t\texec_given = arg + 7;\n \t\telse\n \t\t\tusage(init_db_usage);\n \t}\n \n+\tif (remote_given || exec_given) {\n+\t\tif (!remote_given)\n+\t\t\tdie(\"--exec= without --remote=?\");\n+\t\treturn remote_init(remote_given, exec_given, argc, argv);\n+\t}\n+\n \tif (bare_given) {\n \t\tstatic char git_dir[PATH_MAX+1];\n \t\tis_bare_repository_cfg = 1;\ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex 5ac0a27..6f47930 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -199,4 +199,16 @@ test_expect_success 'init honors global core.sharedRepository' '\n \tx`git config -f shared-honor-global/.git/config core.sharedRepository`\n '\n \n+test_expect_success 'init --remote' '\n+\tR=\"$(pwd)/test-of-remote\" &&\n+\ttest_must_fail git init --remote=\"$R\" --bare --template=frotz &&\n+\tgit init --remote=\"$R\" --bare &&\n+\ttest -d \"$R/objects/pack\" &&\n+\ttest_must_fail git init --remote=\"$R\" &&\n+\trm -fr \"$R\" &&\n+\ttest_must_fail git init --remote=\"$R\" --exec=\"false is not git\" &&\n+\tgit init --remote=\"$R\" --exec=\"$TEST_DIRECTORY/../git-init-serve\" &&\n+\ttest -d \"$R/.git/objects/pack\"\n+'\n+\n test_done\n-- \n1.6.2.rc2.99.g9f3bb\n"},{"id":"106572","messageId":"20090301031609.GA30384@coredump.intra.peff.net","threadId":"18072","inReplyTo":"1235865822-14625-3-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 3/4] Add init-serve, the remote side of \"git init --remote=host:path\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-01T03:16:09Z","receivedAt":"2009-03-01T03:16:09Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 28, 2009 at 04:03:41PM -0800, Junio C Hamano wrote:\n\n> +/*\n> + * Notice any command line argument that we may not want to invoke\n> + * \"git init\" with when we are doing this remotely, and reject the\n> + * request.\n> + */\n> +static int forbidden_arg(const char *arg)\n> +{\n> +\tif (!prefixcmp(arg, \"--shared=\") ||\n> +\t    !strcmp(arg, \"--shared\") ||\n> +\t    !strcmp(arg, \"--bare\"))\n> +\t\treturn 0;\n> +\treturn 1;\n> +}\n\nI started this mail to complain that this function was \"disallow known\nbad\" instead of \"allow known good\". But then after reading it carefully\nthree times, I see that it is in fact \"not allow known good\". Can we\nmake it \"allowed_arg\" to prevent double negation?\n\n> +\t\t/*\n> +\t\t * NEEDSWORK: I do not currently think it is worth it,\n> +\t\t * but this might want to set up and use the sideband\n> +\t\t * to capture and send output from the child back to\n> +\t\t * the requestor.  At least this comment needs to be removed\n> +\t\t * once we make the decision.\n> +\t\t */\n> +\t\tchild.stdout_to_stderr = 1;\n\nI guess there is a potential information leak to say \"directory does not\nexist\" versus \"permission denied\". Stopping such leaks often ends up\ncreating more harm (in confused users who don't know why it failed) than\ngood, but I think the fetch protocol is intentionally quiet here.\n\n...\n\nActually, I just checked. Over ssh, you get:\n\n  $ git fetch host:/nonexistent\n  fatal: '/foo': unable to chdir or not a git archive\n  fatal: The remote end hung up unexpectedly\n\nBut over git://, you get:\n\n  $ git fetch git://host/nonexistent\n  fatal: The remote end hung up unexpectedly\n\nwhich I think is just because ssh relays stderr but the git daemon does\nnot.\n\nSo we are leaking the information to people authenticated via ssh (who\nstill might not be trusted or have full shell access, but are more\nlikely to be), but not to the whole world.\n\n> +\t\t/*\n> +\t\t * NEEDSWORK: we might want to distinguish various\n> +\t\t * error codes from run_command() and return different\n> +\t\t * messages back.  I am too lazy to be bothered.\n> +\t\t */\n> +\t\tif (run_command(&child))\n> +\t\t\terrmsg = \"bad\";\n\nI think this somewhat falls into the same category as above (though\nperhaps the information is less interesting).\n\n-Peff\n"},{"id":"106580","messageId":"7v63itbxe7.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090301031609.GA30384@coredump.intra.peff.net","subject":"Re: [PATCH 3/4] Add init-serve, the remote side of \"git init --remote=host:path\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-01T05:54:56Z","receivedAt":"2009-03-01T05:54:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, Feb 28, 2009 at 04:03:41PM -0800, Junio C Hamano wrote:\n>\n>> +/*\n>> + * Notice any command line argument that we may not want to invoke\n>> + * \"git init\" with when we are doing this remotely, and reject the\n>> + * request.\n>> + */\n>> +static int forbidden_arg(const char *arg)\n>> +{\n>> +\tif (!prefixcmp(arg, \"--shared=\") ||\n>> +\t    !strcmp(arg, \"--shared\") ||\n>> +\t    !strcmp(arg, \"--bare\"))\n>> +\t\treturn 0;\n>> +\treturn 1;\n>> +}\n>\n> I started this mail to complain that this function was \"disallow known\n> bad\" instead of \"allow known good\". But then after reading it carefully\n> three times, I see that it is in fact \"not allow known good\". Can we\n> make it \"allowed_arg\" to prevent double negation?\n\nI originally had \"arg_ok()\", but the implementation checked that the\nargument is not --template, which is the only known to be bad one at the\nmoment, so that we would allow things by default.  Later I switched both\nname and the implementation ;-)\n\nI think renaming it to affirmative form (and swapping the return value, of\ncourse) would be a good idea.\n\nOne issue I did not describe in the message was to what extent we would\nwant to allow operations other than the creating of a new repository\nitself.\n\n\"Other than the creation\" includes things like these:\n\n - \"chgrp project-group\" and \"chmod g+s\".\n\n   It is typical for the system administrator to set up two classes of\n   groups in /etc/groups file.  One group per user that is the primary\n   group for a user, so that $HOME/ can be owned by that primary group and\n   its permission bits set to 2775, and one group per project, so a user\n   can belong to groups of the projects he works on.\n\n   With the patch series:\n\n    $ git init --remote=central.xz:/pub/projects/mine.git --shared --bare\n\n   would take care of the \"shared\" (i.e. g+w) part, but the \"mine.git\"\n   repository will either inherit the group ownership from /pub/projects\n   (if /pub/projects is marked with g+s) or owned by the creating user's\n   primary group, which would not be usable for use by a project the user\n   belongs to.  IOW, --shared by itself is not very useful with its\n   current form.\n\n - Writing to .git/description\n\n   Primarily for use with gitweb; the need for this goes without saying.\n   This shouldn't have security implications (even if the current\n   implementation had one, it could easily be squashed).\n\n - Other administrative bits that have security implications:\n\n   In a friendly environment without security concerns, e.g. company\n   intranet setting, the user may want to do these things:\n\n   - Installing custom hooks\n   - Updating .git/config\n\n   But these should never be allowed in a hosting-site setting.\n\nMy current thinking is that \"init --remote\" should not cater to the third\nkind.  In a friendly environment the user would have a shell access, and\nif the system does not give a shell access, then the user should not\nallowed to muck freely with the repository.\n\nI think the \"chgrp/chmod g+s\" part is necessary, and I envisioned that it\nwould be done by a new option to \"git init\", but I haven't thought things\nthrough.  The options to \"init\" will not be visible to git-shell because\nthey are carried over pkt-line protocol as the payload, and programs like\ngitosis may have hard time implementing limited access to certain groups,\neven if they wanted to; I do not think gitosis would care, as it does not\nrely on the UNIX group permission model for its access control, but other\nimplementations may care.\n"},{"id":"106596","messageId":"20090301100039.GD4146@coredump.intra.peff.net","threadId":"18072","inReplyTo":"7v63itbxe7.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 3/4] Add init-serve, the remote side of \"git init --remote=host:path\"","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-01T10:00:39Z","receivedAt":"2009-03-01T10:00:39Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 28, 2009 at 09:54:56PM -0800, Junio C Hamano wrote:\n\n> One issue I did not describe in the message was to what extent we would\n> want to allow operations other than the creating of a new repository\n> itself.\n> \n> \"Other than the creation\" includes things like these:\n\nHmph. I am not too excited by this list. What is the advantage of doing\nthem over the git protocol versus some out-of-band method?\n\nIt seems to me there are two main cases for dealing with a remote in\nthis way:\n\n  1. You have shell access and a uid on the remote, but it is\n     inconvenient to ssh across, find the repo (which may already be\n     known locally by remote.*.url config), and then execute some\n     commands.\n\n     In this scenario, there really are no security concerns; you could\n     have logged in and done all of this anyway. So it seems like a more\n     natural fit would be a _client_ program that figures out what shell\n     snippet you want to execute, connects to the remote, and does it.\n\n  2. Your access on the remote is very restricted, you may not have your\n     own uid, and hooks may be enforcing arbitrary security policy.\n\n     In this case, even something as simple as chgrp seems like it could\n     be a problem, depending on the remote's setup (e.g., because all\n     users connect as one uid, but group permissions are somehow\n     meaningful to the system; this implies that connecting users should\n     not be able to arbitrarily chgrp their repos, even if chgrp itself\n     allows it).\n\n     Furthermore, in the case of many providers (e.g., github,\n     repo.or.cz), there is already a separate out-of-band interface for\n     doing \"meta\" stuff, like managing user accounts and repos. Isn't it\n     more natural for them to integrate these features with their\n     existing interfaces?\n\nBut let's say that there really is some value in setting up this\nchannel (because we want a uniform way of doing these things so we can\nadd more automated tool support from the client side). Then I think it\nmakes sense to look at what the people in (2) above are doing already.\nThat is, what sorts of things can you already do (and not do) in\ngithub's or repo.or.cz's interface? On top of that, it probably makes\nsense to ask them if they are interested in such a feature, as they\nwould be primary users. And if they are, what do they want out of it?\n\n-Peff\n"},{"id":"106618","messageId":"20090301170436.GA14365@spearce.org","threadId":"18072","inReplyTo":"20090301100039.GD4146@coredump.intra.peff.net","subject":"Re: [PATCH 3/4] Add init-serve, the remote side of \"git init --remote=host:path\"","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-01T17:04:36Z","receivedAt":"2009-03-01T17:04:36Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jeff King <peff@peff.net> wrote:\n> On Sat, Feb 28, 2009 at 09:54:56PM -0800, Junio C Hamano wrote:\n> \n> > One issue I did not describe in the message was to what extent we would\n> > want to allow operations other than the creating of a new repository\n> > itself.\n> > \n> > \"Other than the creation\" includes things like these:\n> \n> Hmph. I am not too excited by this list. What is the advantage of doing\n> them over the git protocol versus some out-of-band method?\n\nMy feelings echo Peff's here.\n \n>      Furthermore, in the case of many providers (e.g., github,\n>      repo.or.cz), there is already a separate out-of-band interface for\n>      doing \"meta\" stuff, like managing user accounts and repos. Isn't it\n>      more natural for them to integrate these features with their\n>      existing interfaces?\n\nDon't forget about my day-job project, Gerrit Code Review.\n\nI'm already hosting 138 projects on review.source.android.com, and\nbased on weekly downloads of Gerrit builds I'd estimate another ~60\ndeployments at internal servers within organizations.  (I'm doing\nweekly \"stable\" builds and I'm seeing an average of ~70 downloads\nfor each build.)\n \n> But let's say that there really is some value in setting up this\n> channel (because we want a uniform way of doing these things so we can\n> add more automated tool support from the client side). Then I think it\n> makes sense to look at what the people in (2) above are doing already.\n> That is, what sorts of things can you already do (and not do) in\n> github's or repo.or.cz's interface? On top of that, it probably makes\n> sense to ask them if they are interested in such a feature, as they\n> would be primary users. And if they are, what do they want out of it?\n\nEarlier last week a co-worker who is new to git complained that he\ncan't create a repository easily from his desktop.  There may be\nvalue in being able to create a repository remotely, as it removes\nthat confusion.\n\nBut I think that's only true for situations where you are likely the\nowner of the repository in your own home directory, such as ~you\non kernel.org.  For \"hosted repositories\" like any of the systems\nyou described above, there is a lot more to the creation than just\nexecuting \"git init\" somewhere.\n\nFWIW, JGit automatically creates a repository over the amazon-s3://\ntransport during push if it doesn't exist yet.  In my mind, this is\nsomewhat like scp or rsync automatically creating the destination\ndirectory when recursively copying a directory.  For the usage of\ncreating a new repository in your own home directory on some remote\nserver, why isn't this just an option to git push?\n\n  git push --create me@george:my/new/repo.git master\n\nIt fits better with the push-creates-a-branch feature.\n\n\nGitosis allows repositories to be created during the first push\ninto that repository, if the repository is listed in the config\nand the user is permitted to write to it.\n\nGitHub and repo.or.cz allow you to create empty repositories,\nbut both do so through the web interface.\n\nGerrit Code Review still requires you to manually run \"git init\"\nand also do a SQL INSERT by hand.  Its missing some sort of user\nfriendly repository creation feature.  But I'm starting to consider\ndoing it automatically during \"git push\", like gitosis does.\n\nRepository creation in Gerrit is more than just \"git init\" and\na SQL INSERT.  I also have to run rsync a few times to replicate\nthe repository onto multiple servers, so that subsequent pushes\nto those servers won't fail.\n\nI suspect the situation is the same for GitHub; I know they have\na custom daemon that handles repository mapping, and some database\nbehind that daemon to store those translations.\n\nIMHO, _if_ we do support remote repository creation, it should match\nbranch creation UI better (meaning, be part of git push, not part of\ngit init), and it should be something that the hosted providers can\nall hook into so we can keep our non-git state management current.\n\n-- \nShawn.\n"},{"id":"106766","messageId":"7vwsb7gkvt.fsf_-_@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090301170436.GA14365@spearce.org","subject":"Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T06:50:46Z","receivedAt":"2009-03-03T06:50:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This teaches receive-pack to create a new directory as a bare repository\nwhen a user tries to push into a directory that does not exist.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n > But I think that's only true for situations where you are likely the\n > owner of the repository in your own home directory, such as ~you\n > on kernel.org.  For \"hosted repositories\" like any of the systems\n > you described above, there is a lot more to the creation than just\n > executing \"git init\" somewhere.\n > .\n > For the usage of\n > creating a new repository in your own home directory on some remote\n > server, why isn't this just an option to git push?\n\n I am not at all convinced that the use case people would for whatever\n reason do not want to \"ssh-in, create and then push from here\" is limited\n to \"your own playpen in your $HOME\", but it certainly limits the\n complexity and the scope of the damage.\n\n builtin-receive-pack.c |   29 ++++++++++++++++++++++++++++-\n t/t5541-push-create.sh |   20 ++++++++++++++++++++\n 2 files changed, 48 insertions(+), 1 deletions(-)\n create mode 100755 t/t5541-push-create.sh\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 849f1fe..2f2831c 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -652,6 +652,33 @@ static void add_alternate_refs(void)\n \tforeach_alt_odb(add_refs_from_alternate, NULL);\n }\n \n+static char *create_new_repo(char *dir)\n+{\n+\tstruct child_process child;\n+\tconst char *argv[20];\n+\tint argc;\n+\n+\tif (mkdir(dir, 0777)) {\n+\t\terror(\"cannot mkdir '%s': %s\", dir, strerror(errno));\n+\t\treturn NULL;\n+\t}\n+\targc = 0;\n+\targv[argc++] = \"init\";\n+\targv[argc++] = \"--bare\";\n+\targv[argc++] = NULL;\n+\tchild.argv = argv;\n+\tif (run_command_v_opt_cd_env(argv,\n+\t\t\t\t     RUN_COMMAND_NO_STDIN |\n+\t\t\t\t     RUN_COMMAND_STDOUT_TO_STDERR |\n+\t\t\t\t     RUN_GIT_CMD,\n+\t\t\t\t     dir,\n+\t\t\t\t     NULL)) {\n+\t\terror(\"cannot run git init\");\n+\t\treturn NULL;\n+\t}\n+\treturn enter_repo(dir, 0);\n+}\n+\n int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n {\n \tint i;\n@@ -674,7 +701,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \n \tsetup_path();\n \n-\tif (!enter_repo(dir, 0))\n+\tif (!enter_repo(dir, 0) && !create_new_repo(dir))\n \t\tdie(\"'%s': unable to chdir or not a git archive\", dir);\n \n \tif (is_repository_shallow())\ndiff --git a/t/t5541-push-create.sh b/t/t5541-push-create.sh\nnew file mode 100755\nindex 0000000..52558a5\n--- /dev/null\n+++ b/t/t5541-push-create.sh\n@@ -0,0 +1,20 @@\n+#!/bin/sh\n+\n+test_description='push into nonexisting repository'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\ttest_commit A &&\n+\ttest_commit B &&\n+\ttest_commit C\n+'\n+\n+test_expect_success 'push into nonexisting repository' '\n+\tthis=$(git rev-parse B) &&\n+\tgit push \"file://$(pwd)/not-here.git\" B:refs/heads/master &&\n+\tthat=$(GIT_DIR=not-here.git git rev-parse HEAD) &&\n+\ttest \"$this\" = \"$that\"\n+'\n+\n+test_done\n-- \n1.6.2.rc2.123.gab4478\n"},{"id":"106771","messageId":"76718490903022309q43862d34ma99ba191cef3742c@mail.gmail.com","threadId":"18072","inReplyTo":"7vwsb7gkvt.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T07:09:35Z","receivedAt":"2009-03-03T07:09:35Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 1:50 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> +       if (mkdir(dir, 0777)) {\n> +               error(\"cannot mkdir '%s': %s\", dir, strerror(errno));\n> +               return NULL;\n> +       }\n\nHow about \"cannot create repository; mkdir failed '%s': %s\" ...\n\nj.\n"},{"id":"106770","messageId":"20090303070937.GB30609@coredump.intra.peff.net","threadId":"18072","inReplyTo":"7vwsb7gkvt.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-03T07:09:37Z","receivedAt":"2009-03-03T07:09:37Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 02, 2009 at 10:50:46PM -0800, Junio C Hamano wrote:\n\n>  I am not at all convinced that the use case people would for whatever\n>  reason do not want to \"ssh-in, create and then push from here\" is limited\n>  to \"your own playpen in your $HOME\", but it certainly limits the\n>  complexity and the scope of the damage.\n\nIf you are going to limit it in that way, wouldn't it be better to do it\nentirely client-side? As in, \"git push --create remote\" will literally\ndo:\n\n    ssh remote_host \"mkdir -p remote_dir && cd remote_dir && git init --bare\"\n\n? Then you don't have to care about whether the remote side is recent\nenough to support this, and there are no potential security issues; git\nis merely saving you from typing the commands you could have done\nyourself.\n\n> +test_expect_success 'push into nonexisting repository' '\n> +\tthis=$(git rev-parse B) &&\n> +\tgit push \"file://$(pwd)/not-here.git\" B:refs/heads/master &&\n> +\tthat=$(GIT_DIR=not-here.git git rev-parse HEAD) &&\n> +\ttest \"$this\" = \"$that\"\n> +'\n\nI think a feature like this needs to be triggered manually via\n\"--create\" or similar. Otherwise a typo on a regular push will be very\nconfusing as your pushes appear to go nowhere. Though I suppose most\nregular pushes happen using a configured remote, in which case it is not\nas much of an issue.\n\n-Peff\n"},{"id":"106776","messageId":"76718490903022337n79a0c11cw95e80d99cd598d17@mail.gmail.com","threadId":"18072","inReplyTo":"20090303070937.GB30609@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T07:37:34Z","receivedAt":"2009-03-03T07:37:34Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 2:09 AM, Jeff King <peff@peff.net> wrote:\n> If you are going to limit it in that way, wouldn't it be better to do it\n> entirely client-side? As in, \"git push --create remote\" will literally\n> do:\n>\n>    ssh remote_host \"mkdir -p remote_dir && cd remote_dir && git init --bare\"\n>\n> ? Then you don't have to care about whether the remote side is recent\n> enough to support this, and there are no potential security issues; git\n> is merely saving you from typing the commands you could have done\n> yourself.\n\nSo I was curious how Mercurial implemented this, and it is similar to\nwhat Junio coded. It runs \"hg init\" on the remote end via ssh. (hg\ninit <path> takes care of creating the directory; I just also noticed\nyou can do hg init ssh://host/path to create the repo remotely, which\nis I guess sorta interesting.)\n\n> I think a featur like this needs to be triggered manually via\n> \"--create\" or similar. Otherwise a typo on a regular push will be very\n> confusing as your pushes appear to go nowhere. Though I suppose most\n> regular pushes happen using a configured remote, in which case it is not\n> as much of an issue.\n\nSo I could've sworn Mercurial creates a remote repo for you on push,\nbut it turns out it does not:\n\n$ hg push ssh://localhost/~/bar\nremote: abort: There is no Mercurial repository here (.hg not found)!\nabort: no suitable response from remote hg!\n\nI concur w/Jeff and I think git probably should not as well. I think\nthat instead adding it to init might be interesting\n\n\"git init <arg>\" where <arg> is local (and it creates the directory\nand repo for you) or arg is ssh://... and it creates the dir and repo\nover there for you.\n\nAnd have \"git push\" abort with a friendlier message than:\n\nfatal: '~/bar': unable to chdir or not a git archive\nfatal: The remote end hung up unexpectedly\n\nIf that's a plumbing message maybe it can't change, unless push\nswallows it and says something nicer like:\n\nfatal: '~/bar' not a git repository. Create the destination repository\nwith \"git init\" before pushing.\n\nWe can be even friendlier than Mercurial. :-)\n\nj.\n"},{"id":"106777","messageId":"76718490903022339j79f41516kd97a96b2515677d@mail.gmail.com","threadId":"18072","inReplyTo":"76718490903022337n79a0c11cw95e80d99cd598d17@mail.gmail.com","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T07:39:35Z","receivedAt":"2009-03-03T07:39:35Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 2:37 AM, Jay Soffian <jaysoffian@gmail.com> wrote:\n> I concur w/Jeff and I think git probably should not as well.\n\nEr, w/o being told to do so explicitly. I'd argue \"--init\" is a saner\noption name than \"--create\" though since you say \"git init\", not \"git\ncreate\" to make a repo.\n\nj.\n"},{"id":"106780","messageId":"7vy6vnf3aw.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090303070937.GB30609@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T07:55:51Z","receivedAt":"2009-03-03T07:55:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> If you are going to limit it in that way, wouldn't it be better to do it\n> entirely client-side? As in, \"git push --create remote\" will literally\n> do:\n>\n>     ssh remote_host \"mkdir -p remote_dir && cd remote_dir && git init --bare\"\n>\n> ? Then you don't have to care about whether the remote side is recent\n> enough to support this, and there are no potential security issues; git\n> is merely saving you from typing the commands you could have done\n> yourself.\n\nAs with the previous \"git init --remote\" patch, my design constraints\nincludes keeping the door open for \"git shell\" users to optionally allow\nthis mode of operation.\n"},{"id":"106782","messageId":"7vtz6bf392.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"76718490903022337n79a0c11cw95e80d99cd598d17@mail.gmail.com","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T07:56:57Z","receivedAt":"2009-03-03T07:56:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> I concur w/Jeff and I think git probably should not as well. I think\n> that instead adding it to init might be interesting\n\nThe thing is Jeff and Shawn already rejected that route.\n"},{"id":"106784","messageId":"76718490903030002u5a7babe2k6f26b4cc4b48c9d1@mail.gmail.com","threadId":"18072","inReplyTo":"7vtz6bf392.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T08:02:48Z","receivedAt":"2009-03-03T08:02:48Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 2:56 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Jay Soffian <jaysoffian@gmail.com> writes:\n>\n>> I concur w/Jeff and I think git probably should not as well. I think\n>> that instead adding it to init might be interesting\n>\n> The thing is Jeff and Shawn already rejected that route.\n\nOkay. I missed that, so I'll go search for it, but it still seems like\n\"init [<path>|ssh://]\" should be the basis for \"push --init\".\n\nj.\n"},{"id":"106785","messageId":"7vljrnf2wn.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"76718490903030002u5a7babe2k6f26b4cc4b48c9d1@mail.gmail.com","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T08:04:24Z","receivedAt":"2009-03-03T08:04:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> On Tue, Mar 3, 2009 at 2:56 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Jay Soffian <jaysoffian@gmail.com> writes:\n>>\n>>> I concur w/Jeff and I think git probably should not as well. I think\n>>> that instead adding it to init might be interesting\n>>\n>> The thing is Jeff and Shawn already rejected that route.\n>\n> Okay. I missed that, so I'll go search for it, but it still seems like\n> \"init [<path>|ssh://]\" should be the basis for \"push --init\".\n\nIt was called \"init --remote\".\n"},{"id":"106786","messageId":"7vk577f2vq.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"76718490903030002u5a7babe2k6f26b4cc4b48c9d1@mail.gmail.com","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T08:04:57Z","receivedAt":"2009-03-03T08:04:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> On Tue, Mar 3, 2009 at 2:56 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Jay Soffian <jaysoffian@gmail.com> writes:\n>>\n>>> I concur w/Jeff and I think git probably should not as well. I think\n>>> that instead adding it to init might be interesting\n>>\n>> The thing is Jeff and Shawn already rejected that route.\n>\n> Okay. I missed that, so I'll go search for it, but it still seems like\n> \"init [<path>|ssh://]\" should be the basis for \"push --init\".\n\nIt was called \"init --remote\".\n\nNo need to look for it; it is one of the message on the References line of\nthis message, iow, in *this* thread.\n"},{"id":"106787","messageId":"20090303080603.GA3158@coredump.intra.peff.net","threadId":"18072","inReplyTo":"7vy6vnf3aw.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-03T08:06:03Z","receivedAt":"2009-03-03T08:06:03Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 02, 2009 at 11:55:51PM -0800, Junio C Hamano wrote:\n\n> As with the previous \"git init --remote\" patch, my design constraints\n> includes keeping the door open for \"git shell\" users to optionally allow\n> this mode of operation.\n\nOK, I thought your original comment was \"I don't think this constraint\n(thinking only of normal shell users) is right, but here is a patch\nanyway\". Which did leave me confused, since it seemed like your patch\ndid not cater just to such users. But I see now what you meant.\n\nHowever, if you are thinking of \"git shell\" users, then is it not a\npotential security problem to allow them to create new repositories\nwithout the admin explicitly enabling it? If a site is depending on\nhooks in existing repositories to implement some kind of policy, then\nisn't this a way to bypass it (not to make changes in those existing\nrepos, obviously, but let's say there is a policy about how disk usage\nis counted).\n\nEven if it isn't a security issue, it might simply be broken. Shawn has\nsaid that Gerrit needs extra magic when creating a repository, and I\nwouldn't be surprised if github and repo.or.cz were the same. With your\npatch, what switch should a Gerrit admin flip to prevent people from\ncreating broken repos?\n\nWhat about places that might simply want to put some policy in place,\nlike kernel.org having all linux repos point to Linus as alternates?\n\n-Peff\n"},{"id":"106788","messageId":"76718490903030016v68b70dbag304ab7d27e02b40b@mail.gmail.com","threadId":"18072","inReplyTo":"7vk577f2vq.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T08:16:40Z","receivedAt":"2009-03-03T08:16:40Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 3:04 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> It was called \"init --remote\".\n>\n> No need to look for it; it is one of the message on the References line of\n> this message, iow, in *this* thread.\n\nAh, not in gmail's web interface. :-(\n\nj.\n"},{"id":"106790","messageId":"7v63irf21u.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090303080603.GA3158@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T08:22:53Z","receivedAt":"2009-03-03T08:22:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Mon, Mar 02, 2009 at 11:55:51PM -0800, Junio C Hamano wrote:\n>\n>> As with the previous \"git init --remote\" patch, my design constraints\n>> includes keeping the door open for \"git shell\" users to optionally allow\n>> this mode of operation.\n>\n> OK, I thought your original comment was \"I don't think this constraint\n> (thinking only of normal shell users) is right, but here is a patch\n> anyway\". Which did leave me confused, since it seemed like your patch\n> did not cater just to such users. But I see now what you meant.\n\nYeah, I wanted to see if we can give git-shell only people a sane way to\nhost a group project, so that was why I mentioned \"chgrp/chmod\" in the\nfollow-up message to the \"init --remote\" series.\n\n> However, if you are thinking of \"git shell\" users, then is it not a\n> potential security problem to allow them to create new repositories\n> without the admin explicitly enabling it? If a site is depending on\n> hooks in existing repositories to implement some kind of policy, then\n> isn't this a way to bypass it (not to make changes in those existing\n> repos, obviously, but let's say there is a policy about how disk usage\n> is counted).\n\nYes and no.  I think \"git shell\" sites fall broadly into two categories.\nThe ones arranged ala gitosis without per-user UNIX account, it certainly\nis an issue.  The ones with per-user UNIX account would not let anywhere\nother than $HOME written, so it is not.\n\nMy sole interest lies in building a track record of suggested patches to\neliminate the excuse people would use to complain that we do not attempt\nto allow repositories to be created remotely.  I've shown two possible\nways.  It now is turn for those who want to have the feature to fill in\nthe details.  These are weatherbaloon patches, and it is not my itch to\nscratch anyway.\n\n> Even if it isn't a security issue, it might simply be broken. Shawn has\n> said that Gerrit needs extra magic when creating a repository, and I\n> wouldn't be surprised if github and repo.or.cz were the same. With your\n> patch, what switch should a Gerrit admin flip to prevent people from\n> creating broken repos?\n>\n> What about places that might simply want to put some policy in place,\n> like kernel.org having all linux repos point to Linus as alternates?\n\nThese are all valid points and people who are interested in creating\nrepositories remotely must think about them when they finally decide to\nscratch their own itch.  I am merely helping by showing where to add\nhooks.\n"},{"id":"106791","messageId":"20090303082318.GB3158@coredump.intra.peff.net","threadId":"18072","inReplyTo":"7vtz6bf392.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-03T08:23:18Z","receivedAt":"2009-03-03T08:23:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 02, 2009 at 11:56:57PM -0800, Junio C Hamano wrote:\n\n> > I concur w/Jeff and I think git probably should not as well. I think\n> > that instead adding it to init might be interesting\n> \n> The thing is Jeff and Shawn already rejected that route.\n\nSince when do you listen to me? ;P\n\nI think there are actually two issues to be resolved, though:\n\n  1. What is a standardized way for clients to ask for repo creation?\n\n  2. How do users trigger that repo creation.\n\nI think once you have (1), then (2) is easy. You can have \"git init\nhost:dir\", \"git push --init remote\", or whatever, and they can all\ntrigger the same mechanism. For systems which have an out-of-band\nmethod, they can continue to behave as they have, or they can hook into\nthe standardized mechanism as if they were clients themselves. So there\nis not that much point in debating (2), I think, until there is a\nworking (1).\n\nNow (1) is much harder. Some parameters come from the user, but some\n(including whether creation is allowed at all) must come from the site\nadministrator. And some site administrators will a hook to do whatever\nsite-specific magic they need.\n\nWhat about the client just calling init-serve on the server as a program\nwhich does whatever it wants to create a repo? The shipped default would\nbe:\n\n  #!/bin/sh\n  echo >&2 Sorry, repo creation not allowed.\n  exit 1\n\nSites who want to give their users full creation access would do (and\nobviously the --mkdir option would need to be added):\n\n  #!/bin/sh\n  exec git init --mkdir \"$@\"\n\nSites which want to restrict can do:\n\n  #!/bin/sh\n  for i in \"$@\"; do\n    case \"$i\" in\n    --bare) ;;\n         *) echo >&2 Forbidden argument: $i; exit 1 ;;\n    esac\n  done\n  exec git init --mkdir \"$@\"\n\nSites like GitHub or Gerrit can munge the arguments as appropriate. They\ncould even allow site-specific options if they wanted as long as they\nwere syntactically correct (i.e., \"git init --gerrit-base=foo remote\"\nwould pass the argument through to the remote unharmed).\n\n-Peff\n"},{"id":"106792","messageId":"20090303082706.GC3158@coredump.intra.peff.net","threadId":"18072","inReplyTo":"7v63irf21u.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-03T08:27:06Z","receivedAt":"2009-03-03T08:27:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 03, 2009 at 12:22:53AM -0800, Junio C Hamano wrote:\n\n> Yes and no.  I think \"git shell\" sites fall broadly into two categories.\n> The ones arranged ala gitosis without per-user UNIX account, it certainly\n> is an issue.  The ones with per-user UNIX account would not let anywhere\n> other than $HOME written, so it is not.\n\nRight. My problem is that for the former case, there is no switch.\nPeople upgrading git would just get this new feature which has security\nimplications. So I think any patch needs to default to \"off\".\n\n> My sole interest lies in building a track record of suggested patches to\n> eliminate the excuse people would use to complain that we do not attempt\n> to allow repositories to be created remotely.  I've shown two possible\n> ways.  It now is turn for those who want to have the feature to fill in\n> the details.  These are weatherbaloon patches, and it is not my itch to\n> scratch anyway.\n\nWell, that's sneaky of you. ;P\n\nBut I think that coincides with what I was trying to say in my original\nresponse to the series, which is \"this issue is complex, and we need to\nhear from the people who would really want this exactly what it is they\nwant\".\n\n-Peff\n"},{"id":"106793","messageId":"7v1vtff1op.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090303082706.GC3158@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-03T08:30:46Z","receivedAt":"2009-03-03T08:30:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> But I think that coincides with what I was trying to say in my original\n> response to the series, which is \"this issue is complex, and we need to\n> hear from the people who would really want this exactly what it is they\n> want\".\n\nAnd we haven't heard from them at all, unless you and/or Shawn are\ninterested.  After all we may not have to worry about this at all ;-)\n\nAnd that answers your question (1) in the other message.  The standard way\nfor users to create a repository becomes:\n\n\tmkdir this-new-directory\n        cd this-new-directory\n        git init\n"},{"id":"106795","messageId":"76718490903030041r2d1ee1abpb8e0a59d5e4f1c2c@mail.gmail.com","threadId":"18072","inReplyTo":"7v1vtff1op.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T08:41:05Z","receivedAt":"2009-03-03T08:41:05Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 3:30 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> And we haven't heard from them at all\n\nWell, not here anyway, they seem to just complain about it on their\nblogs and git's reputation suffers in silence. :-(\n\n(I don't know when the heck I started to care about git's reputation.)\n\nj.\n"},{"id":"106804","messageId":"20090303092301.GE32284@mit.edu","threadId":"18072","inReplyTo":"7v1vtff1op.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2009-03-03T09:23:01Z","receivedAt":"2009-03-03T09:23:01Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Tue, Mar 03, 2009 at 12:30:46AM -0800, Junio C Hamano wrote:\n> Jeff King <peff@peff.net> writes:\n> \n> > But I think that coincides with what I was trying to say in my original\n> > response to the series, which is \"this issue is complex, and we need to\n> > hear from the people who would really want this exactly what it is they\n> > want\".\n> \n> And we haven't heard from them at all, unless you and/or Shawn are\n> interested.  After all we may not have to worry about this at all ;-)\n\nJunio, I assume you saw Scott James Remnant blog posts, \"Git Sucks\"?\n\n       http://www.netsplit.com/2009/02/17/git-sucks/\n       http://www.netsplit.com/2009/02/17/git-sucks-2/\n       http://www.netsplit.com/2009/02/17/git-sucks-3/\n       http://www.netsplit.com/2009/02/23/revision-control-systems-suck/\n\nMy commentary on his complaint is found here:\n\nhttp://thunk.org/tytso/blog/2009/02/23/reflections-on-a-complaint-from-a-frustrated-git-user/\n\nSome (but not all) of the comments on my blog are also worth reading.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"106813","messageId":"alpine.DEB.1.00.0903031118280.6399@intel-tinevez-2-302","threadId":"18072","inReplyTo":"20090303092301.GE32284@mit.edu","subject":"Re: Subject: [PATCH] Push to create","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-03T10:39:16Z","receivedAt":"2009-03-03T10:39:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 3 Mar 2009, Theodore Tso wrote:\n\n> On Tue, Mar 03, 2009 at 12:30:46AM -0800, Junio C Hamano wrote:\n> > Jeff King <peff@peff.net> writes:\n> > \n> > > But I think that coincides with what I was trying to say in my \n> > > original response to the series, which is \"this issue is complex, \n> > > and we need to hear from the people who would really want this \n> > > exactly what it is they want\".\n> > \n> > And we haven't heard from them at all, unless you and/or Shawn are \n> > interested.  After all we may not have to worry about this at all ;-)\n> \n> Junio, I assume you saw Scott James Remnant blog posts, \"Git Sucks\"?\n> \n>        http://www.netsplit.com/2009/02/17/git-sucks/\n>        http://www.netsplit.com/2009/02/17/git-sucks-2/\n>        http://www.netsplit.com/2009/02/17/git-sucks-3/\n>        http://www.netsplit.com/2009/02/23/revision-control-systems-suck/\n\nI have to admit that I only skimmed the first two: happily, this guy just \nwanted to vent, and chose the correct forum.  His personal blog.\n\nBecause he would have had to do something completely different if he \nwanted to change things.  He would have had to:\n\n- write in the public (i.e. this mailing list),\n\n- guard his language much more,\n\n- actually come up with something useful, constructive instead of \n  repeating several times that Git is hard to use,\n\n- defend that the most important purpose of a revision control system is \n  the initial publication of a branch, as opposed to controlling \n  revisions.\n\nIt reminds me very much of the question: \"Does a universe exist when there \nis nobody in it to observe it?\"\n\nOnly in this case, I would rephrase it to: \"Is a usability wart really \nserious when the guy does not even bother to report it where it can be \nfixed?\"\n\nNeedless to say, I consider the answer to the latter to be \"No.  Really, \nno.\"\n\nI mean, it is easy, really, really easy to say that something sucks.  It \nis so easy that nobody should even pay attention.  Certainly so easy that \nI should not even have bothered writing this mail.\n\nIt is much harder work to come up with solutions, and that is what I am \ninterested in.  So I'll try very hard to ignore everything else.\n\nCiao,\nDscho\n"},{"id":"106908","messageId":"20090303184106.GH14365@spearce.org","threadId":"18072","inReplyTo":"20090303092301.GE32284@mit.edu","subject":"Re: Subject: [PATCH] Push to create","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-03T18:41:06Z","receivedAt":"2009-03-03T18:41:06Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Theodore Tso <tytso@mit.edu> wrote:\n> On Tue, Mar 03, 2009 at 12:30:46AM -0800, Junio C Hamano wrote:\n> > Jeff King <peff@peff.net> writes:\n> > \n> > > But I think that coincides with what I was trying to say in my original\n> > > response to the series, which is \"this issue is complex, and we need to\n> > > hear from the people who would really want this exactly what it is they\n> > > want\".\n> > \n> > And we haven't heard from them at all, unless you and/or Shawn are\n> > interested.  After all we may not have to worry about this at all ;-)\n> \n> Junio, I assume you saw Scott James Remnant blog posts, \"Git Sucks\"?\n> \n>        http://www.netsplit.com/2009/02/17/git-sucks/\n\nFunny, this very blog post is talking about why I think remote\ncreation should be under git push, not \"git init --remote\".\n\nIMHO, maybe we also should change the error message that receive-pack\nproduces when the path its given isn't a Git repository.  Its really\nnot very human friendly to say \"unable to chdir or not a git archive\".\nHell, we don't even call them archives, we call them repositories.\n\n-- \nShawn.\n"},{"id":"106925","messageId":"76718490903031157o2938d46cl6c33e78cf64ad9d1@mail.gmail.com","threadId":"18072","inReplyTo":"20090303082318.GB3158@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-03T19:57:15Z","receivedAt":"2009-03-03T19:57:15Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Mar 3, 2009 at 3:23 AM, Jeff King <peff@peff.net> wrote:\n>\n> What about the client just calling init-serve on the server as a program\n> which does whatever it wants to create a repo? The shipped default would\n> be:\n>\n>  #!/bin/sh\n>  echo >&2 Sorry, repo creation not allowed.\n>  exit 1\n>\n> Sites who want to give their users full creation access would do (and\n> obviously the --mkdir option would need to be added):\n>\n>  #!/bin/sh\n>  exec git init --mkdir \"$@\"\n>\n> Sites which want to restrict can do:\n>\n>  #!/bin/sh\n>  for i in \"$@\"; do\n>    case \"$i\" in\n>    --bare) ;;\n>         *) echo >&2 Forbidden argument: $i; exit 1 ;;\n>    esac\n>  done\n>  exec git init --mkdir \"$@\"\n>\n> Sites like GitHub or Gerrit can munge the arguments as appropriate. They\n> could even allow site-specific options if they wanted as long as they\n> were syntactically correct (i.e., \"git init --gerrit-base=foo remote\"\n> would pass the argument through to the remote unharmed).\n\nFWIW, I like this proposal. The only issue I have which I think simply\ncannot be reconciled is this: it doesn't do anything to help a user\nthat expects \"git push --init ssh://...\" to \"just work\". (And here I'm\nassuming push --init just calls init --remote under the covers.) The\nreason is that such a user is probably just using the git supplied by\ntheir vendor, and thus remote creation is likely disabled by default.\nThe best I can come up with is a different error message:\n\n\"Sorry, remote repo creation not allowed. To enable it, blah blah blah\"\n\nSo at least the user has a clue that git can help them here, but there\nare security reasons it does not do so by default.\n\nj.\n"},{"id":"106931","messageId":"alpine.LNX.1.00.0903031558490.19665@iabervon.org","threadId":"18072","inReplyTo":"7vy6vnf3aw.fsf@gitster.siamese.dyndns.org","subject":"Re: Subject: [PATCH] Push to create","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-03-03T21:08:30Z","receivedAt":"2009-03-03T21:08:30Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 2 Mar 2009, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > If you are going to limit it in that way, wouldn't it be better to do it\n> > entirely client-side? As in, \"git push --create remote\" will literally\n> > do:\n> >\n> >     ssh remote_host \"mkdir -p remote_dir && cd remote_dir && git init --bare\"\n> >\n> > ? Then you don't have to care about whether the remote side is recent\n> > enough to support this, and there are no potential security issues; git\n> > is merely saving you from typing the commands you could have done\n> > yourself.\n> \n> As with the previous \"git init --remote\" patch, my design constraints\n> includes keeping the door open for \"git shell\" users to optionally allow\n> this mode of operation.\n\nOne possibility would be to allow \"git init\" to create the directory (and \nits parents) if it is able. Then the command is \"ssh remote_host \nGIT_DIR=remote_dir git init --bare\". The \"git shell\" users can't use it, \nbut only because \"git shell\" won't run \"git init\". But there's no reason \nit couldn't be configured (per-site or per-user) to allow it. Also, \ngit-init could run the template's \"pre-init\" hook to do whatever it is \nthat needs to be done for a new repository.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"106944","messageId":"20090304054211.GA3753@coredump.intra.peff.net","threadId":"18072","inReplyTo":"76718490903031157o2938d46cl6c33e78cf64ad9d1@mail.gmail.com","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-04T05:42:11Z","receivedAt":"2009-03-04T05:42:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 03, 2009 at 02:57:15PM -0500, Jay Soffian wrote:\n\n> FWIW, I like this proposal. The only issue I have which I think simply\n> cannot be reconciled is this: it doesn't do anything to help a user\n> that expects \"git push --init ssh://...\" to \"just work\". (And here I'm\n> assuming push --init just calls init --remote under the covers.) The\n> reason is that such a user is probably just using the git supplied by\n> their vendor, and thus remote creation is likely disabled by default.\n> The best I can come up with is a different error message:\n> \n> \"Sorry, remote repo creation not allowed. To enable it, blah blah blah\"\n> \n> So at least the user has a clue that git can help them here, but there\n> are security reasons it does not do so by default.\n\nYeah, the error messages should be more descriptive. Sites that have a\nweb interface can even do:\n\n  Sorry, remote repo creation must be down through the web interface.\n  Please go to http://host/$user/create/$repo.\n\nwhere the URL can be customized based on the user and repo that made the\nrequest.\n\nNow we just need somebody who cares enough about this feature to work on\nit. ;)\n\n-Peff\n"},{"id":"106947","messageId":"7vocwh94nd.fsf@gitster.siamese.dyndns.org","threadId":"18072","inReplyTo":"20090304054211.GA3753@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-04T06:35:34Z","receivedAt":"2009-03-04T06:35:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Now we just need somebody who cares enough about this feature to work on\n> it. ;)\n\nWe actually do not need anything.  But somebody who cares enough might\n;-).\n"},{"id":"106951","messageId":"20090304083229.GA31798@coredump.intra.peff.net","threadId":"18072","inReplyTo":"20090303184106.GH14365@spearce.org","subject":"[RFC/PATCH 1/2] improve missing repository error message","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-04T08:32:29Z","receivedAt":"2009-03-04T08:32:29Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Certain remote commands, when asked to do something in a\nparticular directory that was not actually a git repository,\nwould say \"unable to chdir or not a git archive\". The\n\"chdir\" bit is an unnecessary detail, and the term \"git\narchive\" is much less common these days than \"git repository\".\n\nSo let's switch them all to:\n\n  fatal: '%s' does not appear to be a git repository\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nOn Tue, Mar 03, 2009 at 10:41:06AM -0800, Shawn O. Pearce wrote:\n\n> IMHO, maybe we also should change the error message that receive-pack\n> produces when the path its given isn't a Git repository.  Its really\n> not very human friendly to say \"unable to chdir or not a git archive\".\n> Hell, we don't even call them archives, we call them repositories.\n\nI agree completely.\n\nPerhaps this should match the local \"Not a git repository: %s\". I prefer\nthis text, but maybe there is value in consistency.\n\n builtin-receive-pack.c   |    2 +-\n builtin-upload-archive.c |    2 +-\n daemon.c                 |    2 +-\n upload-pack.c            |    2 +-\n 4 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 849f1fe..a970b39 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -675,7 +675,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \tsetup_path();\n \n \tif (!enter_repo(dir, 0))\n-\t\tdie(\"'%s': unable to chdir or not a git archive\", dir);\n+\t\tdie(\"'%s' does not appear to be a git repository\", dir);\n \n \tif (is_repository_shallow())\n \t\tdie(\"attempt to push into a shallow repository\");\ndiff --git a/builtin-upload-archive.c b/builtin-upload-archive.c\nindex a9b02fa..0206b41 100644\n--- a/builtin-upload-archive.c\n+++ b/builtin-upload-archive.c\n@@ -35,7 +35,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)\n \tstrcpy(buf, argv[1]); /* enter-repo smudges its argument */\n \n \tif (!enter_repo(buf, 0))\n-\t\tdie(\"not a git archive\");\n+\t\tdie(\"'%s' does not appear to be a git repository\", buf);\n \n \t/* put received options in sent_argv[] */\n \tsent_argc = 1;\ndiff --git a/daemon.c b/daemon.c\nindex d93cf96..13401f1 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -229,7 +229,7 @@ static char *path_ok(char *directory)\n \t}\n \n \tif (!path) {\n-\t\tlogerror(\"'%s': unable to chdir or not a git archive\", dir);\n+\t\tlogerror(\"'%s' does not appear to be a git repository\", dir);\n \t\treturn NULL;\n \t}\n \ndiff --git a/upload-pack.c b/upload-pack.c\nindex 19c24db..e15ebdc 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -645,7 +645,7 @@ int main(int argc, char **argv)\n \tdir = argv[i];\n \n \tif (!enter_repo(dir, strict))\n-\t\tdie(\"'%s': unable to chdir or not a git archive\", dir);\n+\t\tdie(\"'%s' does not appear to be a git repository\", dir);\n \tif (is_repository_shallow())\n \t\tdie(\"attempt to fetch/clone from a shallow repository\");\n \tif (getenv(\"GIT_DEBUG_SEND_PACK\"))\n-- \n1.6.2.rc2.24.g55bc2\n"},{"id":"106952","messageId":"20090304084245.GB31798@coredump.intra.peff.net","threadId":"18072","inReplyTo":"20090303184106.GH14365@spearce.org","subject":"[RFC/PATCH 2/2] make remote hangup warnings more friendly","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-04T08:42:45Z","receivedAt":"2009-03-04T08:42:45Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When a user asks to do a remote operation but the remote\nside thinks the operation is invalid (e.g., because the user\npointed to a directory which is not actually a repository),\nthen we generally end up showing the user two fatal\nmessages: one from the remote explaining what went wrong, and\none from the local side complaining of an unexpected hangup.\n\nFor example:\n\n  $ git push /nonexistent master\n  fatal: '/nonexistent' does not appear to be a git repository\n  fatal: The remote end hung up unexpectedly\n\nIn this case, the second message is useless noise, and the\nuser is better off seeing just the first.\n\nThis patch tries to suppress the \"hung up\" message when it\nis redundant (but still exits with an error code, of\ncourse).\n\nOne heuristic would be to suppress it whenever the remote\nhas said something on stderr. Unfortunately, in many\ntransports we don't actually handle stderr ourselves; it\nis simply a clone of the parent program's stderr and goes\nstraight to the terminal.\n\nInstead, we note that the remote end will typically perform\nsuch an \"expected\" hangup at the beginning of a packet\ninstead of in the middle. Therefore if we are expecting a\npacket and get an end-of-file from the remote, we assume\nthey have printed something useful and exit without further\nmessages. Any other short read or eof is reported as before.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nThere are two possible problems with this patch:\n\n  1. The \"beginning of packet\" heuristic may not be the best. I\n     tried a few obvious test cases like pushing and fetching with\n     invalid repos and bogus --receive-pack= settings. All of them have\n     useful output from the remote. You would of course get no message\n     if the remote was cut off randomly at just the right spot.\n\n    The \"remote said something on stderr\" heuristic does seem better.\n    But we would have to start processing stderr for local and ssh\n    connections, which we don't do currently. On the other hand, that\n    might be nicer in the long run, because you can mark the remote\n    errors as remote, which makes it more obvious what is going on.\n    E.g.,:\n\n      $ git push host:bogus master\n      remote: fatal: 'bogus' does not appear to be a git repository\n\n  2. Even \"remote said something on stderr\" may not be a desirable\n     heuristic. In the case of a bogus --receive-pack, you get:\n\n       $ git push --receive-pack=bogus host:repo master\n       sh: bogus: command not found\n\n     So you are losing the part where git says \"fatal: \". Maybe it\n     is obvious that such an error is fatal. It is to me, but I am not\n     the intended audience.\n\n     I think this would be improved somewhat with stderr processing to:\n\n       remote: sh: bogus: command not found\n\n     Or you could even trigger the suppression only if stderr had a line\n     matching \"^fatal:\".\n\n     Or it may even be that adding \"remote:\" is enough to make things\n     less confusing:\n\n       remote: fatal: 'bogus' does not appear to be a git repository\n       fatal: The remote end hung up unexpectedly\n\n     I think I still favor suppression in that case, but it is at least\n     more clear why there are two fatals.\n\nSo you can see, the possibilities are endless. The perfect bikeshed. ;)\n\n pkt-line.c |   11 +++++++----\n 1 files changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/pkt-line.c b/pkt-line.c\nindex f5d0086..f2b387c 100644\n--- a/pkt-line.c\n+++ b/pkt-line.c\n@@ -63,13 +63,16 @@ void packet_write(int fd, const char *fmt, ...)\n \tsafe_write(fd, buffer, n);\n }\n \n-static void safe_read(int fd, void *buffer, unsigned size)\n+static void safe_read(int fd, void *buffer, unsigned size, int eof_warn)\n {\n \tssize_t ret = read_in_full(fd, buffer, size);\n \tif (ret < 0)\n \t\tdie(\"read error (%s)\", strerror(errno));\n-\telse if (ret < size)\n+\telse if (ret < size) {\n+\t\tif (ret == 0 && !eof_warn)\n+\t\t\texit(128);\n \t\tdie(\"The remote end hung up unexpectedly\");\n+\t}\n }\n \n int packet_read_line(int fd, char *buffer, unsigned size)\n@@ -78,7 +81,7 @@ int packet_read_line(int fd, char *buffer, unsigned size)\n \tunsigned len;\n \tchar linelen[4];\n \n-\tsafe_read(fd, linelen, 4);\n+\tsafe_read(fd, linelen, 4, 0);\n \n \tlen = 0;\n \tfor (n = 0; n < 4; n++) {\n@@ -103,7 +106,7 @@ int packet_read_line(int fd, char *buffer, unsigned size)\n \tlen -= 4;\n \tif (len >= size)\n \t\tdie(\"protocol error: bad line length %d\", len);\n-\tsafe_read(fd, buffer, len);\n+\tsafe_read(fd, buffer, len, 1);\n \tbuffer[len] = 0;\n \treturn len;\n }\n-- \n1.6.2.rc2.24.g55bc2\n"},{"id":"106954","messageId":"vpqtz69lk6a.fsf@bauges.imag.fr","threadId":"18072","inReplyTo":"20090304083229.GA31798@coredump.intra.peff.net","subject":"Re: [RFC/PATCH 1/2] improve missing repository error message","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2009-03-04T09:19:25Z","receivedAt":"2009-03-04T09:19:25Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> +\t\tdie(\"'%s' does not appear to be a git repository\", dir);\n\nIt may be sensible to distinguish the case where dir exists as a\ndirectory but isn't a repository, and the case where it does not exist\nat all, like \"directory exists but does not appear to be a git\nrepository\" Vs \"no such directory\".\n\nJust in case someone does a \"mkdir\" on the server and doesn't know he\nhas to \"git init\" there too.\n\nMy 2 cents,\n\n-- \nMatthieu\n"},{"id":"106963","messageId":"20090304103556.GB16123@coredump.intra.peff.net","threadId":"18072","inReplyTo":"vpqtz69lk6a.fsf@bauges.imag.fr","subject":"Re: [RFC/PATCH 1/2] improve missing repository error message","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-04T10:35:56Z","receivedAt":"2009-03-04T10:35:56Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 04, 2009 at 10:19:25AM +0100, Matthieu Moy wrote:\n\n> > +\t\tdie(\"'%s' does not appear to be a git repository\", dir);\n> \n> It may be sensible to distinguish the case where dir exists as a\n> directory but isn't a repository, and the case where it does not exist\n> at all, like \"directory exists but does not appear to be a git\n> repository\" Vs \"no such directory\".\n> \n> Just in case someone does a \"mkdir\" on the server and doesn't know he\n> has to \"git init\" there too.\n\nI agree it would be nice to be more descriptive; however, it's not quite\nas simple as checking if the chdir failed. For \"non-strict\" repo lookup,\nwe check a number of variants. For $foo, we check:\n\n  $foo.git/.git\n  $foo/.git\n  $foo.git\n  $foo\n\nIf $foo exists but isn't a git directory, but $foo/.git does not exist,\nthen what is the correct response?  I guess we can say \"no such\ndirectory\" only if $foo and $foo.git don't exist, and \"not a git\nrepository\" for the others.\n\nI also don't know if we care about information leakage; with such a\npatch can I now start probing the existence of arbitrary directories via\ngit-daemon (I haven't checked to see if there are other path\nrestrictions in place)?\n\n-Peff\n"},{"id":"106973","messageId":"76718490903040506o3519ff90r38c9f4e3ea9e45af@mail.gmail.com","threadId":"18072","inReplyTo":"20090304054211.GA3753@coredump.intra.peff.net","subject":"Re: Subject: [PATCH] Push to create","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-04T13:06:45Z","receivedAt":"2009-03-04T13:06:45Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Wed, Mar 4, 2009 at 12:42 AM, Jeff King <peff@peff.net> wrote:\n> Now we just need somebody who cares enough about this feature to work on\n> it. ;)\n\nI'll see what I can do with the patches Junio sent.\n\n(See Junio, I care enough.) :-)\n\nj.\n"},{"id":"106997","messageId":"20090304175830.GA6305@mit.edu","threadId":"18072","inReplyTo":"alpine.DEB.1.00.0903031118280.6399@intel-tinevez-2-302","subject":"Re: Subject: [PATCH] Push to create","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2009-03-04T17:58:30Z","receivedAt":"2009-03-04T17:58:30Z","isPatch":true,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Tue, Mar 03, 2009 at 11:39:16AM +0100, Johannes Schindelin wrote:\n> Only in this case, I would rephrase it to: \"Is a usability wart really \n> serious when the guy does not even bother to report it where it can be \n> fixed?\"\n> \n> It is much harder work to come up with solutions, and that is what I am \n> interested in.  So I'll try very hard to ignore everything else.\n\nWell, I think there is a point hiding behind all of his whining, which\nis that if you aren't joining a big established project, but are\nrather the maintainer of an existing project that wants to move over\nto git, or someone who is starting a new project, and decides to use\ngit because they've heard it's all the rage --- but the tutorials and\nthe documentation don't do that great of a job pointing people to the\nright place.\n\nFor example, the git tutorial's \"Using got for collaboration\" assumes\nthat Alice and Bob have accounts on the same system.  C'mon!\nTime-sharing systems are so.... 1970's.  Granted that arranging SSH\naccess is non-trivial, but there are plenty of web sites that offer\nfree git hosting services: repo.or.oz, gitorious, Github, and now\nSourceforge.  The tutorial should at least point people at the git\nhosting sites.\n\nOne of the advantages that bzr has is that it is integrated fairly\ntightly with Launchpad, which has its own bzr hosting service.  So the\ndocumentation is easier, and with Launchpad's integration into bzr's\nUI, a bzr user can publish a branch in a single command line (assuming\nthey are a registered launchpad user and have an account on launchpad):\n\n\tbzr push lp:~userid/project-name/branch-name\n\nIt's going to be hard for git to be able to match this usability,\ngiven that we need to do something that works with multiple hosting\nfacilities, and not just tie ourselves to a single system like\ngitorious, Github, or Sourceforge.  (Although I could imagine some\nkind of plugin/hook system where once the plugin for a particular git\nhosting facility was installed, git could be much more tightly\nintegrated with a particular hosting service.)\n\nAt the very least, though, it should be relatively easy to update our\ndocumentation to at least acknowledge the many and varied free git\nhosting services; it's not like we need to tell people that the only\nway to share repositories involves setting up an ssh or Apache server.\n\n\t\t\t\t\t- Ted\n\n\nP.S.  For more details about the bzr/Launchpad integration, see:\n\nhttp://doc.bazaar-vcs.org/bzr.dev/en/tutorials/using_bazaar_with_launchpad.html\n"},{"id":"106998","messageId":"20090304185742.GI14365@spearce.org","threadId":"18072","inReplyTo":"20090304083229.GA31798@coredump.intra.peff.net","subject":"Re: [RFC/PATCH 1/2] improve missing repository error message","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-04T18:57:42Z","receivedAt":"2009-03-04T18:57:42Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jeff King <peff@peff.net> wrote:\n> Certain remote commands, when asked to do something in a\n> particular directory that was not actually a git repository,\n> would say \"unable to chdir or not a git archive\". The\n> \"chdir\" bit is an unnecessary detail, and the term \"git\n> archive\" is much less common these days than \"git repository\".\n> \n> So let's switch them all to:\n> \n>   fatal: '%s' does not appear to be a git repository\n> \n> Signed-off-by: Jeff King <peff@peff.net>\n\nAcked-by: Shawn O. Pearce <spearce@spearce.org>\n\n> On Tue, Mar 03, 2009 at 10:41:06AM -0800, Shawn O. Pearce wrote:\n> \n> > IMHO, maybe we also should change the error message that receive-pack\n> > produces when the path its given isn't a Git repository.  Its really\n> > not very human friendly to say \"unable to chdir or not a git archive\".\n> > Hell, we don't even call them archives, we call them repositories.\n\nI really mean to write this patch myself, I haven't done much for\ngit lately.  But I got sidetracked yesterday and forgot.  Thank you\nfor doing it for me.\n\n> Perhaps this should match the local \"Not a git repository: %s\". I prefer\n> this text, but maybe there is value in consistency.\n\nFWIW I also prefer the text you used in the patch...\n\n-- \nShawn.\n"},{"id":"106999","messageId":"20090304190452.GJ14365@spearce.org","threadId":"18072","inReplyTo":"20090304084245.GB31798@coredump.intra.peff.net","subject":"Re: [RFC/PATCH 2/2] make remote hangup warnings more friendly","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-04T19:04:52Z","receivedAt":"2009-03-04T19:04:52Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jeff King <peff@peff.net> wrote:\n> When a user asks to do a remote operation but the remote\n> side thinks the operation is invalid (e.g., because the user\n> pointed to a directory which is not actually a repository),\n> then we generally end up showing the user two fatal\n> messages: one from the remote explaining what went wrong, and\n> one from the local side complaining of an unexpected hangup.\n> \n> For example:\n> \n>   $ git push /nonexistent master\n>   fatal: '/nonexistent' does not appear to be a git repository\n>   fatal: The remote end hung up unexpectedly\n \n> In this case, the second message is useless noise, and the\n> user is better off seeing just the first.\n> \n> This patch tries to suppress the \"hung up\" message when it\n> is redundant (but still exits with an error code, of\n> course).\n\nHmm.  It would be nice to clean up these messages, but I\nthink the better way to do it is...\n \n>      I think this would be improved somewhat with stderr processing to:\n> \n>        remote: sh: bogus: command not found\n\n... because then we can have positive proof that the remote said\nsomething to the user, and we tagged it as being from the remote\nside, just like we do with progress data in sideband, and then the\nuser can work from that information.  Any local side errors are\nvery likely caused by the remote errors, so we shouldn't bother\ndisplaying them.\n\nBut its a lot more invasive of a patch to setup stderr processing\nfor pipe/SSH.\n\nActually, the remote stderr processing is desired for more than\njust the bad path case.  Its good for when the remote aborts with\na write error from a write_or_die(), at least we know it was on\nthe remote side and not the local.  Its good for when the remote\nshell says a \"git-upload-pack: command not found\".  Its good for\nwhen the remote hook prints output, the client knows it came from\nthe remote side and not something local, so its messages should be\nread in the context of the remote side.  Etc.\n \n-- \nShawn.\n"},{"id":"107051","messageId":"20090305103659.GA17196@coredump.intra.peff.net","threadId":"18072","inReplyTo":"20090304185742.GI14365@spearce.org","subject":"Re: [RFC/PATCH 1/2] improve missing repository error message","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-05T10:36:59Z","receivedAt":"2009-03-05T10:36:59Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 04, 2009 at 10:57:42AM -0800, Shawn O. Pearce wrote:\n\n> > > IMHO, maybe we also should change the error message that receive-pack\n> > > produces when the path its given isn't a Git repository.  Its really\n> > > not very human friendly to say \"unable to chdir or not a git archive\".\n> > > Hell, we don't even call them archives, we call them repositories.\n> \n> I really mean to write this patch myself, I haven't done much for\n> git lately.  But I got sidetracked yesterday and forgot.  Thank you\n> for doing it for me.\n\nI think you are OK coasting on past glory for a while longer:\n\n  $ git shortlog -ns | egrep -im2 'jeff|shawn'\n  1313  Shawn O. Pearce\n   305  Jeff King\n\n:)\n\n> > Perhaps this should match the local \"Not a git repository: %s\". I prefer\n> > this text, but maybe there is value in consistency.\n> \n> FWIW I also prefer the text you used in the patch...\n\nI don't know if it is worth changing the _local_ one to match this,\nthen. I seem to recall some discussion about that message recently.\nPersonally I find the \"Not a git repository (or any of the parent\ndirectories)\" wording to be quite awkward.\n\n-Peff\n"},{"id":"107054","messageId":"20090305104506.GB17196@coredump.intra.peff.net","threadId":"18072","inReplyTo":"20090304190452.GJ14365@spearce.org","subject":"Re: [RFC/PATCH 2/2] make remote hangup warnings more friendly","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-05T10:45:06Z","receivedAt":"2009-03-05T10:45:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 04, 2009 at 11:04:52AM -0800, Shawn O. Pearce wrote:\n\n> Hmm.  It would be nice to clean up these messages, but I\n> think the better way to do it is...\n>  \n> >      I think this would be improved somewhat with stderr processing to:\n> > \n> >        remote: sh: bogus: command not found\n> \n> ... because then we can have positive proof that the remote said\n> something to the user, and we tagged it as being from the remote\n> side, just like we do with progress data in sideband, and then the\n> user can work from that information.  Any local side errors are\n> very likely caused by the remote errors, so we shouldn't bother\n> displaying them.\n\nOK. I was hoping to avoid that because it's more work, but I think it is\na better path in the long run. I'll add it to do my todo list. Unless\nyou want to redeem yourself by working on it first. ;)\n\n-Peff\n"},{"id":"107127","messageId":"87sklrfn3m.fsf@catnip.gol.com","threadId":"18072","inReplyTo":"20090304175830.GA6305@mit.edu","subject":"Re: Subject: [PATCH] Push to create","fromName":"Miles Bader","fromEmail":"miles@gnu.org","sentAt":"2009-03-06T01:37:17Z","receivedAt":"2009-03-06T01:37:17Z","isPatch":true,"sender":{"key":"miles@gnu.org","avatar":"https://gravatar.com/avatar/01069b69593af7bff28e2f97afeb3644ae6fe2f5f56cb3a8cf34c5fb8c36efe5?d=mp&s=160"},"body":"Theodore Tso <tytso@mit.edu> writes:\n> One of the advantages that bzr has is that it is integrated fairly\n> tightly with Launchpad\n\nTo be honest, that seems vaguely creepy...\n\n-Miles\n\n-- \nFriendship, n. A ship big enough to carry two in fair weather, but only one\nin foul.\n"}]}