{"thread":{"id":"8208","subject":"[PATCH 04/16] git-config: read remote config files over HTTP","startedAt":"2007-05-18T19:24:49Z","lastAt":"2007-05-25T22:11:12Z","messageCount":63,"participants":["skimo@liacs.nl","Sven Verdoolaege","Alex Riesen","Junio C Hamano","Petr Baudis","Shawn O. Pearce","Jan Hudec","Martin Waitz","Jakub Narebski","Steven Grimm"],"isPatch":true,"patchVersion":1,"patchTotal":16},"messages":[{"id":"42516","messageId":"11795163053812-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":null,"subject":"Second round of support for cloning submodules","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:49Z","receivedAt":"2007-05-18T19:24:49Z","isPatch":false,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis patch series implements a mechanism for cloning submodules.\nEach submodule is specified by a 'submodule.<submodule>.url'\nconfiguration option, e.g.,\n\nbash-3.00$ ./git-config --remote=http://www.liacs.nl/~sverdool/isa.git --get-regexp 'submodule\\..*\\.url' \nsubmodule.cloog.url /home/sverdool/public_html/cloog.git\nsubmodule.cloog.url http://www.liacs.nl/~sverdool/cloog.git\n\ngit-clone will use the first url that works.\nE.g., a\n\ngit clone --submodules ssh://liacs/~/public_html/isa.git\n\n(which only works for me), will use the first url, while a\n\ngit clone --submodules http://www.liacs.nl/~sverdool/isa.git\n\nwill use the second.\n\nThe cloning of submodules is now handled inside git-fetch.\n\nskimo\n"},{"id":"42512","messageId":"11795163051366-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 01/16] Add dump-config","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:50Z","receivedAt":"2007-05-18T19:24:50Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis command dumps the config of a repository and will be used\nto read config options from a remote site.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n .gitignore                        |    1 +\n Documentation/cmd-list.perl       |    1 +\n Documentation/git-dump-config.txt |   37 +++++++++++++++++++++++++++++++++++++\n Makefile                          |    1 +\n daemon.c                          |    7 +++++++\n dump-config.c                     |   29 +++++++++++++++++++++++++++++\n 6 files changed, 76 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-dump-config.txt\n create mode 100644 dump-config.c\n\ndiff --git a/.gitignore b/.gitignore\nindex 4dc0c39..d4e5492 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -38,6 +38,7 @@ git-diff-files\n git-diff-index\n git-diff-tree\n git-describe\n+git-dump-config\n git-fast-import\n git-fetch\n git-fetch--tool\ndiff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl\nindex 443802a..fa04615 100755\n--- a/Documentation/cmd-list.perl\n+++ b/Documentation/cmd-list.perl\n@@ -103,6 +103,7 @@ git-diff-files                          plumbinginterrogators\n git-diff-index                          plumbinginterrogators\n git-diff                                mainporcelain\n git-diff-tree                           plumbinginterrogators\n+git-dump-config                         synchelpers\n git-fast-import\t\t\t\tancillarymanipulators\n git-fetch                               mainporcelain\n git-fetch-pack                          synchingrepositories\ndiff --git a/Documentation/git-dump-config.txt b/Documentation/git-dump-config.txt\nnew file mode 100644\nindex 0000000..370781c\n--- /dev/null\n+++ b/Documentation/git-dump-config.txt\n@@ -0,0 +1,37 @@\n+git-dump-config(1)\n+====================\n+\n+NAME\n+----\n+git-dump-config - Dump config options\n+\n+\n+SYNOPSIS\n+--------\n+'git-dump-config' <directory>\n+\n+DESCRIPTION\n+-----------\n+Invoked by 'git-config --remote' and dumps the config file to the\n+other end over the git protocol.\n+\n+This command is usually not invoked directly by the end user.  The UI\n+for the protocol is on the 'git-config' side, where it is used to get\n+options from a remote repository.\n+\n+OPTIONS\n+-------\n+<directory>::\n+\tThe repository to get the config options from.\n+\n+Author\n+------\n+Written by Sven Verdoolaege.\n+\n+Documentation\n+--------------\n+Documentation by Sven Verdoolaege.\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\ndiff --git a/Makefile b/Makefile\nindex 29243c6..37eb861 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -240,6 +240,7 @@ PROGRAMS = \\\n \tgit-fast-import$X \\\n \tgit-merge-base$X \\\n \tgit-daemon$X \\\n+\tgit-dump-config$X \\\n \tgit-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \\\n \tgit-peek-remote$X git-receive-pack$X \\\n \tgit-send-pack$X git-shell$X \\\ndiff --git a/daemon.c b/daemon.c\nindex e74ecac..3e5ebf3 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -378,10 +378,17 @@ static int receive_pack(void)\n \treturn -1;\n }\n \n+static int dump_config(void)\n+{\n+\texecl_git_cmd(\"dump-config\", \".\", NULL);\n+\treturn -1;\n+}\n+\n static struct daemon_service daemon_service[] = {\n \t{ \"upload-archive\", \"uploadarch\", upload_archive, 0, 1 },\n \t{ \"upload-pack\", \"uploadpack\", upload_pack, 1, 1 },\n \t{ \"receive-pack\", \"receivepack\", receive_pack, 0, 1 },\n+\t{ \"dump-config\", \"dumpconfig\", dump_config, 0, 1 },\n };\n \n static void enable_service(const char *name, int ena) {\ndiff --git a/dump-config.c b/dump-config.c\nnew file mode 100644\nindex 0000000..355920d\n--- /dev/null\n+++ b/dump-config.c\n@@ -0,0 +1,29 @@\n+#include \"git-compat-util.h\"\n+#include \"cache.h\"\n+#include \"pkt-line.h\"\n+\n+static const char dump_config_usage[] = \"git-dump-config <dir>\";\n+\n+static int dump_config(const char *var, const char *value)\n+{\n+\tpacket_write(1, \"%s\", var);\n+\tpacket_write(1, \"%s\", value);\n+\treturn 0;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tchar *dir;\n+\n+\tif (argc != 2)\n+\t\tusage(dump_config_usage);\n+\n+\tdir = argv[1];\n+\tif (!enter_repo(dir, 0))\n+\t\tdie(\"'%s': unable to chdir or not a git archive\", dir);\n+\n+\tgit_config(dump_config);\n+\tpacket_flush(1);\n+\n+\treturn 0;\n+}\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42513","messageId":"11795163064160-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 02/16] git-config: add --remote option for reading config from remote repo","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:51Z","receivedAt":"2007-05-18T19:24:51Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n Documentation/git-config.txt |   33 +++++++++++++++++++++---------\n builtin-config.c             |   44 ++++++++++++++++++++++++++++++++---------\n cache.h                      |    1 +\n config.c                     |   26 ++++++++++++++++++++++++\n 4 files changed, 84 insertions(+), 20 deletions(-)\n\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex 280ef20..76398ab 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -9,16 +9,25 @@ git-config - Get and set repository or global options\n SYNOPSIS\n --------\n [verse]\n-'git-config' [--system | --global] [type] name [value [value_regex]]\n-'git-config' [--system | --global] [type] --add name value\n-'git-config' [--system | --global] [type] --replace-all name [value [value_regex]]\n-'git-config' [--system | --global] [type] --get name [value_regex]\n-'git-config' [--system | --global] [type] --get-all name [value_regex]\n-'git-config' [--system | --global] [type] --unset name [value_regex]\n-'git-config' [--system | --global] [type] --unset-all name [value_regex]\n-'git-config' [--system | --global] [type] --rename-section old_name new_name\n-'git-config' [--system | --global] [type] --remove-section name\n-'git-config' [--system | --global] -l | --list\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] name [value [value_regex]]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --add name value\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --replace-all name [value [value_regex]]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --get name [value_regex]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --get-all name [value_regex]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --unset name [value_regex]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --unset-all name [value_regex]\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --rename-section old_name new_name\n+'git-config' [--system | --global | --remote=[<host>:]<directory ]\n+\t     [type] --remove-section name\n+'git-config' [--system | --global | --remote=[<host>:]<directory ] -l | --list\n \n DESCRIPTION\n -----------\n@@ -80,6 +89,10 @@ OPTIONS\n \tUse system-wide $(prefix)/etc/gitconfig rather than the repository\n \t.git/config.\n \n+--remote=[<host>:]<directory\n+\tUse remote config instead of the repository .git/config.\n+\tOnly available for reading options.\n+\n --remove-section::\n \tRemove the given section from the configuration file.\n \ndiff --git a/builtin-config.c b/builtin-config.c\nindex b2515f7..3a1e86c 100644\n--- a/builtin-config.c\n+++ b/builtin-config.c\n@@ -2,8 +2,10 @@\n #include \"cache.h\"\n \n static const char git_config_set_usage[] =\n-\"git-config [ --global | --system ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list\";\n+\"git-config [ --global | --system | --remote=[<host>:]<directory ] \"\n+\"[ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list\";\n \n+static char *dest;\n static char *key;\n static regex_t *key_regexp;\n static regex_t *regexp;\n@@ -104,15 +106,19 @@ static int get_value(const char* key_, const char* regex_)\n \t\t}\n \t}\n \n-\tif (do_all && system_wide)\n-\t\tgit_config_from_file(show_config, system_wide);\n-\tif (do_all && global)\n-\t\tgit_config_from_file(show_config, global);\n-\tgit_config_from_file(show_config, local);\n-\tif (!do_all && !seen && global)\n-\t\tgit_config_from_file(show_config, global);\n-\tif (!do_all && !seen && system_wide)\n-\t\tgit_config_from_file(show_config, system_wide);\n+\tif (dest)\n+\t\tgit_config_from_remote(show_config, dest);\n+\telse {\n+\t\tif (do_all && system_wide)\n+\t\t\tgit_config_from_file(show_config, system_wide);\n+\t\tif (do_all && global)\n+\t\t\tgit_config_from_file(show_config, global);\n+\t\tgit_config_from_file(show_config, local);\n+\t\tif (!do_all && !seen && global)\n+\t\t\tgit_config_from_file(show_config, global);\n+\t\tif (!do_all && !seen && system_wide)\n+\t\t\tgit_config_from_file(show_config, system_wide);\n+\t}\n \n \tfree(key);\n \tif (regexp) {\n@@ -155,8 +161,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\telse if (!strcmp(argv[1], \"--system\"))\n \t\t\tsetenv(\"GIT_CONFIG\", ETC_GITCONFIG, 1);\n+\t\telse if (!prefixcmp(argv[1], \"--remote=\"))\n+\t\t\tdest = xstrdup(argv[1]+9);\n \t\telse if (!strcmp(argv[1], \"--rename-section\")) {\n \t\t\tint ret;\n+\t\t\tif (dest) {\n+\t\t\t\tfprintf(stderr, \"Cannot rename on remote\\n\");\n+\t\t\t\treturn 1;\n+\t\t\t}\n \t\t\tif (argc != 4)\n \t\t\t\tusage(git_config_set_usage);\n \t\t\tret = git_config_rename_section(argv[2], argv[3]);\n@@ -170,6 +182,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\telse if (!strcmp(argv[1], \"--remove-section\")) {\n \t\t\tint ret;\n+\t\t\tif (dest) {\n+\t\t\t\tfprintf(stderr, \"Cannot remove on remote\\n\");\n+\t\t\t\treturn 1;\n+\t\t\t}\n \t\t\tif (argc != 3)\n \t\t\t\tusage(git_config_set_usage);\n \t\t\tret = git_config_rename_section(argv[2], NULL);\n@@ -191,6 +207,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \tcase 2:\n \t\treturn get_value(argv[1], NULL);\n \tcase 3:\n+\t\tif (dest && prefixcmp(argv[1], \"--get\")) {\n+\t\t\tfprintf(stderr, \"Cannot (un)set on remote\\n\");\n+\t\t\treturn 1;\n+\t\t}\n \t\tif (!strcmp(argv[1], \"--unset\"))\n \t\t\treturn git_config_set(argv[2], NULL);\n \t\telse if (!strcmp(argv[1], \"--unset-all\"))\n@@ -209,6 +229,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \n \t\t\treturn git_config_set(argv[1], argv[2]);\n \tcase 4:\n+\t\tif (dest && prefixcmp(argv[1], \"--get\")) {\n+\t\t\tfprintf(stderr, \"Cannot (un)set on remote\\n\");\n+\t\t\treturn 1;\n+\t\t}\n \t\tif (!strcmp(argv[1], \"--unset\"))\n \t\t\treturn git_config_set_multivar(argv[2], NULL, argv[3], 0);\n \t\telse if (!strcmp(argv[1], \"--unset-all\"))\ndiff --git a/cache.h b/cache.h\nindex e34958b..6acc330 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -501,6 +501,7 @@ extern int update_server_info(int);\n typedef int (*config_fn_t)(const char *, const char *);\n extern int git_default_config(const char *, const char *);\n extern int git_config_from_file(config_fn_t fn, const char *);\n+extern int git_config_from_remote(config_fn_t fn, char *dest);\n extern int git_config(config_fn_t fn);\n extern int git_config_int(const char *, const char *);\n extern int git_config_bool(const char *, const char *);\ndiff --git a/config.c b/config.c\nindex 0614c2b..dbfae3f 100644\n--- a/config.c\n+++ b/config.c\n@@ -6,9 +6,12 @@\n  *\n  */\n #include \"cache.h\"\n+#include \"pkt-line.h\"\n \n #define MAXNAME (256)\n \n+static const char *dumpconfig = \"git-dump-config\";\n+\n static FILE *config_file;\n static const char *config_file_name;\n static int config_linenr;\n@@ -403,6 +406,29 @@ int git_config_from_file(config_fn_t fn, const char *filename)\n \treturn ret;\n }\n \n+int git_config_from_remote(config_fn_t fn, char *dest)\n+{\n+\tint ret;\n+\tint fd[2];\n+\tpid_t pid;\n+\tstatic char var[MAXNAME];\n+\tstatic char value[1024];\n+\n+\tpid = git_connect(fd, dest, dumpconfig);\n+\tif (pid < 0)\n+\t\treturn 1;\n+\tret = 0;\n+\twhile (packet_read_line(fd[0], var, sizeof(var))) {\n+\t\tif (!packet_read_line(fd[0], value, sizeof(value)))\n+\t\t\tdie(\"Missing value\");\n+\t\tfn(var, value);\n+\t}\n+\tclose(fd[0]);\n+\tclose(fd[1]);\n+\tret |= finish_connect(pid);\n+\treturn !!ret;\n+}\n+\n int git_config(config_fn_t fn)\n {\n \tint ret = 0;\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42520","messageId":"11795163062901-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 03/16] http.h: make fill_active_slots a function pointer","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:52Z","receivedAt":"2007-05-18T19:24:52Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis allows us to use the methods provided by http.c\nfrom within libgit, in particular config.c.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n http-fetch.c |    5 ++++-\n http-push.c  |    5 ++++-\n http.h       |    2 +-\n 3 files changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 09baedc..53fb2a9 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -317,7 +317,7 @@ static void release_object_request(struct object_request *obj_req)\n }\n \n #ifdef USE_CURL_MULTI\n-void fill_active_slots(void)\n+static void fetch_fill_active_slots(void)\n {\n \tstruct object_request *obj_req = object_queue_head;\n \tstruct active_request_slot *slot = active_queue_head;\n@@ -1031,6 +1031,9 @@ int main(int argc, const char **argv)\n \t}\n \turl = argv[arg];\n \n+#ifdef USE_CURL_MULTI\n+\tfill_active_slots = fetch_fill_active_slots;\n+#endif\n \thttp_init();\n \n \tno_pragma_header = curl_slist_append(no_pragma_header, \"Pragma:\");\ndiff --git a/http-push.c b/http-push.c\nindex e3f7675..d4c850b 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -794,7 +794,7 @@ static void finish_request(struct transfer_request *request)\n }\n \n #ifdef USE_CURL_MULTI\n-void fill_active_slots(void)\n+static void push_fill_active_slots(void)\n {\n \tstruct transfer_request *request = request_queue_head;\n \tstruct transfer_request *next;\n@@ -2355,6 +2355,9 @@ int main(int argc, char **argv)\n \n \tmemset(remote_dir_exists, -1, 256);\n \n+#ifdef USE_CURL_MULTI\n+\tfill_active_slots = push_fill_active_slots;\n+#endif\n \thttp_init();\n \n \tno_pragma_header = curl_slist_append(no_pragma_header, \"Pragma:\");\ndiff --git a/http.h b/http.h\nindex 69b6b66..7a41cde 100644\n--- a/http.h\n+++ b/http.h\n@@ -69,7 +69,7 @@ extern void finish_all_active_slots(void);\n extern void release_active_slot(struct active_request_slot *slot);\n \n #ifdef USE_CURL_MULTI\n-extern void fill_active_slots(void);\n+extern void (*fill_active_slots)(void);\n extern void step_active_slots(void);\n #endif\n \n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42511","messageId":"117951630670-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 04/16] git-config: read remote config files over HTTP","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:53Z","receivedAt":"2007-05-18T19:24:53Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n Makefile           |    7 ++++++-\n builtin-config.c   |    8 ++++++--\n config.c           |   16 +++++++++++++++-\n http.c             |   10 ++++++----\n http.h             |    2 +-\n http_config.h      |    1 +\n http_config_curl.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n http_config_none.c |    6 ++++++\n 8 files changed, 93 insertions(+), 9 deletions(-)\n create mode 100644 http_config.h\n create mode 100644 http_config_curl.c\n create mode 100644 http_config_none.c\n\ndiff --git a/Makefile b/Makefile\nindex 37eb861..bce8514 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -319,7 +319,8 @@ LIB_OBJS = \\\n \twrite_or_die.o trace.o list-objects.o grep.o match-trees.o \\\n \talloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \\\n \tcolor.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \\\n-\tconvert.o attr.o decorate.o progress.o mailmap.o symlinks.o\n+\tconvert.o attr.o decorate.o progress.o mailmap.o symlinks.o \\\n+\t$(HTTP_CONFIG_OBJ)\n \n BUILTIN_OBJS = \\\n \tbuiltin-add.o \\\n@@ -526,6 +527,10 @@ ifndef NO_CURL\n \tifndef NO_EXPAT\n \t\tEXPAT_LIBEXPAT = -lexpat\n \tendif\n+\tHTTP_CONFIG_OBJ = http_config_curl.o http.o\n+\tEXTLIBS += $(CURL_LIBCURL)\n+else\n+\tHTTP_CONFIG_OBJ = http_config_none.o\n endif\n \n ifndef NO_OPENSSL\ndiff --git a/builtin-config.c b/builtin-config.c\nindex 3a1e86c..7e18f73 100644\n--- a/builtin-config.c\n+++ b/builtin-config.c\n@@ -147,8 +147,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t\ttype = T_INT;\n \t\telse if (!strcmp(argv[1], \"--bool\"))\n \t\t\ttype = T_BOOL;\n-\t\telse if (!strcmp(argv[1], \"--list\") || !strcmp(argv[1], \"-l\"))\n-\t\t\treturn git_config(show_all_config);\n+\t\telse if (!strcmp(argv[1], \"--list\") || !strcmp(argv[1], \"-l\")) {\n+\t\t\tif (dest)\n+\t\t\t\treturn git_config_from_remote(show_all_config, dest);\n+\t\t\telse\n+\t\t\t\treturn git_config(show_all_config);\n+\t\t}\n \t\telse if (!strcmp(argv[1], \"--global\")) {\n \t\t\tchar *home = getenv(\"HOME\");\n \t\t\tif (home) {\ndiff --git a/config.c b/config.c\nindex dbfae3f..fc2162b 100644\n--- a/config.c\n+++ b/config.c\n@@ -7,6 +7,7 @@\n  */\n #include \"cache.h\"\n #include \"pkt-line.h\"\n+#include \"http_config.h\"\n \n #define MAXNAME (256)\n \n@@ -406,6 +407,16 @@ int git_config_from_file(config_fn_t fn, const char *filename)\n \treturn ret;\n }\n \n+static int config_from_http(config_fn_t fn, char *dest)\n+{\n+\tchar config_temp[50];\n+\tif (git_http_fetch_config(dest, config_temp, sizeof(config_temp)))\n+\t\treturn 1;\n+\tgit_config_from_file(fn, config_temp);\n+\tunlink(config_temp);\n+\treturn 0;\n+}\n+\n int git_config_from_remote(config_fn_t fn, char *dest)\n {\n \tint ret;\n@@ -414,7 +425,10 @@ int git_config_from_remote(config_fn_t fn, char *dest)\n \tstatic char var[MAXNAME];\n \tstatic char value[1024];\n \n-\tpid = git_connect(fd, dest, dumpconfig);\n+\tif (!prefixcmp(dest, \"http://\"))\n+\t\treturn config_from_http(fn, dest);\n+\n+\tpid = git_connect(fd, dest, dumpconfig, 0);\n \tif (pid < 0)\n \t\treturn 1;\n \tret = 0;\ndiff --git a/http.c b/http.c\nindex ae27e0c..c8237cb 100644\n--- a/http.c\n+++ b/http.c\n@@ -25,6 +25,8 @@ long curl_low_speed_limit = -1;\n long curl_low_speed_time = -1;\n int curl_ftp_no_epsv = 0;\n \n+void (*fill_active_slots)(void) = NULL;\n+\n struct curl_slist *pragma_header;\n \n struct active_request_slot *active_queue_head = NULL;\n@@ -394,7 +396,8 @@ void step_active_slots(void)\n \t} while (curlm_result == CURLM_CALL_MULTI_PERFORM);\n \tif (num_transfers < active_requests) {\n \t\tprocess_curl_messages();\n-\t\tfill_active_slots();\n+\t\tif (fill_active_slots)\n+\t\t\tfill_active_slots();\n \t}\n }\n #endif\n@@ -458,9 +461,8 @@ void release_active_slot(struct active_request_slot *slot)\n \t\tcurl_easy_cleanup(slot->curl);\n \t\tslot->curl = NULL;\n \t}\n-#ifdef USE_CURL_MULTI\n-\tfill_active_slots();\n-#endif\n+\tif (fill_active_slots)\n+\t\tfill_active_slots();\n }\n \n static void finish_active_slot(struct active_request_slot *slot)\ndiff --git a/http.h b/http.h\nindex 7a41cde..7f29ff8 100644\n--- a/http.h\n+++ b/http.h\n@@ -68,8 +68,8 @@ extern void run_active_slot(struct active_request_slot *slot);\n extern void finish_all_active_slots(void);\n extern void release_active_slot(struct active_request_slot *slot);\n \n-#ifdef USE_CURL_MULTI\n extern void (*fill_active_slots)(void);\n+#ifdef USE_CURL_MULTI\n extern void step_active_slots(void);\n #endif\n \ndiff --git a/http_config.h b/http_config.h\nnew file mode 100644\nindex 0000000..25f5c19\n--- /dev/null\n+++ b/http_config.h\n@@ -0,0 +1 @@\n+int git_http_fetch_config(const char *repo, char *config_file, int len);\ndiff --git a/http_config_curl.c b/http_config_curl.c\nnew file mode 100644\nindex 0000000..88317cf\n--- /dev/null\n+++ b/http_config_curl.c\n@@ -0,0 +1,52 @@\n+#include \"http_config.h\"\n+#include \"http.h\"\n+\n+int git_http_fetch_config(const char *repo, char *config, int config_len)\n+{\n+\tchar url[PATH_MAX];\n+\tint len = strlen(repo);\n+\n+\tint fd;\n+\tFILE *configfile;\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\n+\tstrcpy(url, repo);\n+\twhile (len > 0 && url[len-1] == '/')\n+\t\t--len;\n+\tsnprintf(url+len, sizeof(url)-len, \"/config\");\n+\n+\tfd = git_mkstemp(config, config_len, \".config_XXXXXX\");\n+\tif (fd >= 0)\n+\t\tconfigfile = fdopen(fd, \"w\");\n+\tif (fd < 0 || !configfile)\n+\t\treturn error(\"Unable to open local file %s for config\",\n+\t\t\t     config);\n+\n+\thttp_init();\n+\n+\tslot = get_active_slot();\n+\tslot->results = &results;\n+\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, configfile);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tslot->local = configfile;\n+\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result != CURLE_OK) {\n+\t\t\tfclose(configfile);\n+\t\t\twarning(\"Unable to get config %s\\n%s\", url,\n+\t\t\t\t curl_errorstr);\n+\t\t}\n+\t} else {\n+\t\tfclose(configfile);\n+\t\treturn error(\"Unable to start request\");\n+\t}\n+\n+\thttp_cleanup();\n+\n+\tfclose(configfile);\n+\n+\treturn 0;\n+}\ndiff --git a/http_config_none.c b/http_config_none.c\nnew file mode 100644\nindex 0000000..860ae84\n--- /dev/null\n+++ b/http_config_none.c\n@@ -0,0 +1,6 @@\n+#include \"http_config.h\"\n+\n+int git_http_fetch_config(const char *repo, char *config_file, int len)\n+{\n+\treturn error(\"Reading http config files not supported\");\n+}\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42523","messageId":"11795163061911-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 05/16] unpack-trees.c: verify_uptodate: remove dead code","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:54Z","receivedAt":"2007-05-18T19:24:54Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis code was killed by commit fcc387db9bc453dc7e07a262873481af2ee9e5c8.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n unpack-trees.c |    4 ----\n 1 files changed, 0 insertions(+), 4 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 906ce69..cac2411 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -414,10 +414,6 @@ static void verify_uptodate(struct cache_entry *ce,\n \t\t\treturn;\n \t\terrno = 0;\n \t}\n-\tif (o->reset) {\n-\t\tce->ce_flags |= htons(CE_UPDATE);\n-\t\treturn;\n-\t}\n \tif (errno == ENOENT)\n \t\treturn;\n \tdie(\"Entry '%s' not uptodate. Cannot merge.\", ce->name);\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42522","messageId":"11795163061763-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 06/16] unpack-trees.c: pass cache_entry * to verify_absent rather than just the name","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:55Z","receivedAt":"2007-05-18T19:24:55Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nWe will need the full cache_entry later to figure out if we are dealing\nwith a submodule.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n unpack-trees.c |   32 ++++++++++++++++----------------\n 1 files changed, 16 insertions(+), 16 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex cac2411..3dac150 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -487,7 +487,7 @@ static int verify_clean_subdirectory(const char *path, const char *action,\n  * We do not want to remove or overwrite a working tree file that\n  * is not tracked, unless it is ignored.\n  */\n-static void verify_absent(const char *path, const char *action,\n+static void verify_absent(struct cache_entry *ce, const char *action,\n \t\tstruct unpack_trees_options *o)\n {\n \tstruct stat st;\n@@ -495,12 +495,12 @@ static void verify_absent(const char *path, const char *action,\n \tif (o->index_only || o->reset || !o->update)\n \t\treturn;\n \n-\tif (!lstat(path, &st)) {\n+\tif (!lstat(ce->name, &st)) {\n \t\tint cnt;\n \n-\t\tif (o->dir && excluded(o->dir, path))\n+\t\tif (o->dir && excluded(o->dir, ce->name))\n \t\t\t/*\n-\t\t\t * path is explicitly excluded, so it is Ok to\n+\t\t\t * ce->name is explicitly excluded, so it is Ok to\n \t\t\t * overwrite it.\n \t\t\t */\n \t\t\treturn;\n@@ -512,7 +512,7 @@ static void verify_absent(const char *path, const char *action,\n \t\t\t * files that are in \"foo/\" we would lose\n \t\t\t * it.\n \t\t\t */\n-\t\t\tcnt = verify_clean_subdirectory(path, action, o);\n+\t\t\tcnt = verify_clean_subdirectory(ce->name, action, o);\n \n \t\t\t/*\n \t\t\t * If this removed entries from the index,\n@@ -540,7 +540,7 @@ static void verify_absent(const char *path, const char *action,\n \t\t * delete this path, which is in a subdirectory that\n \t\t * is being replaced with a blob.\n \t\t */\n-\t\tcnt = cache_name_pos(path, strlen(path));\n+\t\tcnt = cache_name_pos(ce->name, strlen(ce->name));\n \t\tif (0 <= cnt) {\n \t\t\tstruct cache_entry *ce = active_cache[cnt];\n \t\t\tif (!ce_stage(ce) && !ce->ce_mode)\n@@ -548,7 +548,7 @@ static void verify_absent(const char *path, const char *action,\n \t\t}\n \n \t\tdie(\"Untracked working tree file '%s' \"\n-\t\t    \"would be %s by merge.\", path, action);\n+\t\t    \"would be %s by merge.\", ce->name, action);\n \t}\n }\n \n@@ -572,7 +572,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,\n \t\t}\n \t}\n \telse {\n-\t\tverify_absent(merge->name, \"overwritten\", o);\n+\t\tverify_absent(merge, \"overwritten\", o);\n \t\tinvalidate_ce_path(merge);\n \t}\n \n@@ -587,7 +587,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,\n \tif (old)\n \t\tverify_uptodate(old, o);\n \telse\n-\t\tverify_absent(ce->name, \"removed\", o);\n+\t\tverify_absent(ce, \"removed\", o);\n \tce->ce_mode = 0;\n \tadd_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);\n \tinvalidate_ce_path(ce);\n@@ -704,18 +704,18 @@ int threeway_merge(struct cache_entry **stages,\n \tif (o->aggressive) {\n \t\tint head_deleted = !head && !df_conflict_head;\n \t\tint remote_deleted = !remote && !df_conflict_remote;\n-\t\tconst char *path = NULL;\n+\t\tstruct cache_entry *ce = NULL;\n \n \t\tif (index)\n-\t\t\tpath = index->name;\n+\t\t\tce = index;\n \t\telse if (head)\n-\t\t\tpath = head->name;\n+\t\t\tce = head;\n \t\telse if (remote)\n-\t\t\tpath = remote->name;\n+\t\t\tce = remote;\n \t\telse {\n \t\t\tfor (i = 1; i < o->head_idx; i++) {\n \t\t\t\tif (stages[i] && stages[i] != o->df_conflict_entry) {\n-\t\t\t\t\tpath = stages[i]->name;\n+\t\t\t\t\tce = stages[i];\n \t\t\t\t\tbreak;\n \t\t\t\t}\n \t\t\t}\n@@ -730,8 +730,8 @@ int threeway_merge(struct cache_entry **stages,\n \t\t    (remote_deleted && head && head_match)) {\n \t\t\tif (index)\n \t\t\t\treturn deleted_entry(index, index, o);\n-\t\t\telse if (path && !head_deleted)\n-\t\t\t\tverify_absent(path, \"removed\", o);\n+\t\t\telse if (ce && !head_deleted)\n+\t\t\t\tverify_absent(ce, \"removed\", o);\n \t\t\treturn 0;\n \t\t}\n \t\t/*\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42517","messageId":"11795163061588-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 07/16] git-read-tree: take --submodules option","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:56Z","receivedAt":"2007-05-18T19:24:56Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis option currently has no effect.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n builtin-read-tree.c |   25 ++++++++++++++++++++++---\n cache.h             |    3 ++-\n unpack-trees.c      |    1 +\n unpack-trees.h      |    1 +\n 4 files changed, 26 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin-read-tree.c b/builtin-read-tree.c\nindex 316fb0f..929dd95 100644\n--- a/builtin-read-tree.c\n+++ b/builtin-read-tree.c\n@@ -87,14 +87,23 @@ static void prime_cache_tree(void)\n static const char read_tree_usage[] = \"git-read-tree (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])\";\n \n static struct lock_file lock_file;\n+static struct unpack_trees_options opts;\n+\n+static int git_read_tree_config(const char *var, const char *value)\n+{\n+\tif (!strcmp(var, \"core.submodules\")) {\n+\t\topts.submodules = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n+\treturn git_default_config(var, value);\n+}\n \n int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n {\n \tint i, newfd, stage = 0;\n \tunsigned char sha1[20];\n-\tstruct unpack_trees_options opts;\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = -1;\n \n \tsetup_git_directory();\n@@ -102,7 +111,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \n \tnewfd = hold_locked_index(&lock_file, 1);\n \n-\tgit_config(git_default_config);\n+\tgit_config(git_read_tree_config);\n \n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n@@ -172,6 +181,16 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \t\t\tcontinue;\n \t\t}\n \n+\t\tif (!strcmp(arg, \"--no-submodules\")) {\n+\t\t\topts.submodules = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (!strcmp(arg, \"--submodules\")) {\n+\t\t\topts.submodules = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\t/* \"-m\" stands for \"merge\", meaning we start in stage 1 */\n \t\tif (!strcmp(arg, \"-m\")) {\n \t\t\tif (stage || opts.merge || opts.prefix)\ndiff --git a/cache.h b/cache.h\nindex 6acc330..42a275e 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -406,7 +406,8 @@ struct checkout {\n \tunsigned force:1,\n \t\t quiet:1,\n \t\t not_new:1,\n-\t\t refresh_cache:1;\n+\t\t refresh_cache:1,\n+\t\t submodules:1;\n };\n \n extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 3dac150..5fa637a 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -352,6 +352,7 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)\n \tstate.force = 1;\n \tstate.quiet = 1;\n \tstate.refresh_cache = 1;\n+\tstate.submodules = o->submodules;\n \n \to->merge_size = len;\n \ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex fee7da4..21005d9 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -15,6 +15,7 @@ struct unpack_trees_options {\n \tint trivial_merges_only;\n \tint verbose_update;\n \tint aggressive;\n+\tint submodules;\n \tconst char *prefix;\n \tint pos;\n \tstruct dir_struct *dir;\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42519","messageId":"11795163062080-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 08/16] unpack-trees.c: assume submodules are clean","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:57Z","receivedAt":"2007-05-18T19:24:57Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nIf the submodules are not clean, then we will get an error\nwhen we actally do the checkout.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n unpack-trees.c |   43 ++++++++++++++++++++++++++++++++++---------\n 1 files changed, 34 insertions(+), 9 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 5fa637a..e979bc5 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -5,6 +5,7 @@\n #include \"cache-tree.h\"\n #include \"unpack-trees.h\"\n #include \"progress.h\"\n+#include \"refs.h\"\n \n #define DBRT_DEBUG 1\n \n@@ -426,11 +427,24 @@ static void invalidate_ce_path(struct cache_entry *ce)\n \t\tcache_tree_invalidate_path(active_cache_tree, ce->name);\n }\n \n-static int verify_clean_subdirectory(const char *path, const char *action,\n+/* Check that checking out ce->sha1 in subdir ce->name is not\n+ * going to overwrite any working files.\n+ *\n+ * FIXME: implement this function, so we can detect problems\n+ *        early, rather than waiting until we actually try to checkout\n+ *        the submodules.\n+ */\n+static int verify_clean_submodule(struct cache_entry *ce, const char *action,\n+\t\t\t\t      struct unpack_trees_options *o)\n+{\n+\treturn 0;\n+}\n+\n+static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,\n \t\t\t\t      struct unpack_trees_options *o)\n {\n \t/*\n-\t * we are about to extract \"path\"; we would not want to lose\n+\t * we are about to extract \"ce->name\"; we would not want to lose\n \t * anything in the existing directory there.\n \t */\n \tint namelen;\n@@ -438,13 +452,24 @@ static int verify_clean_subdirectory(const char *path, const char *action,\n \tstruct dir_struct d;\n \tchar *pathbuf;\n \tint cnt = 0;\n+\tunsigned char sha1[20];\n+\n+\tif (S_ISDIRLNK(ntohl(ce->ce_mode)) &&\n+\t    resolve_gitlink_ref(ce->name, \"HEAD\", sha1) == 0) {\n+\t\t/* If we are not going to update the submodule, then\n+\t\t * we don't care.\n+\t\t */\n+\t\tif (!o->submodules || !hashcmp(sha1, ce->sha1))\n+\t\t\treturn 0;\n+\t\tverify_clean_submodule(ce, action, o);\n+\t}\n \n \t/*\n \t * First let's make sure we do not have a local modification\n \t * in that directory.\n \t */\n-\tnamelen = strlen(path);\n-\tpos = cache_name_pos(path, namelen);\n+\tnamelen = strlen(ce->name);\n+\tpos = cache_name_pos(ce->name, namelen);\n \tif (0 <= pos)\n \t\treturn cnt; /* we have it as nondirectory */\n \tpos = -pos - 1;\n@@ -452,7 +477,7 @@ static int verify_clean_subdirectory(const char *path, const char *action,\n \t\tstruct cache_entry *ce = active_cache[i];\n \t\tint len = ce_namelen(ce);\n \t\tif (len < namelen ||\n-\t\t    strncmp(path, ce->name, namelen) ||\n+\t\t    strncmp(ce->name, ce->name, namelen) ||\n \t\t    ce->name[namelen] != '/')\n \t\t\tbreak;\n \t\t/*\n@@ -470,16 +495,16 @@ static int verify_clean_subdirectory(const char *path, const char *action,\n \t * present file that is not ignored.\n \t */\n \tpathbuf = xmalloc(namelen + 2);\n-\tmemcpy(pathbuf, path, namelen);\n+\tmemcpy(pathbuf, ce->name, namelen);\n \tstrcpy(pathbuf+namelen, \"/\");\n \n \tmemset(&d, 0, sizeof(d));\n \tif (o->dir)\n \t\td.exclude_per_dir = o->dir->exclude_per_dir;\n-\ti = read_directory(&d, path, pathbuf, namelen+1, NULL);\n+\ti = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);\n \tif (i)\n \t\tdie(\"Updating '%s' would lose untracked files in it\",\n-\t\t    path);\n+\t\t    ce->name);\n \tfree(pathbuf);\n \treturn cnt;\n }\n@@ -513,7 +538,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,\n \t\t\t * files that are in \"foo/\" we would lose\n \t\t\t * it.\n \t\t\t */\n-\t\t\tcnt = verify_clean_subdirectory(ce->name, action, o);\n+\t\t\tcnt = verify_clean_subdirectory(ce, action, o);\n \n \t\t\t/*\n \t\t\t * If this removed entries from the index,\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42518","messageId":"1179516307425-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 09/16] entry.c: optionally checkout submodules","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:58Z","receivedAt":"2007-05-18T19:24:58Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n entry.c |   42 ++++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 40 insertions(+), 2 deletions(-)\n\ndiff --git a/entry.c b/entry.c\nindex 82bf725..96a4a60 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"blob.h\"\n+#include \"run-command.h\"\n \n static void create_directories(const char *path, const struct checkout *state)\n {\n@@ -163,6 +164,44 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout\n \treturn 0;\n }\n \n+static int checkout_submodule(const char *path, struct cache_entry *ce, const struct checkout *state)\n+{\n+\tstatic char cwd[PATH_MAX];\n+\tconst char *gitdirenv;\n+\tconst char *args[10];\n+\tint argc;\n+\tint err;\n+\n+\tif (!state->submodules)\n+\t\treturn 0;\n+\n+\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n+\t\tdie(\"Unable to read current working directory\");\n+\n+\tif (chdir(path))\n+\t\tdie(\"Cannot move to '%s'\", path);\n+\n+\targc = 0;\n+\targs[argc++] = \"checkout\";\n+\tif (state->force)\n+\t    args[argc++] = \"-f\";\n+\targs[argc++] = sha1_to_hex(ce->sha1);\n+\targs[argc] = NULL;\n+\n+\tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n+\tunsetenv(GIT_DIR_ENVIRONMENT);\n+\terr = run_command_v_opt(args, RUN_GIT_CMD);\n+\tsetenv(GIT_DIR_ENVIRONMENT, gitdirenv, 1);\n+\n+\tif (chdir(cwd))\n+\t\tdie(\"Cannot come back to cwd\");\n+\n+\tif (err)\n+\t\treturn error(\"failed to run git-checkout in submodule '%s'\", path);\n+\n+\treturn 0;\n+}\n+\n int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath)\n {\n \tstatic char path[PATH_MAX + 1];\n@@ -193,9 +232,8 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t\n \t\t */\n \t\tunlink(path);\n \t\tif (S_ISDIR(st.st_mode)) {\n-\t\t\t/* If it is a gitlink, leave it alone! */\n \t\t\tif (S_ISDIRLNK(ntohl(ce->ce_mode)))\n-\t\t\t\treturn 0;\n+\t\t\t\treturn checkout_submodule(path, ce, state);\n \t\t\tif (!state->force)\n \t\t\t\treturn error(\"%s is a directory\", path);\n \t\t\tremove_subtree(path);\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42514","messageId":"11795163073176-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 10/16] git-checkout: pass --submodules option to git-read-tree","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:24:59Z","receivedAt":"2007-05-18T19:24:59Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n git-checkout.sh |   20 +++++++++++++++-----\n 1 files changed, 15 insertions(+), 5 deletions(-)\n\ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex 6b6facf..cbb1f00 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'\n+USAGE='[-q] [-f] [--submodules] [--no-submodules] [-b <new_branch>] [-m] [<branch>] [<paths>...]'\n SUBDIRECTORY_OK=Sometimes\n . git-sh-setup\n require_work_tree\n@@ -16,6 +16,7 @@ track=\n newbranch=\n newbranch_log=\n merge=\n+submodules=\n quiet=\n v=-v\n LF='\n@@ -46,6 +47,15 @@ while [ \"$#\" != \"0\" ]; do\n \t-m)\n \t\tmerge=1\n \t\t;;\n+\t*,--su|*,--sub|*,--subm|*,--submo|*,--submod|*,--submodu|*,--submodul|\\\n+\t*,--submodule|*,--submodules)\n+\t\tsubmodules=\"--submodules\"\n+\t\t;;\n+\t*,--no-su|*,--no-sub|*,--no-subm|*,--no-submo|*,--no-submod|\\\n+\t*,--no-submodu|*,--no-submodul|\\\n+\t*,--no-submodule|*,--no-submodules)\n+\t\tsubmodules=\"--no-submodules\"\n+\t\t;;\n \t\"-q\")\n \t\tquiet=1\n \t\tv=\n@@ -199,10 +209,10 @@ fi\n \n if [ \"$force\" ]\n then\n-    git-read-tree $v --reset -u $new\n+    git-read-tree $v $submodules --reset -u $new\n else\n     git-update-index --refresh >/dev/null\n-    merge_error=$(git-read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (\n+    merge_error=$(git-read-tree $submodules -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (\n \tcase \"$merge\" in\n \t'')\n \t\techo >&2 \"$merge_error\"\n@@ -212,7 +222,7 @@ else\n \t# Match the index to the working tree, and do a three-way.\n     \tgit diff-files --name-only | git update-index --remove --stdin &&\n \twork=`git write-tree` &&\n-\tgit read-tree $v --reset -u $new || exit\n+\tgit read-tree $v $submodules --reset -u $new || exit\n \n \teval GITHEAD_$new='${new_name:-${branch:-$new}}' &&\n \teval GITHEAD_$work=local &&\n@@ -223,7 +233,7 @@ else\n \t# this is not a real merge before committing, but just carrying\n \t# the working tree changes along.\n \tunmerged=`git ls-files -u`\n-\tgit read-tree $v --reset $new\n+\tgit read-tree $v $submodules --reset $new\n \tcase \"$unmerged\" in\n \t'')\t;;\n \t*)\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42524","messageId":"117951630747-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 11/16] git-fetch: skip empty arguments","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:00Z","receivedAt":"2007-05-18T19:25:00Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nThis makes it easier for scripts to call git-fetch with options\nthat may or may not be set.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n git-fetch.sh |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex 0e05cf1..dbeca14 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -76,6 +76,8 @@ do\n \t-*)\n \t\tusage\n \t\t;;\n+\t'')\n+\t\t;;\n \t*)\n \t\tbreak\n \t\t;;\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42515","messageId":"11795163072266-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 12/16] builtin-fetch--tool: extend \"native-store\" for use in cloning","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:01Z","receivedAt":"2007-05-18T19:25:01Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n builtin-fetch--tool.c |   48 ++++++++++++++++++++++++++++++++++++++++++++----\n 1 files changed, 44 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c\nindex ed4d5de..3441a4a 100644\n--- a/builtin-fetch--tool.c\n+++ b/builtin-fetch--tool.c\n@@ -207,6 +207,32 @@ static void remove_keep_on_signal(int signo)\n \traise(signo);\n }\n \n+static char *construct_local_name(const char *remote_ref, const char *remote_nick,\n+\t\t\t\t  int use_separate_remote)\n+{\n+\tstatic char local_ref[PATH_MAX];\n+\tint len = strlen(remote_ref);\n+\n+\tif (len >= 3 && !memcmp(remote_ref+len-3, \"^{}\", 3))\n+\t\treturn NULL;\n+\tif (!strcmp(remote_ref, \"HEAD\"))\n+\t\treturn \"REMOTE_HEAD\";\n+\tif (!prefixcmp(remote_ref, \"refs/heads/\")) {\n+\t\tif (snprintf(local_ref, sizeof(local_ref), \"refs/%s%s/%s\",\n+\t\t\t    use_separate_remote ? \"remotes/\" : \"heads\",\n+\t\t\t    use_separate_remote ? remote_nick : \"\",\n+\t\t\t    remote_ref+11) > sizeof(local_ref))\n+\t\t\tdie(\"Local branchname too long\");\n+\t} else if (!prefixcmp(remote_ref, \"refs/tags/\")) {\n+\t\tif (snprintf(local_ref, sizeof(local_ref), \"refs/tags/%s\",\n+\t\t\t    remote_ref+10) > sizeof(local_ref))\n+\t\t\tdie(\"Local branchname too long\");\n+\t} else\n+\t\treturn NULL;\n+\n+\treturn local_ref;\n+}\n+\n static char *find_local_name(const char *remote_name, const char *refs,\n \t\t\t     int *force_p, int *not_for_merge_p)\n {\n@@ -261,7 +287,8 @@ static int fetch_native_store(FILE *fp,\n \t\t\t      const char *remote,\n \t\t\t      const char *remote_nick,\n \t\t\t      const char *refs,\n-\t\t\t      int verbose, int force)\n+\t\t\t      int verbose, int force,\n+\t\t\t      int all, int use_separate_remote)\n {\n \tchar buffer[1024];\n \tint err = 0;\n@@ -294,8 +321,12 @@ static int fetch_native_store(FILE *fp,\n \t\t\tcontinue;\n \t\t}\n \n-\t\tlocal_name = find_local_name(cp, refs,\n-\t\t\t\t\t     &single_force, &not_for_merge);\n+\t\tif (all)\n+\t\t\tlocal_name = construct_local_name(cp, remote_nick,\n+\t\t\t\t\t\t\t  use_separate_remote);\n+\t\telse\n+\t\t\tlocal_name = find_local_name(cp, refs,\n+\t\t\t\t\t\t     &single_force, &not_for_merge);\n \t\tif (!local_name)\n \t\t\tcontinue;\n \t\terr |= append_fetch_head(fp,\n@@ -514,6 +545,8 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)\n \tint verbose = 0;\n \tint force = 0;\n \tint sopt = 0;\n+\tint all = 0;\n+\tint use_separate_remote = 1;\n \n \twhile (1 < argc) {\n \t\tconst char *arg = argv[1];\n@@ -523,6 +556,12 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)\n \t\t\tforce = 1;\n \t\telse if (!strcmp(\"-s\", arg))\n \t\t\tsopt = 1;\n+\t\telse if (!strcmp(\"--all\", arg))\n+\t\t\tall = 1;\n+\t\telse if (!strcmp(\"--use-separate-remote\", arg))\n+\t\t\tuse_separate_remote = 1;\n+\t\telse if (!strcmp(\"--no-separate-remote\", arg))\n+\t\t\tuse_separate_remote = 0;\n \t\telse\n \t\t\tbreak;\n \t\targc--;\n@@ -554,7 +593,8 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)\n \t\t\treturn error(\"fetch-native-store takes 3 args\");\n \t\tfp = fopen(git_path(\"FETCH_HEAD\"), \"a\");\n \t\tresult = fetch_native_store(fp, argv[2], argv[3], argv[4],\n-\t\t\t\t\t    verbose, force);\n+\t\t\t\t\t    verbose, force, all,\n+\t\t\t\t\t    use_separate_remote);\n \t\tfclose(fp);\n \t\treturn result;\n \t}\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42521","messageId":"11795163071819-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 13/16] git-clone: rely on git-fetch for fetching for most protocols","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:02Z","receivedAt":"2007-05-18T19:25:02Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n git-clone.sh |   20 ++++++++++++--------\n git-fetch.sh |   28 ++++++++++++++++++++++------\n 2 files changed, 34 insertions(+), 14 deletions(-)\n\ndiff --git a/git-clone.sh b/git-clone.sh\nindex fdd354f..44127c5 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -159,6 +159,11 @@ then\n \tno_checkout=yes\n \tuse_separate_remote=\n fi\n+if test t = \"$use_separate_remote\"; then\n+\tseparate_remote_flag=\"--use-separate-remote\"\n+else\n+\tseparate_remote_flag=\"--no-separate-remote\"\n+fi\n \n if test -z \"$origin\"\n then\n@@ -219,6 +224,10 @@ then\n \tfi\n fi\n \n+# Write out $origin URL\n+GIT_CONFIG=\"$GIT_DIR/config\"\n+git-config remote.\"$origin\".url \"$repo\" || exit\n+\n rm -f \"$GIT_DIR/CLONE_HEAD\"\n \n # We do local magic only when the user tells us to.\n@@ -299,11 +308,9 @@ yes,yes)\n \t\tfi\n \t\t;;\n \t*)\n-\t\tcase \"$upload_pack\" in\n-\t\t'') git-fetch-pack --all -k $quiet $depth $no_progress \"$repo\";;\n-\t\t*) git-fetch-pack --all -k $quiet \"$upload_pack\" $depth $no_progress \"$repo\" ;;\n-\t\tesac >\"$GIT_DIR/CLONE_HEAD\" ||\n-\t\t\tdie \"fetch-pack from '$repo' failed.\"\n+\t\tgit-fetch --all -k $quiet \"$upload_pack\" $depth \\\n+\t\t\t$separate_remote_flag \"$origin\" ||\n+\t\t\tdie \"fetch from '$repo' failed.\"\n \t\t;;\n \tesac\n \t;;\n@@ -387,9 +394,6 @@ then\n \t\torigin_track=\"$remote_top/$head_points_at\" &&\n \t\tgit-update-ref HEAD \"$head_sha1\" &&\n \n-\t\t# Upstream URL\n-\t\tgit-config remote.\"$origin\".url \"$repo\" &&\n-\n \t\t# Set up the mappings to track the remote branches.\n \t\tgit-config remote.\"$origin\".fetch \\\n \t\t\t\"+refs/heads/*:$remote_top/*\" '^$' &&\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex dbeca14..e169848 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -15,6 +15,7 @@ LF='\n '\n IFS=\"$LF\"\n \n+all=\n no_tags=\n tags=\n append=\n@@ -25,6 +26,7 @@ exec=\n keep=\n shallow_depth=\n no_progress=\n+use_separate_remote=\n test -t 1 || no_progress=--no-progress\n quiet=\n while case \"$#\" in 0) break ;; esac\n@@ -33,6 +35,9 @@ do\n \t-a|--a|--ap|--app|--appe|--appen|--append)\n \t\tappend=t\n \t\t;;\n+\t--al|--all)\n+\t\tall=--all\n+\t\t;;\n \t--upl|--uplo|--uploa|--upload|--upload-|--upload-p|\\\n \t--upload-pa|--upload-pac|--upload-pack)\n \t\tshift\n@@ -63,6 +68,12 @@ do\n \t-v|--verbose)\n \t\tverbose=Yes\n \t\t;;\n+\t--use-separate-remote)\n+\t\tuse_separate_remote=\"--use-separate-remote\"\n+\t\t;;\n+\t--no-separate-remote)\n+\t\tuse_separate_remote=\"--no-separate-remote\"\n+\t\t;;\n \t-k|--k|--ke|--kee|--keep)\n \t\tkeep='-k -k'\n \t\t;;\n@@ -143,7 +154,9 @@ esac\n # branches file, and just fetch those and refspecs explicitly given.\n # Otherwise we do what we always did.\n \n-reflist=$(get_remote_refs_for_fetch \"$@\")\n+if test -z \"$all\"; then\n+\treflist=$(get_remote_refs_for_fetch \"$@\")\n+fi\n if test \"$tags\"\n then\n \ttaglist=`IFS='\t' &&\n@@ -165,8 +178,10 @@ fi\n \n fetch_all_at_once () {\n \n-  eval=$(echo \"$1\" | git-fetch--tool parse-reflist \"-\")\n-  eval \"$eval\"\n+    if test -z \"$all\"; then\n+\teval=$(echo \"$1\" | git-fetch--tool parse-reflist \"-\")\n+\teval \"$eval\"\n+    fi\n \n     ( : subshell because we muck with IFS\n       IFS=\" \t$LF\"\n@@ -179,7 +194,8 @@ fetch_all_at_once () {\n \t    git-bundle unbundle \"$remote\" $rref ||\n \t    echo failed \"$remote\"\n \telse\n-\t\tif\ttest -d \"$remote\" &&\n+\t\tif\ttest -z \"$all\" &&\n+\t\t\ttest -d \"$remote\" &&\n \n \t\t\t# The remote might be our alternate.  With\n \t\t\t# this optimization we will bypass fetch-pack\n@@ -203,7 +219,7 @@ fetch_all_at_once () {\n \t\t\techo \"$ls_remote_result\" | \\\n \t\t\t\tgit-fetch--tool pick-rref \"$rref\" \"-\"\n \t\telse\n-\t\t\tgit-fetch-pack --thin $exec $keep $shallow_depth \\\n+\t\t\tgit-fetch-pack --thin $all $exec $keep $shallow_depth \\\n \t\t\t\t$quiet $no_progress \"$remote\" $rref ||\n \t\t\techo failed \"$remote\"\n \t\tfi\n@@ -214,7 +230,7 @@ fetch_all_at_once () {\n \ttest -n \"$verbose\" && flags=\"$flags -v\"\n \ttest -n \"$force\" && flags=\"$flags -f\"\n \tGIT_REFLOG_ACTION=\"$GIT_REFLOG_ACTION\" \\\n-\t\tgit-fetch--tool $flags native-store \\\n+\t\tgit-fetch--tool $flags $all $use_separate_remote native-store \\\n \t\t\t\"$remote\" \"$remote_nick\" \"$refs\"\n       )\n     ) || exit\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42526","messageId":"11795163074010-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 14/16] git-clone: rely on git-fetch for non-bare fetching over http","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:03Z","receivedAt":"2007-05-18T19:25:03Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n git-clone.sh |    6 +++---\n git-fetch.sh |   20 ++++++++++++++++++++\n 2 files changed, 23 insertions(+), 3 deletions(-)\n\ndiff --git a/git-clone.sh b/git-clone.sh\nindex 44127c5..44387f4 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -262,8 +262,8 @@ yes,yes)\n \tgit-ls-remote \"$repo\" >\"$GIT_DIR/CLONE_HEAD\" || exit 1\n \t;;\n *)\n-\tcase \"$repo\" in\n-\trsync://*)\n+\tcase \"$bare,$repo\" in\n+\t*,rsync://*)\n \t\tcase \"$depth\" in\n \t\t\"\") ;;\n \t\t*) die \"shallow over rsync not supported\" ;;\n@@ -295,7 +295,7 @@ yes,yes)\n \t\tfi\n \t\tgit-ls-remote \"$repo\" >\"$GIT_DIR/CLONE_HEAD\" || exit 1\n \t\t;;\n-\thttps://*|http://*|ftp://*)\n+\tyes,https://*|yes,http://*|yes,ftp://*)\n \t\tcase \"$depth\" in\n \t\t\"\") ;;\n \t\t*) die \"shallow over http or ftp not supported\" ;;\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex e169848..84c2523 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -237,11 +237,31 @@ fetch_all_at_once () {\n \n }\n \n+http_fetch () {\n+\tif [ -n \"$GIT_SSL_NO_VERIFY\" ]; then\n+\t\tcurl_extra_args=\"-k\"\n+\tfi\n+\tif [ -n \"$GIT_CURL_FTP_NO_EPSV\" -o \\\n+\t\t\"`git-config --bool http.noEPSV`\" = true ]; then\n+\t\tcurl_extra_args=\"${curl_extra_args} --disable-epsv\"\n+\tfi\n+\n+\t# $1 = Remote, $2 = Local\n+\tcurl -nsfL $curl_extra_args \"$1\" >\"$2\"\n+}\n+\n fetch_per_ref () {\n   reflist=\"$1\"\n   refs=\n   rref=\n \n+    if test -n \"$all\"; then\n+\treflist=$(canon_refs_list_for_fetch -d \"$remote_nick\" \\\n+\t\t\t\"+refs/heads/*:refs/remotes/$remote_nick/*\")\n+\thttp_fetch \"$remote/HEAD\" \"$GIT_DIR/REMOTE_HEAD\" ||\n+\trm -f \"$GIT_DIR/REMOTE_HEAD\"\n+    fi\n+\n   for ref in $reflist\n   do\n       refs=\"$refs$LF$ref\"\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42527","messageId":"11795163072872-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 15/16] git-read-tree: treat null commit as empty tree","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:04Z","receivedAt":"2007-05-18T19:25:04Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\n---\n builtin-read-tree.c |    9 ++++++---\n unpack-trees.c      |    3 +++\n 2 files changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-read-tree.c b/builtin-read-tree.c\nindex 929dd95..b9fcff7 100644\n--- a/builtin-read-tree.c\n+++ b/builtin-read-tree.c\n@@ -17,9 +17,12 @@ static struct object_list *trees;\n \n static int list_tree(unsigned char *sha1)\n {\n-\tstruct tree *tree = parse_tree_indirect(sha1);\n-\tif (!tree)\n-\t\treturn -1;\n+\tstruct tree *tree = NULL;\n+\tif (!is_null_sha1(sha1)) {\n+\t\ttree = parse_tree_indirect(sha1);\n+\t\tif (!tree)\n+\t\t\treturn -1;\n+\t}\n \tobject_list_append(&tree->object, &trees);\n \treturn 0;\n }\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex e979bc5..30c2a49 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -26,6 +26,9 @@ static struct tree_entry_list *create_tree_entry_list(struct tree *tree)\n \tstruct tree_entry_list *ret = NULL;\n \tstruct tree_entry_list **list_p = &ret;\n \n+\tif (!tree)\n+\t\treturn ret;\n+\n \tif (!tree->object.parsed)\n \t\tparse_tree(tree);\n \n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42525","messageId":"11795163073175-git-send-email-skimo@liacs.nl","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"[PATCH 16/16] git-clone: add --submodules for cloning submodules","fromName":"","fromEmail":"skimo@liacs.nl","sentAt":"2007-05-18T19:25:05Z","receivedAt":"2007-05-18T19:25:05Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"From: Sven Verdoolaege <skimo@kotnet.org>\n\nWhen the --submodules option is specified, git-clone will search\nfor submodule.<submodule>.url options in the remote configuration\nand clone each submodule using the first url that it can use from\nthe local site.\n\nSigned-off-by: Sven Verdoolaege <skimo@kotnet.org>\n---\n Documentation/config.txt    |    7 +++\n Documentation/git-clone.txt |    6 ++-\n git-clone.sh                |   18 +++++++-\n git-fetch.sh                |   90 +++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 117 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex ee1c35e..cee9e40 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -256,6 +256,10 @@ You probably do not need to adjust this value.\n +\n Common unit suffixes of 'k', 'm', or 'g' are supported.\n \n+core.submodules\n+\tIf true, gitlink:git-checkout[1] also checks out submodules.\n+\tFalse by default.\n+\n alias.*::\n \tCommand aliases for the gitlink:git[1] command wrapper - e.g.\n \tafter defining \"alias.last = cat-file commit HEAD\", the invocation\n@@ -606,6 +610,9 @@ showbranch.default::\n \tThe default set of branches for gitlink:git-show-branch[1].\n \tSee gitlink:git-show-branch[1].\n \n+submodule.<submodule>.url\n+\tThe URL of a submodule.  See gitlink:git-clone[1].\n+\n tar.umask::\n \tBy default, gitlink:git-tar-tree[1] sets file and directories modes\n \tto 0666 or 0777. While this is both useful and acceptable for projects\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 644bf12..565155b 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -11,7 +11,7 @@ SYNOPSIS\n [verse]\n 'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]\n \t  [-o <name>] [-u <upload-pack>] [--reference <repository>]\n-\t  [--depth <depth>] <repository> [<directory>]\n+\t  [--depth <depth>] [--submodules] <repository> [<directory>]\n \n DESCRIPTION\n -----------\n@@ -105,6 +105,10 @@ OPTIONS\n \twith a long history, and would want to send in a fixes\n \tas patches.\n \n+--submodules::\n+\tClone submodules specified in (remote) configuration parameters\n+\tsubmodule.<submodule>.url.\n+\n <repository>::\n \tThe (possibly remote) repository to clone from.  It can\n \tbe any URL git-fetch supports.\ndiff --git a/git-clone.sh b/git-clone.sh\nindex 44387f4..f5a3548 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -14,7 +14,7 @@ die() {\n }\n \n usage() {\n-\tdie \"Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]\"\n+\tdie \"Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--submodules] <repo> [<dir>]\"\n }\n \n get_repo_base() {\n@@ -88,6 +88,7 @@ origin_override=\n use_separate_remote=t\n depth=\n no_progress=\n+submodules=\n test -t 1 || no_progress=--no-progress\n while\n \tcase \"$#,$1\" in\n@@ -138,6 +139,8 @@ while\n \t*,--depth)\n \t\tshift\n \t\tdepth=\"--depth=$1\";;\n+\t*,--su|*,--sub|*,--subm|*,--submo|*,--submod|*,--submodu|*,--submodul|\\\n+\t*,--submodule|*,--submodules) submodules=\"--submodules\" ;;\n \t*,-*) usage ;;\n \t*) break ;;\n \tesac\n@@ -156,6 +159,10 @@ then\n \tthen\n \t\tdie '--bare and --origin $origin options are incompatible.'\n \tfi\n+\tif test -n \"$submodules\"\n+\tthen\n+\t\tdie '--bare and --submodules origin options are incompatible.'\n+\tfi\n \tno_checkout=yes\n \tuse_separate_remote=\n fi\n@@ -309,7 +316,7 @@ yes,yes)\n \t\t;;\n \t*)\n \t\tgit-fetch --all -k $quiet \"$upload_pack\" $depth \\\n-\t\t\t$separate_remote_flag \"$origin\" ||\n+\t\t\t$separate_remote_flag $submodules \"$origin\" ||\n \t\t\tdie \"fetch from '$repo' failed.\"\n \t\t;;\n \tesac\n@@ -405,10 +412,15 @@ then\n \t\tgit-config branch.\"$head_points_at\".merge \"refs/heads/$head_points_at\"\n \tesac\n \n+\tif test -n \"$submodules\"\n+\tthen\n+\t\tgit-config core.submodules true\n+\tfi\n+\n \tcase \"$no_checkout\" in\n \t'')\n \t\ttest \"z$quiet\" = z -a \"z$no_progress\" = z && v=-v || v=\n-\t\tgit-read-tree -m -u $v HEAD HEAD\n+\t\tgit-read-tree -m -u $v $submodules HEAD HEAD\n \tesac\n fi\n rm -f \"$GIT_DIR/CLONE_HEAD\" \"$GIT_DIR/REMOTE_HEAD\"\ndiff --git a/git-fetch.sh b/git-fetch.sh\nindex 84c2523..b7ef0c3 100755\n--- a/git-fetch.sh\n+++ b/git-fetch.sh\n@@ -15,6 +15,70 @@ LF='\n '\n IFS=\"$LF\"\n \n+local_URL() {\n+\t# tranforms a \"URL\" on the remote to a URL that works on the local machine\n+\t# $1 - remote, $2 - URL on remote\n+\techo \"$1 $2\" >&2\n+\tcase \"$1\" in\n+\thttps://*|http://*|ftp://*)\n+\t\tcase \"$2\" in\n+\t\thttps://*|http://*|ftp://*)\n+\t\t\techo $2\n+\t\tesac\n+\t\t;;\n+\tssh://*)\n+\t\tcase \"$2\" in\n+\t\thttps://*|http://*|ftp://*)\n+\t\t\techo $2\n+\t\t\t;;\n+\t\t/*)\n+\t\t\techo $(echo $1 | sed -e 's/\\(ssh:\\/\\/[^\\/]*\\)\\/.*/\\1/')$2\n+\t\tesac\n+\t\t;;\n+\t/*)\n+\t\techo $2\n+\t\t;;\n+\t*)\n+\t\tcase \"$2\" in\n+\t\thttps://*|http://*|ftp://*)\n+\t\t\techo $2\n+\t\tesac\n+\tesac\n+}\n+\n+clone_submodules () {\n+\t# $1 - remote\n+\tremote=$1\n+\t( : subshell because we muck with IFS\n+        IFS=\" \t$LF\"\n+\tcd \"$GIT_DIR/..\"\n+\tgit-config --remote=\"$remote\" --get-regexp 'submodule\\..*\\.url' | \\\n+\tsed -e 's/^submodule\\.//' -e 's/\\.url / /' |\n+\twhile read submodule URL\n+\tdo\n+\t\tprevious=$(git-config \"submodule.$submodule.url\")\n+\t\tif test -n \"$previous\"\n+\t\tthen\n+\t\t\tcontinue;\n+\t\tfi\n+\t\tURL=$(local_URL \"$remote\" \"$URL\")\n+\t\tif test -z \"$URL\"\n+\t\tthen\n+\t\t\tcontinue;\n+\t\tfi\n+\t\t# At this point, we don't know if the submodule\n+\t\t# appears in the HEAD of the supermodule, so clone it\n+\t\t# without a checkout and overwrite HEAD so that a subsequent\n+\t\t# checkout won't assume the submodule has already been\n+\t\t# checked out.\n+\t\tgit-clone --submodules -n \"$URL\" \"$submodule\"\n+\t\tz40=0000000000000000000000000000000000000000\n+\t\tGIT_DIR=\"$submodule/.git\" git-update-ref --no-deref HEAD $z40\n+\t\tgit-config \"submodule.$submodule.url\" \"$URL\"\n+\tdone\n+\t)\n+}\n+\n all=\n no_tags=\n tags=\n@@ -27,6 +91,7 @@ keep=\n shallow_depth=\n no_progress=\n use_separate_remote=\n+submodules=\n test -t 1 || no_progress=--no-progress\n quiet=\n while case \"$#\" in 0) break ;; esac\n@@ -84,6 +149,15 @@ do\n \t\tshift\n \t\tshallow_depth=\"--depth=$1\"\n \t\t;;\n+\t--su|--sub|--subm|--submo|--submod|--submodu|--submodul|\\\n+\t--submodule|--submodules)\n+\t\tsubmodules=\"yes\"\n+\t\t;;\n+\t--no-su|--no-sub|--no-subm|--no-submo|--no-submod|\\\n+\t--no-submodu|--no-submodul|\\\n+\t--no-submodule|--no-submodules)\n+\t\tsubmodules=\"no\"\n+\t\t;;\n \t-*)\n \t\tusage\n \t\t;;\n@@ -149,6 +223,18 @@ case \"$tags$no_tags\" in\n \tesac\n esac\n \n+case \"$submodules\" in\n+'')\n+\tcase \"$(git-config --bool core.submodules)\" in\n+\ttrue)\n+\t\tsubmodues=yes\n+\t\t;;\n+\t*)\n+\t\tsubmodules=no\n+\t\t;;\n+\tesac\n+esac\n+\n # If --tags (and later --heads or --all) is specified, then we are\n # not talking about defaults stored in Pull: line of remotes or\n # branches file, and just fetch those and refspecs explicitly given.\n@@ -407,3 +493,7 @@ case \"$orig_head\" in\n \tfi\n \t;;\n esac\n+\n+if test \"$submodules\" = yes; then\n+\tclone_submodules \"$remote\"\n+fi\n-- \n1.5.2.rc3.783.gc7476-dirty\n"},{"id":"42529","messageId":"20070518193453.GK942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"11795163053812-git-send-email-skimo@liacs.nl","subject":"Re: Second round of support for cloning submodules","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-18T19:34:53Z","receivedAt":"2007-05-18T19:34:53Z","isPatch":false,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"I forgot to mention that these changes go on top of next\n(v1.5.2-rc3-762-g77e153b).\n\nskimo\n"},{"id":"42534","messageId":"20070518215312.GB10475@steel.home","threadId":"8208","inReplyTo":"11795163061588-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T21:53:12Z","receivedAt":"2007-05-18T21:53:12Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"skimo@liacs.nl, Fri, May 18, 2007 21:24:56 +0200:\n> \n> This option currently has no effect.\n> \n\nCan we have this option (and corresponding support in the following\npatches, of course) first? It is enough to have subprojects working\nlocally, and people can start using them immediately: anyone can clone\nthe subprojects manually if he wishes so.\n\nCloning of subprojects is still unclear, and frankly I'm not sure it\nshould be done at all. Not even with an option which is off by\ndefault.\n"},{"id":"42536","messageId":"20070518215642.GC10475@steel.home","threadId":"8208","inReplyTo":"1179516307425-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 09/16] entry.c: optionally checkout submodules","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T21:56:42Z","receivedAt":"2007-05-18T21:56:42Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"skimo@liacs.nl, Fri, May 18, 2007 21:24:58 +0200:\n> +\tif (err)\n> +\t\treturn error(\"failed to run git-checkout in submodule '%s'\", path);\n\nWe may need an option to ignore these failures. Maybe even active by\ndefault. Imagine a superproject with _optional_ submodules, where it\nis just nice to know that some submodules weren't checked out. BTW,\ndoesn't git-checkout already prints an error?\n"},{"id":"42538","messageId":"20070518220014.GD10475@steel.home","threadId":"8208","inReplyTo":"1179516307425-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 09/16] entry.c: optionally checkout submodules","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:00:14Z","receivedAt":"2007-05-18T22:00:14Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"skimo@liacs.nl, Fri, May 18, 2007 21:24:58 +0200:\n> +\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n> +\t\tdie(\"Unable to read current working directory\");\n> +\n> +\tif (chdir(path))\n> +\t\tdie(\"Cannot move to '%s'\", path);\n> +\n\nHow about modifying run_command to chdir after fork?\n\nYou'd save the hassle of save/restoring cwd and don't mess up process'\ncontext (which is always a good idea to preserve). The code'd be\nsimplier, too.\n"},{"id":"42539","messageId":"20070518220323.GL942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"20070518215642.GC10475@steel.home","subject":"Re: [PATCH 09/16] entry.c: optionally checkout submodules","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-18T22:03:23Z","receivedAt":"2007-05-18T22:03:23Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Fri, May 18, 2007 at 11:56:42PM +0200, Alex Riesen wrote:\n> skimo@liacs.nl, Fri, May 18, 2007 21:24:58 +0200:\n> > +\tif (err)\n> > +\t\treturn error(\"failed to run git-checkout in submodule '%s'\", path);\n> \n> We may need an option to ignore these failures. Maybe even active by\n> default. Imagine a superproject with _optional_ submodules, where it\n> is just nice to know that some submodules weren't checked out. BTW,\n> doesn't git-checkout already prints an error?\n\nProbably.  You probably noticed that I haven't written any tests yet...\n\nStill, the error that git-checkout prints may not give enough of a clue\nthat something was wrong with a submodule.\n\nskimo\n"},{"id":"42540","messageId":"20070518220826.GM942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"20070518215312.GB10475@steel.home","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-18T22:08:26Z","receivedAt":"2007-05-18T22:08:26Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"I noticed there's a whole thread about subprojects that I haven't read yet,\nso this may have been addressed already ....\n\nOn Fri, May 18, 2007 at 11:53:12PM +0200, Alex Riesen wrote:\n> Can we have this option (and corresponding support in the following\n> patches, of course) first?\n\nThat's why the clone thing comes last.\n\n> It is enough to have subprojects working\n> locally, and people can start using them immediately: anyone can clone\n> the subprojects manually if he wishes so.\n\nAnyone can run git-write-tree and git-commit-tree is she wishes so...\n\n> Cloning of subprojects is still unclear, and frankly I'm not sure it\n> should be done at all. Not even with an option which is off by\n> default.\n\nThen don't use it.\n\nThe reason for not putting this in shouldn't be that someone doesn't\nthink it is useful; the reason should be that my code is crap.\n\nskimo\n"},{"id":"42543","messageId":"20070518222015.GE10475@steel.home","threadId":"8208","inReplyTo":"20070518220014.GD10475@steel.home","subject":"[PATCH] Add run_command_v_opt_cd: chdir into a directory before exec","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:20:15Z","receivedAt":"2007-05-18T22:20:15Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"It can make code simplier (no need to preserve cwd) and safer\n(no chance the cwd of the current process is accidentally forgotten).\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\nAlex Riesen, Sat, May 19, 2007 00:00:14 +0200:\n> skimo@liacs.nl, Fri, May 18, 2007 21:24:58 +0200:\n> > +\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n> > +\t\tdie(\"Unable to read current working directory\");\n> > +\n> > +\tif (chdir(path))\n> > +\t\tdie(\"Cannot move to '%s'\", path);\n> > +\n> \n> How about modifying run_command to chdir after fork?\n> \n> You'd save the hassle of save/restoring cwd and don't mess up process'\n> context (which is always a good idea to preserve). The code'd be\n> simplier, too.\n> \n\nsomething like this\n\n run-command.c |   27 ++++++++++++++++++++++-----\n run-command.h |    2 ++\n 2 files changed, 24 insertions(+), 5 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex eff523e..043b570 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -73,6 +73,9 @@ int start_command(struct child_process *cmd)\n \t\t\tclose(cmd->out);\n \t\t}\n \n+\t\tif (cmd->dir && chdir(cmd->dir))\n+\t\t\tdie(\"exec %s: cd to %s failed (%s)\", cmd->argv[0],\n+\t\t\t    cmd->dir, strerror(errno));\n \t\tif (cmd->git_cmd) {\n \t\t\texecv_git_cmd(cmd->argv);\n \t\t} else {\n@@ -133,13 +136,27 @@ int run_command(struct child_process *cmd)\n \treturn finish_command(cmd);\n }\n \n+static void prepare_run_command_v_opt(struct child_process *cmd,\n+\t\t\t\t      const char **argv, int opt)\n+{\n+\tmemset(cmd, 0, sizeof(*cmd));\n+\tcmd->argv = argv;\n+\tcmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;\n+\tcmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0;\n+\tcmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;\n+}\n+\n int run_command_v_opt(const char **argv, int opt)\n {\n \tstruct child_process cmd;\n-\tmemset(&cmd, 0, sizeof(cmd));\n-\tcmd.argv = argv;\n-\tcmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;\n-\tcmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;\n-\tcmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;\n+\tprepare_run_command_v_opt(&cmd, argv, opt);\n+\treturn run_command(&cmd);\n+}\n+\n+int run_command_v_opt_cd(const char **argv, int opt, const char *dir)\n+{\n+\tstruct child_process cmd;\n+\tprepare_run_command_v_opt(&cmd, argv, opt);\n+\tcmd.dir = dir;\n \treturn run_command(&cmd);\n }\ndiff --git a/run-command.h b/run-command.h\nindex 3680ef9..cbd7484 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -16,6 +16,7 @@ struct child_process {\n \tpid_t pid;\n \tint in;\n \tint out;\n+\tconst char *dir;\n \tunsigned close_in:1;\n \tunsigned close_out:1;\n \tunsigned no_stdin:1;\n@@ -32,5 +33,6 @@ int run_command(struct child_process *);\n #define RUN_GIT_CMD\t     2\t/*If this is to be git sub-command */\n #define RUN_COMMAND_STDOUT_TO_STDERR 4\n int run_command_v_opt(const char **argv, int opt);\n+int run_command_v_opt_cd(const char **argv, int opt, const char *dir);\n \n #endif\n-- \n1.5.2.rc3.83.gbbb0\n"},{"id":"42546","messageId":"7vsl9t4va0.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"11795163061911-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 05/16] unpack-trees.c: verify_uptodate: remove dead code","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-18T22:33:11Z","receivedAt":"2007-05-18T22:33:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"skimo@liacs.nl writes:\n\n> From: Sven Verdoolaege <skimo@kotnet.org>\n>\n> This code was killed by commit fcc387db9bc453dc7e07a262873481af2ee9e5c8.\n>\n> Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>\n> ---\n>  unpack-trees.c |    4 ----\n>  1 files changed, 0 insertions(+), 4 deletions(-)\n>\n> diff --git a/unpack-trees.c b/unpack-trees.c\n> index 906ce69..cac2411 100644\n> --- a/unpack-trees.c\n> +++ b/unpack-trees.c\n> @@ -414,10 +414,6 @@ static void verify_uptodate(struct cache_entry *ce,\n>  \t\t\treturn;\n>  \t\terrno = 0;\n>  \t}\n> -\tif (o->reset) {\n> -\t\tce->ce_flags |= htons(CE_UPDATE);\n> -\t\treturn;\n> -\t}\n>  \tif (errno == ENOENT)\n>  \t\treturn;\n>  \tdie(\"Entry '%s' not uptodate. Cannot merge.\", ce->name);\n> -- \n> 1.5.2.rc3.783.gc7476-dirty\n\nHmmm.\n\nI am not absolutely sure if the fcc387db change was correct\nanymore, but in any case, this removal of dead code should not\nbreak anything.\n\nBut this does not belong to your series either.\n\nPerhaps I should apply this to 'master' regardless of the rest\nof the series.\n"},{"id":"42545","messageId":"7vmz014v9z.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"117951630747-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 11/16] git-fetch: skip empty arguments","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-18T22:33:12Z","receivedAt":"2007-05-18T22:33:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"skimo@liacs.nl writes:\n\n> From: Sven Verdoolaege <skimo@kotnet.org>\n>\n> This makes it easier for scripts to call git-fetch with options\n> that may or may not be set.\n\nFor git-fetch it does not matter as I do not think there is any\nvalid case to pass an empty string as a parameter to it (even\n\"fetch from our own repository\" requires a single dot).  But\nfrom discipline point of view, I am not happy about this.\n\nIf you are talking about shell scripts, the standard way to do\nthat is to say ${1+\"$1\"}.\n"},{"id":"42547","messageId":"20070518223338.GF10475@steel.home","threadId":"8208","inReplyTo":"20070518220323.GL942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 09/16] entry.c: optionally checkout submodules","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:33:38Z","receivedAt":"2007-05-18T22:33:38Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Sven Verdoolaege, Sat, May 19, 2007 00:03:23 +0200:\n> On Fri, May 18, 2007 at 11:56:42PM +0200, Alex Riesen wrote:\n> > skimo@liacs.nl, Fri, May 18, 2007 21:24:58 +0200:\n> > > +\tif (err)\n> > > +\t\treturn error(\"failed to run git-checkout in submodule '%s'\", path);\n> > \n> > We may need an option to ignore these failures. Maybe even active by\n> > default. Imagine a superproject with _optional_ submodules, where it\n> > is just nice to know that some submodules weren't checked out. BTW,\n> > doesn't git-checkout already prints an error?\n> \n> Probably.  You probably noticed that I haven't written any tests yet...\n> \n\nI see. It was a very ... provocative patch series :)\n\n> Still, the error that git-checkout prints may not give enough of a clue\n> that something was wrong with a submodule.\n\nLike, for example, it failed because the directory is not a git repo\nyet, because the previous git-checkout was called _without_\n--submodule and the directories created are just empty.\n\nAnyway, just a \"failed to run git-checkout\" is not very helpful\neither. Come to think about it, there is not very much you can tell\nout of super-project context. git-checkout will always know better.\n"},{"id":"42548","messageId":"20070518224209.GG10475@steel.home","threadId":"8208","inReplyTo":"20070518220826.GM942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:42:09Z","receivedAt":"2007-05-18T22:42:09Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Sven Verdoolaege, Sat, May 19, 2007 00:08:26 +0200:\n> I noticed there's a whole thread about subprojects that I haven't read yet,\n> so this may have been addressed already ....\n\nNot the checkout, which is strange. It's mostly about cloning.\n\n> On Fri, May 18, 2007 at 11:53:12PM +0200, Alex Riesen wrote:\n> > Can we have this option (and corresponding support in the following\n> > patches, of course) first?\n> \n> That's why the clone thing comes last.\n> \n> > It is enough to have subprojects working\n> > locally, and people can start using them immediately: anyone can clone\n> > the subprojects manually if he wishes so.\n> \n> Anyone can run git-write-tree and git-commit-tree is she wishes so...\n\nIt is much more tedious. It have to be done recursively, and with\nright SHA and you have to cd into right direcotry first and it is\ngit-read-tree and git-checkout-index, BTW.\n\nIOW, it is hard.\n\n> The reason for not putting this in shouldn't be that someone doesn't\n> think it is useful; the reason should be that my code is crap.\n\nThe code is not a problem. It can be also discarded because you\nimplemented something no one wants.\n\nI just meant to say, that even if no one wants your subproject cloning\ncode, _I_ support your checkout effort and I am asking for it to be\nput in.\n\n\"First\", as the cloning discussion does not seem to be finished (and,\nas I said, I am not interested in cloning anyway).\n"},{"id":"42549","messageId":"20070518224807.GH10475@steel.home","threadId":"8208","inReplyTo":"20070518222015.GE10475@steel.home","subject":"[PATCH] Use run_command_v_opt_cd when checking out a submodule","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:48:07Z","receivedAt":"2007-05-18T22:48:07Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Signed-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n entry.c |   12 +-----------\n 1 files changed, 1 insertions(+), 11 deletions(-)\n\ndiff --git a/entry.c b/entry.c\nindex 96a4a60..0316c74 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -166,7 +166,6 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout\n \n static int checkout_submodule(const char *path, struct cache_entry *ce, const struct checkout *state)\n {\n-\tstatic char cwd[PATH_MAX];\n \tconst char *gitdirenv;\n \tconst char *args[10];\n \tint argc;\n@@ -175,12 +174,6 @@ static int checkout_submodule(const char *path, struct cache_entry *ce, const st\n \tif (!state->submodules)\n \t\treturn 0;\n \n-\tif (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')\n-\t\tdie(\"Unable to read current working directory\");\n-\n-\tif (chdir(path))\n-\t\tdie(\"Cannot move to '%s'\", path);\n-\n \targc = 0;\n \targs[argc++] = \"checkout\";\n \tif (state->force)\n@@ -190,12 +183,9 @@ static int checkout_submodule(const char *path, struct cache_entry *ce, const st\n \n \tgitdirenv = getenv(GIT_DIR_ENVIRONMENT);\n \tunsetenv(GIT_DIR_ENVIRONMENT);\n-\terr = run_command_v_opt(args, RUN_GIT_CMD);\n+\terr = run_command_v_opt_cd(args, RUN_GIT_CMD, path);\n \tsetenv(GIT_DIR_ENVIRONMENT, gitdirenv, 1);\n \n-\tif (chdir(cwd))\n-\t\tdie(\"Cannot come back to cwd\");\n-\n \tif (err)\n \t\treturn error(\"failed to run git-checkout in submodule '%s'\", path);\n \n-- \n1.5.2.rc3.83.gbbb0\n"},{"id":"42550","messageId":"20070518225234.GI10475@steel.home","threadId":"8208","inReplyTo":"11795163072266-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 12/16] builtin-fetch--tool: extend \"native-store\" for use in cloning","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-18T22:52:34Z","receivedAt":"2007-05-18T22:52:34Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"skimo@liacs.nl, Fri, May 18, 2007 21:25:01 +0200:\n> @@ -261,7 +287,8 @@ static int fetch_native_store(FILE *fp,\n>  \t\t\t      const char *remote,\n>  \t\t\t      const char *remote_nick,\n>  \t\t\t      const char *refs,\n> -\t\t\t      int verbose, int force)\n> +\t\t\t      int verbose, int force,\n> +\t\t\t      int all, int use_separate_remote)\n>  {\n>  \tchar buffer[1024];\n>  \tint err = 0;\n> @@ -294,8 +321,12 @@ static int fetch_native_store(FILE *fp,\n>  \t\t\tcontinue;\n>  \t\t}\n>  \n> -\t\tlocal_name = find_local_name(cp, refs,\n> -\t\t\t\t\t     &single_force, &not_for_merge);\n> +\t\tif (all)\n> +\t\t\tlocal_name = construct_local_name(cp, remote_nick,\n> +\t\t\t\t\t\t\t  use_separate_remote);\n> +\t\telse\n> +\t\t\tlocal_name = find_local_name(cp, refs,\n> +\t\t\t\t\t\t     &single_force, &not_for_merge);\n\nThis code produces warning about possible uninitialized used of\nsingle_force and not_for_merge. I used the patch below, but didn't\nlook into what the \"all\" does.\n\n---\n builtin-fetch--tool.c |    4 ++--\n 1 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c\nindex 12adb38..ebb49d9 100644\n--- a/builtin-fetch--tool.c\n+++ b/builtin-fetch--tool.c\n@@ -273,7 +273,7 @@ static int fetch_native_store(FILE *fp,\n \t\tint len;\n \t\tchar *cp;\n \t\tchar *local_name;\n-\t\tint single_force, not_for_merge;\n+\t\tint single_force = force, not_for_merge = 0;\n \n \t\tfor (cp = buffer; *cp && !isspace(*cp); cp++)\n \t\t\t;\n@@ -301,7 +301,7 @@ static int fetch_native_store(FILE *fp,\n \t\terr |= append_fetch_head(fp,\n \t\t\t\t\t buffer, remote, cp, remote_nick,\n \t\t\t\t\t local_name, not_for_merge,\n-\t\t\t\t\t verbose, force || single_force);\n+\t\t\t\t\t verbose, single_force);\n \t}\n \treturn err;\n }\n-- \n1.5.2.rc3.83.gbbb0\n"},{"id":"42571","messageId":"20070519003410.GA4489@pasky.or.cz","threadId":"8208","inReplyTo":"11795163061588-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-19T00:34:10Z","receivedAt":"2007-05-19T00:34:10Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, May 18, 2007 at 09:24:56PM CEST, skimo@liacs.nl wrote:\n> From: Sven Verdoolaege <skimo@kotnet.org>\n> \n> This option currently has no effect.\n> \n> Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>\n\nNacked-by: Petr Baudis <pasky@suse.cz>\n\nPlease do not add more undocumented parameters - include documentation\nin the patch adding the parameter.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"42572","messageId":"20070519003655.GB4489@pasky.or.cz","threadId":"8208","inReplyTo":"11795163073176-git-send-email-skimo@liacs.nl","subject":"Re: [PATCH 10/16] git-checkout: pass --submodules option to git-read-tree","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-19T00:36:55Z","receivedAt":"2007-05-19T00:36:55Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, May 18, 2007 at 09:24:59PM CEST, skimo@liacs.nl wrote:\n> From: Sven Verdoolaege <skimo@kotnet.org>\n> \n> Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>\n> ---\n>  git-checkout.sh |   20 +++++++++++++++-----\n>  1 files changed, 15 insertions(+), 5 deletions(-)\n> \n> diff --git a/git-checkout.sh b/git-checkout.sh\n> index 6b6facf..cbb1f00 100755\n> --- a/git-checkout.sh\n> +++ b/git-checkout.sh\n> @@ -1,6 +1,6 @@\n>  #!/bin/sh\n>  \n> -USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'\n> +USAGE='[-q] [-f] [--submodules] [--no-submodules] [-b <new_branch>] [-m] [<branch>] [<paths>...]'\n>  SUBDIRECTORY_OK=Sometimes\n>  . git-sh-setup\n>  require_work_tree\n\nThus Documentation/git-checkout.txt needs to be updated as well.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"42583","messageId":"7vd50x1n0r.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070518224209.GG10475@steel.home","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-19T03:59:48Z","receivedAt":"2007-05-19T03:59:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alex Riesen <raa.lkml@gmail.com> writes:\n\n> Sven Verdoolaege, Sat, May 19, 2007 00:08:26 +0200:\n> ...\n>> The reason for not putting this in shouldn't be that someone doesn't\n>> think it is useful; the reason should be that my code is crap.\n>\n> The code is not a problem. It can be also discarded because you\n> implemented something no one wants.\n\nMore specifically, at the very high level, what you do and what\npeople want to happen might share the description (e.g. \"this\nallows checkout of subprojects\", or \"this implements clone of\nsuperproject to recurse\") but with semantics that may be\ndifferent from what people would want (I am not saying that is\nthe case, as I do not think the current discussion concluded\nyet).  The _first_ implementation that goes in the mainline\npretty much sets the _semantics_ so we would need to be extra\ncareful, all the more so as this is a feature many people seem\nto want.\n\n> I just meant to say, that even if no one wants your subproject cloning\n> code, _I_ support your checkout effort and I am asking for it to be\n> put in.\n>\n> \"First\", as the cloning discussion does not seem to be finished (and,\n> as I said, I am not interested in cloning anyway).\n\nIt was partly my fault that I mentioned \"clone\" example in the\noriginal message, and then let the discussion drifted to a\ntangent of the clone topic, namely, how the URL would be\ndetermined to clone the subproject from.\n\nI would agree that checkout is a more fundamental operation, and\nI wanted to make that clear in my message, but checkout and\nclone has certain chicken-and-egg factor between them.  After\nthe clone of superproject, checking it out recursively would\nneed cloning the subprojects.  Also after a clone of\nsuperproject without the recursive behaviour, when the user\nexplicitly asks a subproject to be checked out, somebody needs\nto do a clone before the subject can be checked out.\n\nHaving said that, let's throw out an strawman for checkout\nproper and then merge.\n\nThe user may or may not want to deal with subprojects, and for\nsomething truly large like the KDE case, which is where the\nsuperproject support is really needed, a large On/Off switch\nwhere an option --subproject makes everything checked out and no\nsubproject is checked out without it is not a usable option.\nI've already outlined how the .git/config file can be used to\ndefine which subprojects are of interested so that the Porcelain\nlayer can decide which ones to recurse into and which ones to\nleave alone.  The design is NOT the only possible/sensible one,\nand I am sure other people will come up with much nicer\norganization, but I would consider that is just the matter of\ndetails.\n\nNow, suppose \"git checkout\" needs to recurse into one\nsubdirectory that is to have a subproject.  There are three\ncases:\n\n (1) There is no git repository yet (the plumbing layer already\n     makes sure there is a directory, but does not do anything\n     else).\n\n (2) There already is a git repository there, which is the\n     correct repository (perhaps determined by .gitmodules and\n     .git/config in the superproject, or presense of the commit\n     that is recorded in the superproject's index).\n\n (3) There is a git repository but it is not the correct one.\n\nWe've discussed in the other thread about what to do in case\n(1) to some degree.\n\nFor case (2), I think what should happen there is an equivalent\nof this:\n\n\t$ commit=$(git-rev-parse :subproject)\n        $ cd subproject\n\t$ git-rev-parse --verify $commit || git fetch || barf\n        $ git checkout $commit\n\nThat is,\n\n - figure out what commit should be checked out from\n   superproject index;\n\n - make sure the named commit exists, or fetch to make it exist.\n\n - go there and check out that commit; this implies two things:\n\n   1. if there are local changes, it will be carried along and we\n      checkout the named commit;\n\n   2. the repository's HEAD becomes detached;\n\nIt is entirely possible that the repository is the _correct_ one\nbut not quite up to date, and you haven't fetched $commit.  This\nis really a variant of (1) -- before being able to check out,\nsomebody has to clone the subproject.  Before being able to\ncheck out to update the latest, somebody has to fetch in the\nsubproject.\n\nIf there are local changes, we would not at least lose them.  If\nyou want to get to a clean slate, you can cd there and perform\n\"git reset --hard\".  If you want to mark that commit in the\nsubproject, you may want to do \"git checkout -b branch\" after\nthe recursive checkout from the superproject detached the HEAD\nto the commit.\n\nThere is another variant that has already been suggested.  The\nsuperproject tree and index could record 0{40} object name for\nthe subproject, and say \"whatever commit happens to be at the\ntip of the branch of subproject\" (and most likely that URL and\nbranch information would come from .gitmodules and confirmed in\nthe .git/config file).  In such a case, the above outline would\nbe adjusted _BUT_ I think what would be checked out will not be\nthe named branch (e.g. refs/heads/master) itself, but the remote\nbranch that tracks it (e.g. refs/remotes/origin/master).\n\nWhile I am at it, let me think aloud as to what I _think_ should\nhappen in a superproject merge.\n\n - Carry out the tree-level 3-way merge.  If it trivially\n   resolves at the tree-level, we are happy.\n\n - There could be a case where the commit fetched/merged branch\n   has and what the current branch has are different.  If one is\n   a fast forward of the other, take it.\n\n - All other cases will leave the superproject index unmerged.\n\nWhen the merge is cleanly done, the resulting commit is what we\nshould check out in the subproject directory (if we are\nrecursing into it, of course).\n\nIt is likely that in some cases you would want go to the\nsubproject directory and merge the commits at the subproject\nfrom our branch and their branch in the superproject's index,\nand make the resulting commit as the result of the merge for\nthat subproject path in the superproject, but I do not think it\nis the only valid solution.\n"},{"id":"42586","messageId":"20070519042757.GD3141@spearce.org","threadId":"8208","inReplyTo":"7vd50x1n0r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-05-19T04:27:57Z","receivedAt":"2007-05-19T04:27:57Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Now, suppose \"git checkout\" needs to recurse into one\n> subdirectory that is to have a subproject.  There are three\n> cases:\n\nSo I've implemented my own Git subproject support in a Java based\ntool we use internally.  Its actually driving the Git plumbing (as\nJGit isn't complete enough to do the job) but applies quite a bit\nto this discussion as it is a working system that implements this\n\"checkout in superproject and recurse into subproject\".\n\nFirst I don't use the subproject support in the core plumbing,\nbecause that came along from Linus about 2 days after I wrote\nthis implementation.  Our data file looks like:\n\n\tuse-component: subproject1 >=df8cfac815...\n\tuse-component: subproject2 >=af9b543820...\n\nOr really anything that is a valid commit-ish, and often these are\nactually just annotated tag names.\n\n>  (1) There is no git repository yet (the plumbing layer already\n>      makes sure there is a directory, but does not do anything\n>      else).\n\nDuring our build process we scan the root project's data file,\nand clone by the relative URL anything we cannot find locally:\n\n\t$(git config remote.origin.url)/../component-links/subproject1.git\n\nto get the subproject repository.  We don't require that the\nsubproject1 directory actually be called subproject1 in the\nsuperproject, its just a recommendation.  That data file is also\nour build-system driver and the build system driver is pretty darn\nsmart about guessing what is going on.  ;-)\n\nYou'll notice however that we (more or less) have a very flat\nstructure.  The component-links directory is really just a set of\nsymlinks pointing back up a level, as sometimes a component is not\nstored in a repository named the component name, but the component\nname matters to the build system.\n\n>  (2) There already is a git repository there, which is the\n>      correct repository (perhaps determined by .gitmodules and\n>      .git/config in the superproject, or presense of the commit\n>      that is recorded in the superproject's index).\n> \n>  (3) There is a git repository but it is not the correct one.\n> \n> For case (2), I think what should happen there is an equivalent\n> of this:\n> \n> \t$ commit=$(git-rev-parse :subproject)\n>         $ cd subproject\n> \t$ git-rev-parse --verify $commit || git fetch || barf\n>         $ git checkout $commit\n\nYes.  Except we do a few things differently:\n\n - Only update the subproject if its a strict fast-forward.\n\n - Abort on a dirty working directory in the subproject or if a merge\n would be required to keep the current commit and the new commit.\n Yes, we don't really support going \"backwards\".\n\n - The merge aborting thing is probably wrong for some users,\n but blindly switching to the target commit feels somewhat wrong\n in our own uses.  Sometimes you need the current version of the\n subproject to help you debug an older version of the superproject,\n or sibling subproject.\n\n - You can't just checkout $commit if you can rev-parse it.\n You need to verify it and its entire reachable object set exists.\n See the local fetch fast-path thing you did recently in e3c6f240fd.\n\n - We update the user's current branch.  Because we are doing\n a strict fast-forward we're also assuming the user wants the\n current branch to stay correlated to the superproject branch.  Why?\n Most of our users keep the same branch name in all repositories.\n\n-- \nShawn.\n"},{"id":"42606","messageId":"20070519091945.GA2462@steel.home","threadId":"8208","inReplyTo":"7vd50x1n0r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2007-05-19T09:19:45Z","receivedAt":"2007-05-19T09:19:45Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"Junio C Hamano, Sat, May 19, 2007 05:59:48 +0200:\n> \n>  - figure out what commit should be checked out from\n>    superproject index;\n> \n>  - make sure the named commit exists, or fetch to make it exist.\n\nWhat if the fetch is not possible? You can't checkout? What about the\nother subprojects, where the checkout succeeded? Will they be reset to\nthe previuos state?\n\nTo me, the fetch sounds pretty dangerous. Maybe the checkout should\nbe two stage: first - we check all subprojects to be checked out if it\nis possible, second - either fail (default) or checkout what possible,\nwarn the user, leave the incomplete subprojects changed (but not\nupdate the index with them, so that they wont be accidentally\ncommitted).\n\n>  - go there and check out that commit; this implies two things:\n> \n>    1. if there are local changes, it will be carried along and we\n>       checkout the named commit;\n\nShouldn't that depend on \"-m\" option given to git-checkout in\nsuperproject? Sometime the user have to be sure he can checkout\neverything as it were, but without breaking the local state (like what\ncurrent git-checkout without \"-m\" does).\n\n>    2. the repository's HEAD becomes detached;\n> \n\nUniversally agreed upon\n"},{"id":"42620","messageId":"20070519121757.GP942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"20070518225234.GI10475@steel.home","subject":"Re: [PATCH 12/16] builtin-fetch--tool: extend \"native-store\" for use in cloning","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-19T12:17:57Z","receivedAt":"2007-05-19T12:17:57Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Sat, May 19, 2007 at 12:52:34AM +0200, Alex Riesen wrote:\n> This code produces warning about possible uninitialized used of\n> single_force and not_for_merge. I used the patch below, but didn't\n> look into what the \"all\" does.\n\nSorry for being sloppy.  It is assumed that \"all\" is only used\nfor cloning and then the other two flags don't really matter,\nbut I should've set some defaults.\nYours look fine, thanks.\n\nA fixed-up version is available in the \"submodules\" branch\nof http://www.liacs.nl/~sverdool/git.git or\nwww.liacs.nl/~sverdool/gitweb.cgi?p=git.git;a=shortlog;h=submodules\n\nskimo\n"},{"id":"42622","messageId":"20070519130542.GR942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"7vd50x1n0r.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-19T13:05:42Z","receivedAt":"2007-05-19T13:05:42Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Fri, May 18, 2007 at 08:59:48PM -0700, Junio C Hamano wrote:\n> Now, suppose \"git checkout\" needs to recurse into one\n> subdirectory that is to have a subproject.  There are three\n> cases:\n> \n>  (1) There is no git repository yet (the plumbing layer already\n>      makes sure there is a directory, but does not do anything\n>      else).\n> \n>  (2) There already is a git repository there, which is the\n>      correct repository (perhaps determined by .gitmodules and\n>      .git/config in the superproject, or presense of the commit\n>      that is recorded in the superproject's index).\n> \n>  (3) There is a git repository but it is not the correct one.\n> \n> We've discussed in the other thread about what to do in case\n> (1) to some degree.\n> \n> For case (2), I think what should happen there is an equivalent\n> of this:\n> \n> \t$ commit=$(git-rev-parse :subproject)\n>         $ cd subproject\n> \t$ git-rev-parse --verify $commit || git fetch || barf\n>         $ git checkout $commit\n\nDoes everyone agree that we should fetch (possibly after asking\nfor confirmation from the use) _during_ the checkout ?\nI now only fetch submodules during a fetch of the supermodule\n(actually, in my current patch set, I only fetch a submodule\nthe first time I see it, but that's a bug), but if there is\na consensus on this, I can switch to fetching during checkout.\n\nAs to the key to use to lookup the URL in the config, right\nnow I simply use the directory name where it is attached\n(which seems like a useful default to me).\nI'm not all that convinced that we should store a default URL\nin history, so AFAICS, the only thing we need to store is a\nmapping between directory names and subproject names.\nIt has been suggested to do that in .gitattributes.\nIs that OK for everyone, or do we really need a separate .gitmodules ?\n\nskimo\n"},{"id":"42639","messageId":"7v4pm8y8tf.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070519130542.GR942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-19T18:20:12Z","receivedAt":"2007-05-19T18:20:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sven Verdoolaege <skimo@kotnet.org> writes:\n\n> Does everyone agree that we should fetch (possibly after asking\n> for confirmation from the use) _during_ the checkout ?\n> I now only fetch submodules during a fetch of the supermodule\n> (actually, in my current patch set, I only fetch a submodule\n> the first time I see it, but that's a bug), but if there is\n> a consensus on this, I can switch to fetching during checkout.\n\nI think fetching of subproject during fetch or clone of\nsuperproject would not make much sense.  Making it part of\nsuperproject checkout would probably be the way we will end up\ngoing.  The detail of \"which part of the checkout\" would need to\nbe defined, and I tend to agree with Alex that checkout itself\nwould need to be multi-phased, but I think that is a minor\nimplementation detail we can discuss after how the overall flows\nshould look like.\n\n> As to the key to use to lookup the URL in the config, right\n> now I simply use the directory name where it is attached\n> (which seems like a useful default to me).\n\n> I'm not all that convinced that we should store a default URL\n> in history, so AFAICS, the only thing we need to store is a\n> mapping between directory names and subproject names.\n> It has been suggested to do that in .gitattributes.\n> Is that OK for everyone, or do we really need a separate .gitmodules ?\n\nIf your (super)repository is _the_ only repository that knows\nabout the aggregation it is doing, I do not think you need\nanything, as .git/config in the subproject would know where to\nget updates from.  Otherwise, Project wide suggestions need to\nbe there in some machine readable form if you were to allow such\nsuperproject distributed, be it in .gitmodules or\n.gitattributes, don't they?\n\nAnd frankly, I think .gitattributes is a wrong place to store\nit, as its semantics is to give attributes to paths that MATCH\nthe glob.  You can argue that a pattern in .gitattributes can be\nwritten to match only one path, but it still feels conceptually\nwrong.  Something more concrete and exact, like the second level\nkey of .git/config and .gitmodules file format, is preferable.\n"},{"id":"42722","messageId":"20070520155407.GC27087@efreet.light.src","threadId":"8208","inReplyTo":"7v4pm8y8tf.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-20T15:54:07Z","receivedAt":"2007-05-20T15:54:07Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Sat, May 19, 2007 at 11:20:12 -0700, Junio C Hamano wrote:\n> Sven Verdoolaege <skimo@kotnet.org> writes:\n> \n> > Does everyone agree that we should fetch (possibly after asking\n> > for confirmation from the use) _during_ the checkout ?\n> > I now only fetch submodules during a fetch of the supermodule\n> > (actually, in my current patch set, I only fetch a submodule\n> > the first time I see it, but that's a bug), but if there is\n> > a consensus on this, I can switch to fetching during checkout.\n> \n> I think fetching of subproject during fetch or clone of\n> superproject would not make much sense.  Making it part of\n> superproject checkout would probably be the way we will end up\n> going.  The detail of \"which part of the checkout\" would need to\n> be defined, and I tend to agree with Alex that checkout itself\n> would need to be multi-phased, but I think that is a minor\n> implementation detail we can discuss after how the overall flows\n> should look like.\n\nIMHO it makes more sense to fetch during fetch of superproject:\n\n - If you don't fetch the superproject, it won't start refering to\n   unavailable commit of subproject. So should only need to fetch subproject\n   after fetching superproject.\n\n - If you fetch from more than one location, you want to fetch subproject\n   from location corresponding to where you fetch superproject from.\n   \n   Let's have a repository of project P with remotes PA and PB. Let it have\n   a subproject S with remotes SA and SB.\n\n   Whenever I pull P from PA, it might refer to commit of S, that is only\n   available from SA (because that's what PA owner uses). Whenever I pull\n   P from PB, it might refer to commit of S, that is only available from SB\n   (again because that's what PB owner uses).\n\n   Now checkout does not know, whether I pulled the target revision from PA\n   or PB, so:\n    - Either it has to fetch both. But say the commit I want is in SB and SA\n      contains a lot of new stuff, which will slow the thing down, though\n      I don't need it.\n    - Or it has to guess by looking whether any heads in remotes/PA or\n      remotes/PB are descendants of the commit being checked out. But that\n      feels rather hacky.\n\n   I see several options:\n    - Fetch will recurse. This should work ok and is IMHO least magic. We can\n      also add some way to specify refspecs for the subproject, giving user\n      control over what is fetched.\n    - Fetch will store a \"pending fetch from\" note in the subproject and\n      checkout, if it does not find the revision, will try fetching from all\n      sources pointed to by those notes. There is still a problem with what\n      exactly to fetch (user can specify in config).\n    - Checkout will ask all subproject repositories whether they have given\n      commit and pull the first one that does. This would get the needed\n      commit most certainly. It would be slower though, because it would need\n      to ask all the repositories whether they have the particular object.\n      It also leaves the tracking branches in subproject in somewhat random\n      state (maybe both repositories had the commit, so it pulled from the\n      other one that user would etc.).\n\n> > As to the key to use to lookup the URL in the config, right\n> > now I simply use the directory name where it is attached\n> > (which seems like a useful default to me).\n\nThe extra level of indirection has the advantage, that you can describe\nmoving the same subproject to a different directory.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"42756","messageId":"7vbqgfmjki.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070520155407.GC27087@efreet.light.src","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-20T18:33:17Z","receivedAt":"2007-05-20T18:33:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jan Hudec <bulb@ucw.cz> writes:\n\n> IMHO it makes more sense to fetch during fetch of superproject:\n>\n>  - If you don't fetch the superproject, it won't start refering to\n>    unavailable commit of subproject. So should only need to fetch subproject\n>    after fetching superproject.\n\nEh, I was suggesting that the subproject fetch would come after\ncheckout in \"fetch and then checkout\" sequence of the\nsuperproject, and if you are arguing against it, you should\njustify why it should not happen before checkout, as we both\nagree it should come after fetch of superproject.  Your argument\nis like saying you have to git-init before doing anything so\nyou should fetch when you git-init.  That's not a justification.\n\n>  - If you fetch from more than one location, you want to fetch subproject\n>    from location corresponding to where you fetch superproject from.\n\nNot at all.  There is no reason to believe that the case that\nsuperproject and subproject come from related URLs is more\ncommon.  One of the reasons to do a separated project\norganization is to allow looser bindings of the project from\nproject administrative viewpoint. The integrator may not\nnecessarily have any control over what the subproject guys do,\nand more importantly, the subproject people do not even care nor\nbe aware of the fact that their project is sometimes bound\ninside other peoples' superprojects.  Think of the embedded\nappliance vendor binding the kernel, libc and busybox in their\nsuperproject that holds them together with the build\ninfrastructure. The kernel folks certainly do not particularly\ncare about the vendor.\n"},{"id":"42776","messageId":"20070520202201.GY942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"7vbqgfmjki.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-20T20:22:01Z","receivedAt":"2007-05-20T20:22:01Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Sun, May 20, 2007 at 11:33:17AM -0700, Junio C Hamano wrote:\n> Jan Hudec <bulb@ucw.cz> writes:\n> >  - If you fetch from more than one location, you want to fetch subproject\n> >    from location corresponding to where you fetch superproject from.\n> \n> Not at all.  There is no reason to believe that the case that\n> superproject and subproject come from related URLs is more\n> common.  One of the reasons to do a separated project\n> organization is to allow looser bindings of the project from\n> project administrative viewpoint. The integrator may not\n> necessarily have any control over what the subproject guys do,\n> and more importantly, the subproject people do not even care nor\n> be aware of the fact that their project is sometimes bound\n> inside other peoples' superprojects.  Think of the embedded\n> appliance vendor binding the kernel, libc and busybox in their\n> superproject that holds them together with the build\n> infrastructure. The kernel folks certainly do not particularly\n> care about the vendor.\n\nI think what Jan means is that if there are two (or more) copies\nof the superproject then it is more likely that the subproject\ncommit can be found in the subproject repo \"pointed to\" (e.g.,\nthrough my submodule.*.url) by the superproject repo you fetched from.\n\nskimo\n"},{"id":"42903","messageId":"20070521165938.GA4118@efreet.light.src","threadId":"8208","inReplyTo":"7vbqgfmjki.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-21T16:59:38Z","receivedAt":"2007-05-21T16:59:38Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"Hello,\n\nI gave the problem some more thought, and though I follow up on my previous\ncomment below, I can now see this:\n\nSo far it was discussed what should happen in fetch (+ checkout). But I think\nthe following are the interesting cases. Please read ALL before responding,\nthey are in somewhat random order:\n\n For following, assume there is a repo of project super has two branches,\n master and next. The next branch adds subproject sublib. In that state, I fetch\n refs/heads/*:refs/remotes/origin/* and check out master. So I have\n a repository, that contains revision with submodule, but I did not check it\n out yet.\n\n - Some time later, *without* fetching again, I simply\n      git checkout --submodules -b feature1 remotes/origin/next\n   Obviously it needs to give me the module.\n\n - Should that checkout work without network access?\n\n - Ok, now I start hacking on feature1 and find a bug in sublib, that I need\n   to fix for it to work. Therefore I change something within sublib.\n\n   However few days later I am asked to fix a bug in stable release of super.\n   Therefore I: git checkout master Now, where does sublib go? It contains\n   precious data!\n\n   For the worst case situation assume, that the master branch also has\n   directory sublib, so it can't stay where it was as unversioned.\n\n - The fix in master is done, back to our feature1, right?  git checkout\n   --submodules feature1 Obviously re-fetching from upstram won't work. The\n   head feature1 now refers to a commit that I made and only exists localy.\n\n - Now the maintainer of super wants to test the feature1. However sublib\n   upstream did not accept the bugfix yet (and is perhaps waiting for\n   confirmation, that the fixed version really works well for super, so we\n   have to test).\n\n   Therefore I push feature1 to my public repo, set up a public repo with my\n   fixes to sublib and configure my public super repo to know about it.\n\n   The maintainer already has a repo of super including sublib submodule. But\n   when he pulls from me, he does not have the repo with my fixes.\n\n - The maintainer reviewed my feature1 and now needs to work on feature2.\n   That however requires new upstream version of super. Therefore he needs to\n   pull alternatively from both upstream and my repo with super, depending on\n   what he works on.\n\n   For the most complex case, assume here that I add more fixes to sublib\n   while author of feature2 uses more and more bleeding edge stuff, so the\n   maintainer really needs futher changes in sublib from both repos.\n\n - Also git has to fail safe if I forget to push the sublib, so when the\n   maintainer tries to pull super, the refered revision of sublib simply\n   won't be found.\n\nI am not sure how to handle these cases. But they are cases that can happen\nin real life and should be handled somehow. Even if some of them just require\nsome manual configuration.\n\nHere is one possible idea:\n\nWe could store the GIT_DIR of submodule within the GIT_DIR of the\nsuperproject instead of the submodule directory itself. So instead of:\n /\n /.git\n /subdir\n /subdir/.git\n\nThere would be:\n /\n /.git\n /subdir\n /.git/submodules/submodule-name.git\n\nThis would require changes to the logic how git finds GIT_DIR (which would be\nreally deep change), but it would provide place to store the submodule data\nwhile the submodule is not being checked out. \n\nThis does not address the last two cases above with mutliple sources, each\ncontaining some revisions. There I see two options:\n\n - The submodules are fetched during superproject fetch (based on them being\n   configured, even if they are not checked out) and the URL might depend on\n   url configured for superproject. That is:\n      git fetch --submodules foobar\n   would do roughty:\n      for GIT_DIR in $GIT_DIR/submodules/*.git; do\n         git fetch foobar || git fetch\n      done\n   So if you configured source of the same name for the subproject, it would\n   be pulled, otherwise the default one would.\n\n   Checkout would then be local-only operation, because subprojects are\n   up-to-date.\n\n - The superproject checkout would try fetching all sources of the\n   subproject, until the requested revision is found.\n\n   This could be extended to normal checkout doing it as well --\n   \"git checkout sha1\" would try fetching all configured sources if the\n   revision was not found.\n\nPerhaps we could actually do both. That is, \"git fetch --subprojects\" to\nalso fetch all of \"$GIT_DIR/submodules/*.git\" and checkout to try fetching if\nit can't find the desired revision.\n\nOn Sun, May 20, 2007 at 11:33:17 -0700, Junio C Hamano wrote:\n> Jan Hudec <bulb@ucw.cz> writes:\n> > IMHO it makes more sense to fetch during fetch of superproject:\n> >\n> >  - If you don't fetch the superproject, it won't start refering to\n> >    unavailable commit of subproject. So should only need to fetch subproject\n> >    after fetching superproject.\n> \n> Eh, I was suggesting that the subproject fetch would come after\n> checkout in \"fetch and then checkout\" sequence of the\n> superproject, and if you are arguing against it, you should\n> justify why it should not happen before checkout, as we both\n> agree it should come after fetch of superproject.  Your argument\n> is like saying you have to git-init before doing anything so\n> you should fetch when you git-init.  That's not a justification.\n\nIt definitely has to come after fetch on superproject. My original thought\nwas, that it would be weird if it was part of the checkout itself, meaning\neven checkout that does not follow a fetch. However I thought about it some\nmore and that might conflict with other requirements.\n\n> >  - If you fetch from more than one location, you want to fetch subproject\n> >    from location corresponding to where you fetch superproject from.\n> \n> Not at all.  There is no reason to believe that the case that\n> superproject and subproject come from related URLs is more\n> common.  One of the reasons to do a separated project\n\nI definitely don't think it's more common. But it's the harder case and it\nmight happen. Generally it will happen if some people work on both the\nsuperproject and the subproject. Of course the argument is that than it\nshould not be separate projects, but maybe the teams just partly overlap.\n\nExample of this situation is given above. IMHO it needs to be handled\nsomehow (probably git would have to check all potential sources whether they\nhave the revision in question).\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"42909","messageId":"20070521180506.GP942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"20070521165938.GA4118@efreet.light.src","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-21T18:05:06Z","receivedAt":"2007-05-21T18:05:06Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n> We could store the GIT_DIR of submodule within the GIT_DIR of the\n> superproject instead of the submodule directory itself. So instead of:\n>  /\n>  /.git\n>  /subdir\n>  /subdir/.git\n> \n> There would be:\n>  /\n>  /.git\n>  /subdir\n>  /.git/submodules/submodule-name.git\n\nI have this already, except that I use /.git/submodules/submodule-name/.git\nbecause I was too lazy to figure out how to get clone to use the above\nwithout using --bare, because --bare disables separate-remotes.\n\nIs there any good reason, btw for --bare not to do separate-remotes ?\nWe could throw out a lot of speical cases, especially the --bare http\nfetch if we would simply always do a separate-remotes.\n\n> This would require changes to the logic how git finds GIT_DIR (which would be\n> really deep change),\n\nEuhm.... I just add a symlink...\n\nskimo\n"},{"id":"42917","messageId":"7vr6pac86g.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070521180506.GP942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-21T19:01:43Z","receivedAt":"2007-05-21T19:01:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sven Verdoolaege <skimo@kotnet.org> writes:\n\n> On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n>> We could store the GIT_DIR of submodule within the GIT_DIR of the\n>> superproject instead of the submodule directory itself. So instead of:\n>>  /\n>>  /.git\n>>  /subdir\n>>  /subdir/.git\n>> \n>> There would be:\n>>  /\n>>  /.git\n>>  /subdir\n>>  /.git/submodules/submodule-name.git\n>\n> I have this already, except that I use /.git/submodules/submodule-name/.git\n> because I was too lazy to figure out how to get clone to use the above\n> without using --bare, because --bare disables separate-remotes.\n>\n> Is there any good reason, btw for --bare not to do separate-remotes ?\n\nTraditinoally, the purpose of --bare is to set up distribution\npoints, either CVS style \"shared public repository that\neverybody pushes into and fetches from\", or \"owned by me and I\npush my change into it to publish\".  In either case, there is no\npoint of even having an upstream in such a repository, let\nalone refs/remotes/origin/ hierarchy.\n\nSo that's the \"good reason\" part.\n\nHaving said that, last night I was thinking about making the\nlayout after a clone a bit more flexible and orthogonal to\nexistence of working tree.  What got me thinking about it was\ndifferent from your motivation, though.\n\nIf you have an ordinary working tree, and if you want to have a\nclone of that working tree that you can work in, independently\n(i.e. not treating the repository you cloned from any specially\nfrom other repositories by marking it \"origin\"), currently there\nis no straightforward way to do so, other than doing \nsomething like:\n\n (1) do a --bare clone, which would create \"project.git\";\n\n (2) mkdir \"project\" && mv \"project.git\" \"project/.git\";\n\n (3) edit \"project/.git/config\" and mark it as a non-bare\n     repository.\n\n (4) \"git checkout -f HEAD\".\n\nI'd call this a \"pure\" clone.  It is as close as the original\nrepository you would get without copying other per-repository\ndata such as .git/info, .git/config, so that you can start using\nit as an _independent _repository.  It is like a --bare clone\nbut with a working tree associated with it.\n\nWhat you want is probably the opposite.  A bare, but non-pure\nclone.  By non-pure, what I mean is:\n\n (1) it has an upstream (\"origin\"), hence\n (2) it has refs/remotes/origin, and \"remotes.origin.*\"\n\nIf the word \"non-pure\" has a negative connotation, you could\ncall it \"a follower repository\".\n\nIn short, the current behaviour of --bare is \"bare and pure\",\nand clone without --bare is \"not bare, and a follower\".  What I\nwanted was \"not bare, but pure\", and I think what you want is\n\"bare, but a follower\".\n"},{"id":"42921","messageId":"20070521200235.GE5082@efreet.light.src","threadId":"8208","inReplyTo":"20070521180506.GP942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-21T20:02:35Z","receivedAt":"2007-05-21T20:02:35Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Mon, May 21, 2007 at 20:05:06 +0200, Sven Verdoolaege wrote:\n> On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n> > We could store the GIT_DIR of submodule within the GIT_DIR of the\n> > superproject instead of the submodule directory itself. So instead of:\n> >  /\n> >  /.git\n> >  /subdir\n> >  /subdir/.git\n> > \n> > There would be:\n> >  /\n> >  /.git\n> >  /subdir\n> >  /.git/submodules/submodule-name.git\n> \n> I have this already, except that I use /.git/submodules/submodule-name/.git\n> because I was too lazy to figure out how to get clone to use the above\n> without using --bare, because --bare disables separate-remotes.\n> \n> Is there any good reason, btw for --bare not to do separate-remotes ?\n> We could throw out a lot of speical cases, especially the --bare http\n> fetch if we would simply always do a separate-remotes.\n\nGlad to hear it. I didn't really have time to read through all the patches.\n\n> > This would require changes to the logic how git finds GIT_DIR (which would be\n> > really deep change),\n> \n> Euhm.... I just add a symlink...\n\nYes. Except I am not sure mingw supports that.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"42927","messageId":"20070521211133.GD5412@admingilde.org","threadId":"8208","inReplyTo":"20070521165938.GA4118@efreet.light.src","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Martin Waitz","fromEmail":"tali@admingilde.org","sentAt":"2007-05-21T21:11:34Z","receivedAt":"2007-05-21T21:11:34Z","isPatch":true,"sender":{"key":"tali@admingilde.org","avatar":"https://gravatar.com/avatar/3f89b03eee362187effabe257898735b475673a12265c398ea9161259ae91553?d=mp&s=160"},"body":"hoi :)\n\nOn Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n> Here is one possible idea:\n> \n> We could store the GIT_DIR of submodule within the GIT_DIR of the\n> superproject instead of the submodule directory itself. So instead of:\n>  /\n>  /.git\n>  /subdir\n>  /subdir/.git\n> \n> There would be:\n>  /\n>  /.git\n>  /subdir\n>  /.git/submodules/submodule-name.git\n> \n> This would require changes to the logic how git finds GIT_DIR (which would be\n> really deep change), but it would provide place to store the submodule data\n> while the submodule is not being checked out. \n\nI agree that we need something like that.\n\nWe don't have to move the entire subproject.git into the superproject,\nbut we need to have all _referenced_ objects in the .git dir of the\nsuperproject.\n\nThere are several possibilities to do so:\n\n * move the entire .git dir\n * move .git/objects\n * explicitly copy all referenced objects\n\nI have some experimental code to configure a per-subproject directory\nin the superproject/.git as alternate object store for the submodule\nto make the last two solutions possible.  Perhaps I should dig it out again\nand adapt it to current git.\n\nIf there is a 1:1 relationship between subproject and object store then\neven efficient fsck and repack/prune are possible for the submodule without\nloosing objects.\nBut such a 1:1 relationship is bad when you move subprojects to another\nlocation (or include the same subproject several times in different\nlocations of the tree).\nPerhaps the user should be able to choose which one he wants.\n\n> > Not at all.  There is no reason to believe that the case that\n> > superproject and subproject come from related URLs is more\n> > common.  One of the reasons to do a separated project\n> \n> I definitely don't think it's more common. But it's the harder case and it\n> might happen. Generally it will happen if some people work on both the\n> superproject and the subproject. Of course the argument is that than it\n> should not be separate projects, but maybe the teams just partly overlap.\n\nI think it will be _very_ common to store super and subprojects in\nrelated locations.  First to be independent from third-party servers\nwhile working on the superproject.\nSecond (and I think more important) because many times there will\nbe superproject related adaptations in the subproject.  Yes they\nare independent, and exactly for that reason the subproject upstream\nmaintainers may not take every change which is needed to satisfy the\nsuperproject.  We _now_ see that in all Linux distributions already.\nSo when you use superprojects to integrate several independent projects,\nthen the superproject maintainer/administrator should really keep a\nclone of all subprojects handy on his site.\n\n-- \nMartin Waitz\n"},{"id":"42988","messageId":"20070522193706.GA4432@efreet.light.src","threadId":"8208","inReplyTo":"20070521211133.GD5412@admingilde.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-22T19:37:06Z","receivedAt":"2007-05-22T19:37:06Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Mon, May 21, 2007 at 23:11:34 +0200, Martin Waitz wrote:\n> On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n> > There would be:\n> >  /\n> >  /.git\n> >  /subdir\n> >  /.git/submodules/submodule-name.git\n> > \n> > This would require changes to the logic how git finds GIT_DIR (which would be\n> > really deep change), but it would provide place to store the submodule data\n> > while the submodule is not being checked out. \n> \n> I agree that we need something like that.\n> \n> We don't have to move the entire subproject.git into the superproject,\n> but we need to have all _referenced_ objects in the .git dir of the\n> superproject.\n> \n> There are several possibilities to do so:\n> \n>  * move the entire .git dir\n>  * move .git/objects\n>  * explicitly copy all referenced objects\n\nI believe we really need entire .git dir. When the superporject checks out\nrevision which does not reference that subproject, we still need to preserve\nnot only the objects of subproject, but also the refs and config.\n\n> I have some experimental code to configure a per-subproject directory\n> in the superproject/.git as alternate object store for the submodule\n> to make the last two solutions possible.  Perhaps I should dig it out again\n> and adapt it to current git.\n> \n> If there is a 1:1 relationship between subproject and object store then\n> even efficient fsck and repack/prune are possible for the submodule without\n> loosing objects.\n> But such a 1:1 relationship is bad when you move subprojects to another\n> location (or include the same subproject several times in different\n> locations of the tree).\n> Perhaps the user should be able to choose which one he wants.\n\nThat's why there should be the extra level of indirection using .gitmodules.\nIt should map the directory name to the object store name, so you can\nrelocate the subproject.\n\nIncluding the same project several times is indeed interesting. Maybe the\nsubprojects should be \"light checkouts\" (I believe something like this was\nalready discussed on the list sometime). Those would be .git dirs, that would\nonly have HEAD and pointer to another .git dir with everything else.\n\n> > > Not at all.  There is no reason to believe that the case that\n> > > superproject and subproject come from related URLs is more\n> > > common.  One of the reasons to do a separated project\n> > \n> > I definitely don't think it's more common. But it's the harder case and it\n> > might happen. Generally it will happen if some people work on both the\n> > superproject and the subproject. Of course the argument is that than it\n> > should not be separate projects, but maybe the teams just partly overlap.\n> \n> I think it will be _very_ common to store super and subprojects in\n> related locations.  First to be independent from third-party servers\n> while working on the superproject.\n> Second (and I think more important) because many times there will\n> be superproject related adaptations in the subproject.  Yes they\n> are independent, and exactly for that reason the subproject upstream\n> maintainers may not take every change which is needed to satisfy the\n> superproject.  We _now_ see that in all Linux distributions already.\n> So when you use superprojects to integrate several independent projects,\n> then the superproject maintainer/administrator should really keep a\n> clone of all subprojects handy on his site.\n\nYes, repositories with distribution-specific patches will add a large class\nof cases requiring multiple sources support.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"43147","messageId":"20070524154833.GL5412@admingilde.org","threadId":"8208","inReplyTo":"20070522193706.GA4432@efreet.light.src","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Martin Waitz","fromEmail":"tali@admingilde.org","sentAt":"2007-05-24T15:48:33Z","receivedAt":"2007-05-24T15:48:33Z","isPatch":true,"sender":{"key":"tali@admingilde.org","avatar":"https://gravatar.com/avatar/3f89b03eee362187effabe257898735b475673a12265c398ea9161259ae91553?d=mp&s=160"},"body":"On Tue, May 22, 2007 at 09:37:06PM +0200, Jan Hudec wrote:\n> > We don't have to move the entire subproject.git into the superproject,\n> > but we need to have all _referenced_ objects in the .git dir of the\n> > superproject.\n> > \n> > There are several possibilities to do so:\n> > \n> >  * move the entire .git dir\n> >  * move .git/objects\n> >  * explicitly copy all referenced objects\n> \n> I believe we really need entire .git dir. When the superporject checks out\n> revision which does not reference that subproject, we still need to preserve\n> not only the objects of subproject, but also the refs and config.\n\nbut all the other refs do not belong to the superproject.\nFor those who are working on the subproject there are of course a lot\nof refs which they have to work with, but that can be dealt with\noutside of the superproject scope.  The subproject is still a normal\nGit repository, after all.\nThat is, you can have remote entries, branches and what not.\nBut all that is not interesting in the superproject scope.\n\nSo I thing moving the entire subproject.git into the superproject.git is too\nmuch.  The superproject is only interested in the objects and in one\nref -- the one stored inside its tree.\n\n> > I have some experimental code to configure a per-subproject directory\n> > in the superproject/.git as alternate object store for the submodule\n> > to make the last two solutions possible.  Perhaps I should dig it out again\n> > and adapt it to current git.\n> > \n> > If there is a 1:1 relationship between subproject and object store then\n> > even efficient fsck and repack/prune are possible for the submodule without\n> > loosing objects.\n> > But such a 1:1 relationship is bad when you move subprojects to another\n> > location (or include the same subproject several times in different\n> > locations of the tree).\n> > Perhaps the user should be able to choose which one he wants.\n> \n> That's why there should be the extra level of indirection using .gitmodules.\n> It should map the directory name to the object store name, so you can\n> relocate the subproject.\n> \n> Including the same project several times is indeed interesting. Maybe the\n> subprojects should be \"light checkouts\" (I believe something like this was\n> already discussed on the list sometime). Those would be .git dirs, that would\n> only have HEAD and pointer to another .git dir with everything else.\n\nWell, even if they might share a lot of objects they might be included\nfor completely different reasons and so might need to work with\ndifferent communities (remote entries, branches, etc.).\n\nSo sharing objects makes sense, sharing the rest of .git is not\nneccessary.\n\n> > I think it will be _very_ common to store super and subprojects in\n> > related locations.  First to be independent from third-party servers\n> > while working on the superproject.\n> > Second (and I think more important) because many times there will\n> > be superproject related adaptations in the subproject.  Yes they\n> > are independent, and exactly for that reason the subproject upstream\n> > maintainers may not take every change which is needed to satisfy the\n> > superproject.  We _now_ see that in all Linux distributions already.\n> > So when you use superprojects to integrate several independent projects,\n> > then the superproject maintainer/administrator should really keep a\n> > clone of all subprojects handy on his site.\n> \n> Yes, repositories with distribution-specific patches will add a large class\n> of cases requiring multiple sources support.\n\nYou don't really need multiple sources for it.\nThe subproject contains both upstream and local changes, but I think\nit makes sense to keep the entire object store local (the same way\nto keep all the entire history local even if you only want to add to it\nin a normal repository).  Those people who work on the subproject and\ncommunicate with its upstream developers of course need remote entries\nand have to synchronize the subproject with upstream.  But that is\nnot related to the superproject at all.\n\nSo yes, you have different sources but you don't need extra support\nin the subproject implementation for it.\n\n-- \nMartin Waitz\n"},{"id":"43162","messageId":"7viraixeme.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070521211133.GD5412@admingilde.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-24T18:26:01Z","receivedAt":"2007-05-24T18:26:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Martin Waitz <tali@admingilde.org> writes:\n\n> On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n>> Here is one possible idea:\n>> \n>> We could store the GIT_DIR of submodule within the GIT_DIR of the\n>> superproject instead of the submodule directory itself. So instead of:\n>>  /\n>>  /.git\n>>  /subdir\n>>  /subdir/.git\n>> \n>> There would be:\n>>  /\n>>  /.git\n>>  /subdir\n>>  /.git/submodules/submodule-name.git\n>> \n>> This would require changes to the logic how git finds GIT_DIR (which would be\n>> really deep change), but it would provide place to store the submodule data\n>> while the submodule is not being checked out. \n>\n> I agree that we need something like that.\n>\n> We don't have to move the entire subproject.git into the superproject,\n> but we need to have all _referenced_ objects in the .git dir of the\n> superproject.\n>\n> There are several possibilities to do so:\n>\n>  * move the entire .git dir\n>  * move .git/objects\n>  * explicitly copy all referenced objects\n\nI was hoping that we can start from an initial cut that supports\nonly a superproject that had its subprojects in their places\nfrom its initial commit, and did not have to worry about this\nfrom day one, and deal with this kind of \"more advanced\" stuff\nincrementally.  Unfortunately it's more fun to talk about more\nadvanced stuff than starting with small but solid stuff.\n\nAnd we would need to make sure whatever we do as the \"small but\nsolid\" initial round can later support more advanced\narrangements later, so we would need to think about the issues\nnow anyway to a certain degree.\n\nHow about doing something like this, instead?\n\n (1) superproject .gitmodules (in-tree) and .git/config (local\n     repository) use the three-level naming in $gmane/47567.\n     Namely, (1a) .gitmodules says which subdirectory has a\n     checkout of what project, and names the project in\n     logical/abstract terms, not with a URL (e.g. \"kernel26\");\n     (1b) .gitmodules also associates a set of suggested URLs\n     for each of the logical/abstract project name; (1c)\n     .git/config records which project are of interest.\n\n (2) In superproject .git/, we would have a bare repository for\n     each project used by the superproject.\n\n\t.git/subproject/kernel26/{objects,refs,...}\n\n     This is created by making a bare clone from the upstream\n     URL, decided by the user with the help from suggested URL\n     described in the superproject .gitmodules.\n\n     The idea is to use this repository as a long-term\n     subproject state across branch switching.\n\n (3) When we need to check out a revision of superproject whose\n     .gitmodules has \"kernel-src/ -> kernel26\", and when we\n     haven't done so (perhaps we are doing an initial checkout,\n     perhaps we are switching from a different revision of the\n     superproject that did not have \"kernel26\" project at\n     kernel-src/ directory), we rm -f kernel-src/ and then\n     \"git-clone -l -s\" from the repository we keep in (2) to\n     populate kernel-src/ directory.\n\n (4) Before performing the above step (3), we need to make sure\n     we are not losing anything in kernel-src/ if exists.  Three\n     cases plus one:\n\n     (4a) The path kernel-src/ in the old checkout was not a\n     subproject (either it did not exist, it was a blob, or it\n     was a directory with files that are tracked as part of the\n     superproject).  The usual \"don't lose local modification\"\n     rule we use try to carry local changes forward across\n     branch switching, but in this case we shouldn't do so.\n\n     (4b) It has the same logical/abstract project checked out;\n     the commit recorded in the superproject tree may or may not\n     be the same as what its HEAD points at.  In this case we do\n     not have to worry about swapping the git repository at\n     kernel-src/ directory, although we would need to check out\n     the correct revision, and worry about what to do with any\n     local modification (I think the usual \"don't lose local\n     modification but carry them forward\" rule would be Ok in\n     this case).\n\n     (4c) It has a different project checked out; we need to be\n     careful to keep local changes, and also we need to make\n     sure the local changes in this subproject repository are\n     pushed back to (2).  It could be that automated \"git push\"\n     after making sure everything is committed is sufficient and\n     have the user handle failure cases.\n\n     (4d) This applies not just \"before step (3)\", but in cases\n     where we need to replace a checked out subproject directory\n     with something else (e.g. blob or directory that belong to\n     the superproject, or noneness).  We would need to make sure\n     no local change is lost, and the repository is synched up\n     with (2).\n\nI think an arrangement like this would solve \"symlink is a bitch\nfor MinGW\" problem Johannes Sixt brought up today with Sven's\nRFC as well.\n"},{"id":"43165","messageId":"20070524184549.GW942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"7viraixeme.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-24T18:45:49Z","receivedAt":"2007-05-24T18:45:49Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Thu, May 24, 2007 at 11:26:01AM -0700, Junio C Hamano wrote:\n> How about doing something like this, instead?\n> \n>  (1) superproject .gitmodules (in-tree) and .git/config (local\n>      repository) use the three-level naming in $gmane/47567.\n>      Namely, (1a) .gitmodules says which subdirectory has a\n>      checkout of what project, and names the project in\n>      logical/abstract terms, not with a URL (e.g. \"kernel26\");\n>      (1b) .gitmodules also associates a set of suggested URLs\n>      for each of the logical/abstract project name; (1c)\n>      .git/config records which project are of interest.\n\nWhat about the idea of considering any project that is already\npresent to be of interest by default ?\n\n>  (2) In superproject .git/, we would have a bare repository for\n>      each project used by the superproject.\n> \n> \t.git/subproject/kernel26/{objects,refs,...}\n> \n>      This is created by making a bare clone from the upstream\n>      URL, decided by the user with the help from suggested URL\n>      described in the superproject .gitmodules.\n\nDo you mean a \"pure\" clone, i.e., without a working tree,\nbut with separate-remotes?\n\n>      (4b) It has the same logical/abstract project checked out;\n>      the commit recorded in the superproject tree may or may not\n>      be the same as what its HEAD points at.  In this case we do\n>      not have to worry about swapping the git repository at\n>      kernel-src/ directory, although we would need to check out\n>      the correct revision, and worry about what to do with any\n>      local modification (I think the usual \"don't lose local\n>      modification but carry them forward\" rule would be Ok in\n>      this case).\n\nWe may also need to fetch from the remote subproject.\nShould I do this with a \"git fetch\" during the checkout as I do now?\n\nskimo\n"},{"id":"43167","messageId":"7vy7jevyjx.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070524184549.GW942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-24T18:58:26Z","receivedAt":"2007-05-24T18:58:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sven Verdoolaege <skimo@kotnet.org> writes:\n\n> On Thu, May 24, 2007 at 11:26:01AM -0700, Junio C Hamano wrote:\n>> How about doing something like this, instead?\n>> \n>>  (1) superproject .gitmodules (in-tree) and .git/config (local\n>>      repository) use the three-level naming in $gmane/47567.\n>>      Namely, (1a) .gitmodules says which subdirectory has a\n>>      checkout of what project, and names the project in\n>>      logical/abstract terms, not with a URL (e.g. \"kernel26\");\n>>      (1b) .gitmodules also associates a set of suggested URLs\n>>      for each of the logical/abstract project name; (1c)\n>>      .git/config records which project are of interest.\n>\n> What about the idea of considering any project that is already\n> present to be of interest by default ?\n\nYou could do that -- I consider that a minor detail in the\nimplementation.\n\n>>  (2) In superproject .git/, we would have a bare repository for\n>>      each project used by the superproject.\n>> \n>> \t.git/subproject/kernel26/{objects,refs,...}\n>> \n>>      This is created by making a bare clone from the upstream\n>>      URL, decided by the user with the help from suggested URL\n>>      described in the superproject .gitmodules.\n>\n> Do you mean a \"pure\" clone, i.e., without a working tree,\n> but with separate-remotes?\n\nI meant a bare clone without separate remotes.\n\nThe counter-proposal outline essentially says, for the sake of\nsimplicity, \"nuke existing subproject directory whenever we need\nto replace it with something else, and reclone a new/replacement\nsubproject directory every time we need to check it out, after\nmaking sure nothing is lost\".\n\nExcept that having this intermediate repository (a) helps making\nsuch a re-clone extremely cheap \"git clone -l -s -n\", and (b)\nprovides with a place to hold locally committed changes that are\nnot pushed back to the true upstream (you may _never_ push it\nback in the first place).\n\n>>      (4b) It has the same logical/abstract project checked out;\n>>      the commit recorded in the superproject tree may or may not\n>>      be the same as what its HEAD points at.  In this case we do\n>>      not have to worry about swapping the git repository at\n>>      kernel-src/ directory, although we would need to check out\n>>      the correct revision, and worry about what to do with any\n>>      local modification (I think the usual \"don't lose local\n>>      modification but carry them forward\" rule would be Ok in\n>>      this case).\n>\n> We may also need to fetch from the remote subproject.\n> Should I do this with a \"git fetch\" during the checkout as I do now?\n\nIf you are disconnected, you obviously cannot afford to update\n(2) every time you switch branches in the superproject, and even\nif you are connected, updating (2) would not be needed most of\nthe time if what you are doing is switching superproject\nbranches, as long as your last superproject fetch is not very\nmuch more recent than your last subproject fetch.\n\nIf we were to follow the outline in the counter-proposal, I'd\nimagine that update of (2) can happen at any time.  It could be\npart of \"git fetch\" in superprojects, of lazily done when we\nneed to checkout a new revision for a particular subproject, but\nonly if the last time you fetched superproject is more recent\nthan the time you updated (2) for the subproject last time.\n\nOr something like that.  I consider that also a minor detail in\nthe implementation.\n"},{"id":"43169","messageId":"20070524191438.GZ942MdfPADPa@greensroom.kotnet.org","threadId":"8208","inReplyTo":"7vy7jevyjx.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2007-05-24T19:14:38Z","receivedAt":"2007-05-24T19:14:38Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Thu, May 24, 2007 at 11:58:26AM -0700, Junio C Hamano wrote:\n> Sven Verdoolaege <skimo@kotnet.org> writes:\n> > On Thu, May 24, 2007 at 11:26:01AM -0700, Junio C Hamano wrote:\n> >>  (2) In superproject .git/, we would have a bare repository for\n> >>      each project used by the superproject.\n> >> \n> >> \t.git/subproject/kernel26/{objects,refs,...}\n> >> \n> >>      This is created by making a bare clone from the upstream\n> >>      URL, decided by the user with the help from suggested URL\n> >>      described in the superproject .gitmodules.\n> >\n> > Do you mean a \"pure\" clone, i.e., without a working tree,\n> > but with separate-remotes?\n> \n> I meant a bare clone without separate remotes.\n\nWhy without separate remotes?\nIt has been argued before that changes in the subproject\nmay come from different remotes, so the user may want\nto configure extra remotes from which to fetch.\n\n> The counter-proposal outline essentially says, for the sake of\n> simplicity, \"nuke existing subproject directory whenever we need\n> to replace it with something else, and reclone a new/replacement\n> subproject directory every time we need to check it out, after\n> making sure nothing is lost\".\n\nAnd she can't do it in the clone in his working tree if that's\ngoing to get nuked from time to time.\n\n> If we were to follow the outline in the counter-proposal, I'd\n> imagine that update of (2) can happen at any time.  It could be\n> part of \"git fetch\" in superprojects, of lazily done when we\n> need to checkout a new revision for a particular subproject, but\n> only if the last time you fetched superproject is more recent\n> than the time you updated (2) for the subproject last time.\n> \n> Or something like that.  I consider that also a minor detail in\n> the implementation.\n\nBut you still need figure out _what_ to fetch.\nBefore you suggested to just use the default set up by\nclone with separate remotes, but you no longer have that\nin your new proposal.\n\nskimo\n"},{"id":"43173","messageId":"7vk5uyvwgi.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"7viraixeme.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-24T19:43:41Z","receivedAt":"2007-05-24T19:43:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\nSorry, I hate to send \"amend\" message like this, but there are\nsome places I was not clear enough...\n\n> How about doing something like this, instead?\n>\n>  (1) superproject .gitmodules (in-tree) and .git/config (local\n>      repository) use the three-level naming in $gmane/47567.\n>      Namely, (1a) .gitmodules says which subdirectory has a\n>      checkout of what project, and names the project in\n>      logical/abstract terms, not with a URL (e.g. \"kernel26\");\n>      (1b) .gitmodules also associates a set of suggested URLs\n>      for each of the logical/abstract project name; (1c)\n>      .git/config records which project are of interest.\n\n... are of interest, and perhaps which URL to use but that is\nnot necessary, as we can record that in repositories we create\nin (2).\n\n>  (2) In superproject .git/, we would have a bare repository for\n>      each project used by the superproject.\n>\n> \t.git/subproject/kernel26/{objects,refs,...}\n>\n>      This is created by making a bare clone from the upstream\n>      URL, decided by the user with the help from suggested URL\n>      described in the superproject .gitmodules.\n\nThis bare clone probably have its own config that records\nremote.origin.url, which would probably be the same as one of\nthe URL suggested in .gitmodules for many people, but could be\ndifferent.  As to what should happen when the .gitmodules that\ncomes from the upstream changes the set of suggested URLs\nrecorded in there, see $gmane/47621,\n\n>      The idea is to use this repository as a long-term\n>      subproject state across branch switching.\n>\n>  (3) When we need to check out a revision of superproject whose\n>      .gitmodules has \"kernel-src/ -> kernel26\", and when we\n>      haven't done so (perhaps we are doing an initial checkout,\n>      perhaps we are switching from a different revision of the\n>      superproject that did not have \"kernel26\" project at\n>      kernel-src/ directory), we rm -f kernel-src/ and then\n>      \"git-clone -l -s\" from the repository we keep in (2) to\n>      populate kernel-src/ directory.\n\nThe last part of the above should have been:\n\n       we \"rm -fr kernel-src/\" and then \"git-clone -l -s -n\"\n       from the repository we keep in (2).  And then check out\n       the commit that is pointed at by the superproject tree\n       (rather, \"index\").\n\n>  (4) Before performing the above step (3), we need to make sure\n>      we are not losing anything in kernel-src/ if exists.  Three\n>      cases plus one:\n>\n>      (4a) The path kernel-src/ in the old checkout was not a\n>      subproject (either it did not exist, it was a blob, or it\n>      was a directory with files that are tracked as part of the\n>      superproject).  The usual \"don't lose local modification\"\n>      rule we use try to carry local changes forward across\n>      branch switching, but in this case we shouldn't do so.\n\nThe last part of the above should have been:\n\n       ... but in this case we shouldn't even try to carry local\n       changes forward, as there is nowhere to carry them to.\n       Instead we should error out and have the user clean-up\n       the subproject repository (either \"git reset\", or \"git\n       commit && git push\" to stash the change back to\n       repository we prepared in (2)).  We might also want to\n       allow the user to say \"local changes in this subproject\n       checkout does not matter\" by saying \"git checkout -f\n       $commit\" at the superproject level, but I think that is\n       rather dangerous.\n\n>      (4b) It has the same logical/abstract project checked out;\n> ...\n>      (4c) It has a different project checked out; we need to be\n>      careful to keep local changes, and also we need to make\n>      sure the local changes in this subproject repository are\n>      pushed back to (2).  It could be that automated \"git push\"\n>      after making sure everything is committed is sufficient and\n>      have the user handle failure cases.\n>\n>      (4d) This applies not just \"before step (3)\", but in cases\n>      where we need to replace a checked out subproject directory\n>      with something else (e.g. blob or directory that belong to\n>      the superproject, or noneness).  We would need to make sure\n>      no local change is lost, and the repository is synched up\n>      with (2).\n\n... which is the same check and action we would do in case (4c).\n"},{"id":"43178","messageId":"7vy7jeufmn.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070524191438.GZ942MdfPADPa@greensroom.kotnet.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-24T20:32:32Z","receivedAt":"2007-05-24T20:32:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sven Verdoolaege <skimo@kotnet.org> writes:\n\n[side note: I am ignoring your reply-to: liacs.nl as its MTA\nseems to use sorbs that has my ISP's outgoing sender identified\nas spam source; I'll send the bounce to you privately in a\nseparate message.]\n\n> On Thu, May 24, 2007 at 11:58:26AM -0700, Junio C Hamano wrote:\n>> Sven Verdoolaege <skimo@kotnet.org> writes:\n>> > On Thu, May 24, 2007 at 11:26:01AM -0700, Junio C Hamano wrote:\n>> >>  (2) In superproject .git/, we would have a bare repository for\n>> >>      each project used by the superproject.\n>> >> \n>> >> \t.git/subproject/kernel26/{objects,refs,...}\n>> >> \n>> >>      This is created by making a bare clone from the upstream\n>> >>      URL, decided by the user with the help from suggested URL\n>> >>      described in the superproject .gitmodules.\n>> >\n>> > Do you mean a \"pure\" clone, i.e., without a working tree,\n>> > but with separate-remotes?\n>> \n>> I meant a bare clone without separate remotes.\n>\n> Why without separate remotes?\n> It has been argued before that changes in the subproject\n> may come from different remotes, so the user may want\n> to configure extra remotes from which to fetch.\n\nBy different remotes, which do you mean?\n\n (1) .git/subprojects/kernel26/ repository has 'origin'\n     different from any of the suggested URL in .gitmodules, but\n     as far as it is concerned there is one 'origin';\n\nor\n\n (2) it has 'origin' that is what the superproject suggests, but\n     the user locally uses additional repositories to pull and\n     merge from;\n\nIf the former that is not an argument, so I'd assume the\nlatter.  I would say in such a case, you are better off having a\nusual repository to manage the development of subproject part,\nnot grafted to any superproject repository, and handle such\nmerges there (after all, a \"subproject\" should stand on its own\nwithout having any of the superproject stuff).  And treat THAT\nrepository as the 'origin' used in (1) above.  It might be\neasier to use non separate-remote layout in the standalone\nrepository for the subproject, but that is a separate issue.\n\n>> The counter-proposal outline essentially says, for the sake of\n>> simplicity, \"nuke existing subproject directory whenever we need\n>> to replace it with something else, and reclone a new/replacement\n>> subproject directory every time we need to check it out, after\n>> making sure nothing is lost\".\n>\n> And she can't do it in the clone in his working tree if that's\n> going to get nuked from time to time.\n\nAnd she does not have to.  She can do the development/fixes in\n(temporarily) checked out subproject tree, and push it back to\nthe .git/subproject/kernel26/ repository in the superproject\nbefore she leaves (i.e. before branch switching at superproject\nlevel needs to obliterate it).  The change stored in the\n.git/subproject/kernel26/ repository in the superproject can\nfurther be pushed back to its 'origin', be it the true\n\"upstream\", or \"the standalone repository for the subproject\" I\nmentioned above.\n\n> But you still need figure out _what_ to fetch.\n> Before you suggested to just use the default set up by\n> clone with separate remotes, but you no longer have that\n> in your new proposal.\n\nI do remember saying the \"default set up by clone\" but I did not\nmean separate remotes.\n\nWhat is fetched by a bare and non-separate-remote repository vs\na repository that uses separate-remote layout from 'origin' is\nexactly the same -- the difference is only 'pure/bare' layout\nwould use\n\n\tfetch = refs/heads/*:refs/heads/*\n\nwhile separate-remotes would use\n\n\tfetch = refs/heads/*:/refs/remotes/origin/*\n\nSo I do not think the difference matters for our purpose of\nbeing able to check out commits that are referenced in\nsuperproject trees.  As long as we require that the 'origin' for\n\"longer term repository to keep track of the subproject in\nsuperproject\" (aka repository (2) in my message you are\nresponding to) always contain the commit referenced by tree\nobjects in the superproject, which I think is a sensible thing\nto require (otherwise you cannot even clone and checkout the\nwhole superproject), both layout would work equally well.  It's\njust bare/pure layout is easier to understand because it is\nessentially a \"mirror\" of the upstream.\n"},{"id":"43180","messageId":"20070524205535.GP4489@pasky.or.cz","threadId":"8208","inReplyTo":"7vy7jeufmn.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-24T20:55:35Z","receivedAt":"2007-05-24T20:55:35Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Thu, May 24, 2007 at 10:32:32PM CEST, Junio C Hamano wrote:\n> And she does not have to.  She can do the development/fixes in\n> (temporarily) checked out subproject tree, and push it back to\n> the .git/subproject/kernel26/ repository in the superproject\n> before she leaves (i.e. before branch switching at superproject\n> level needs to obliterate it).  The change stored in the\n> .git/subproject/kernel26/ repository in the superproject can\n> further be pushed back to its 'origin', be it the true\n> \"upstream\", or \"the standalone repository for the subproject\" I\n> mentioned above.\n..snip..\n> It's just bare/pure layout is easier to understand because it is\n> essentially a \"mirror\" of the upstream.\n\nI OTOH think that it's less confusing to just keep it the same for all\nthe normal repositories - and you yourself did not rule out the\npossibility to have local changes in the repository, in which case we\ncertainly should use the separate-remotes layout or we go back to last\nyear's refs mess.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"43181","messageId":"20070524205701.GQ4489@pasky.or.cz","threadId":"8208","inReplyTo":"7viraixeme.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-24T20:57:01Z","receivedAt":"2007-05-24T20:57:01Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Thu, May 24, 2007 at 08:26:01PM CEST, Junio C Hamano wrote:\n> How about doing something like this, instead?\n\nThese discussions are spread over so many posts (and especially threads)\nthat it's far beyond me to track it all - I hope I won't repeat\nsomething already debunked.\n\n>  (1) superproject .gitmodules (in-tree) and .git/config (local\n>      repository) use the three-level naming in $gmane/47567.\n>      Namely, (1a) .gitmodules says which subdirectory has a\n>      checkout of what project, and names the project in\n>      logical/abstract terms, not with a URL (e.g. \"kernel26\");\n>      (1b) .gitmodules also associates a set of suggested URLs\n>      for each of the logical/abstract project name; (1c)\n>      .git/config records which project are of interest.\n\nHow do you deal with clashes in subproject names? Until now, several\nindependent projects might live happily in a single repository, this\nbreaks that. When merging disparate projects, you can resolve name\nclashes in .gitmodules, but going back to one of the merged trunks just\nwon't work. It's ugly.\n\nNow, we can just declare that we don't care about this case. This stance\nwouldn't make me comfortable at all, but at least we should make it\nclear that we know about this problem and the users are on their own\nwhen it happens.\n\n>  (2) In superproject .git/, we would have a bare repository for\n>      each project used by the superproject.\n> \n> \t.git/subproject/kernel26/{objects,refs,...}\n> \n>      This is created by making a bare clone from the upstream\n>      URL, decided by the user with the help from suggested URL\n>      described in the superproject .gitmodules.\n> \n>      The idea is to use this repository as a long-term\n>      subproject state across branch switching.\n\nWhen not using subproject aliases, you could just name this after some\nnormalized form of the URL (anything suitable up to an sha1sum of the\nURL :).\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"43182","messageId":"7vps4quecz.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070524205535.GP4489@pasky.or.cz","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-24T20:59:56Z","receivedAt":"2007-05-24T20:59:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> On Thu, May 24, 2007 at 10:32:32PM CEST, Junio C Hamano wrote:\n> ...\n>> It's just bare/pure layout is easier to understand because it is\n>> essentially a \"mirror\" of the upstream.\n>\n> I OTOH think that it's less confusing to just keep it the same for all\n> the normal repositories - and you yourself did not rule out the\n> possibility to have local changes in the repository, in which case we\n> certainly should use the separate-remotes layout or we go back to last\n> year's refs mess.\n\nThat \"local changes in the repository\" will happen in the clone\ncreated in kernel-src/ directory and I do not have any problem\nusing separate remotes there.  I was talking about the refs\nlayout used in .git/subproject/kernel26/, which is a mirror of\nthe upstream and the clone source for that (temporarily checked\nout) repository at kernel-src/ directory.  After all, the\n\"mirror\" is where you would push your local changes back into,\nand it is more common to use non-separate-remote layout (without\neven 'master'->'origin' mapping, hence I had to come up with a\nnew name 'pure', but I realize that what I meant really is a\n'mirror') there.\n"},{"id":"43228","messageId":"f36c4s$ltp$1@sea.gmane.org","threadId":"8208","inReplyTo":"20070524154833.GL5412@admingilde.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-25T10:06:02Z","receivedAt":"2007-05-25T10:06:02Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Martin Waitz wrote:\n\n> On Tue, May 22, 2007 at 09:37:06PM +0200, Jan Hudec wrote:\n\n>> Including the same project several times is indeed interesting. Maybe the\n>> subprojects should be \"light checkouts\" (I believe something like this was\n>> already discussed on the list sometime). Those would be .git dirs, that would\n>> only have HEAD and pointer to another .git dir with everything else.\n> \n> Well, even if they might share a lot of objects they might be included\n> for completely different reasons and so might need to work with\n> different communities (remote entries, branches, etc.).\n> \n> So sharing objects makes sense, sharing the rest of .git is not\n> neccessary.\n\nOne of the final ideas for \"lightweight checkout\" was having in\n.git/config the location of \"true\" $GIT_DIR (or parts of it: \nGIT_INDEX_FILE, GIT_OBJECT_DIRECTORY), and \"shadowing\" the rest\nof \"true $GIT_DIR\" with what is present in .git. It means that\nyou can have .git/index and .git/HEAD, and if you don't find\nappropriate .git/refs/heads/master file you look to \"true $GIT_DIR\".\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"43285","messageId":"20070525201524.GA4493@efreet.light.src","threadId":"8208","inReplyTo":"20070524154833.GL5412@admingilde.org","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-25T20:15:24Z","receivedAt":"2007-05-25T20:15:24Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Thu, May 24, 2007 at 17:48:33 +0200, Martin Waitz wrote:\n> On Tue, May 22, 2007 at 09:37:06PM +0200, Jan Hudec wrote:\n> > > We don't have to move the entire subproject.git into the superproject,\n> > > but we need to have all _referenced_ objects in the .git dir of the\n> > > superproject.\n> > > \n> > > There are several possibilities to do so:\n> > > \n> > >  * move the entire .git dir\n> > >  * move .git/objects\n> > >  * explicitly copy all referenced objects\n> > \n> > I believe we really need entire .git dir. When the superporject checks out\n> > revision which does not reference that subproject, we still need to preserve\n> > not only the objects of subproject, but also the refs and config.\n> \n> but all the other refs do not belong to the superproject.\n> For those who are working on the subproject there are of course a lot\n> of refs which they have to work with, but that can be dealt with\n> outside of the superproject scope.  The subproject is still a normal\n> Git repository, after all.\n> That is, you can have remote entries, branches and what not.\n> But all that is not interesting in the superproject scope.\n> \n> So I thing moving the entire subproject.git into the superproject.git is too\n> much.  The superproject is only interested in the objects and in one\n> ref -- the one stored inside its tree.\n\nNo, the way I mean it the subproject and superproject don't share a single\nbit. The subproject.git dir is subdirectory of superproject.git, but has no\nthing in common with it.\n\n> > > I have some experimental code to configure a per-subproject directory\n> > > in the superproject/.git as alternate object store for the submodule\n> > > to make the last two solutions possible.  Perhaps I should dig it out again\n> > > and adapt it to current git.\n\nAh. My bad. Didn't notice this. I do NOT want to share any objects between\nsubproject and superproject. At least not unless the user explicitely asks\nfor that, which might make sense if the subproject was carved out of the\nsuperproject.\n\n> > > If there is a 1:1 relationship between subproject and object store then\n> > > even efficient fsck and repack/prune are possible for the submodule without\n> > > loosing objects.\n> > > But such a 1:1 relationship is bad when you move subprojects to another\n> > > location (or include the same subproject several times in different\n> > > locations of the tree).\n> > > Perhaps the user should be able to choose which one he wants.\n> > \n> > That's why there should be the extra level of indirection using .gitmodules.\n> > It should map the directory name to the object store name, so you can\n> > relocate the subproject.\n> > \n> > Including the same project several times is indeed interesting. Maybe the\n> > subprojects should be \"light checkouts\" (I believe something like this was\n> > already discussed on the list sometime). Those would be .git dirs, that would\n> > only have HEAD and pointer to another .git dir with everything else.\n> \n> Well, even if they might share a lot of objects they might be included\n> for completely different reasons and so might need to work with\n> different communities (remote entries, branches, etc.).\n> \n> So sharing objects makes sense, sharing the rest of .git is not\n> neccessary.\n\nNo, I didn't mean the subproject and superproject would share anything.\nThe case I talk about is if project foo has subdirs A and B and they both\ncontain (different revisions of) the same subproject. The .gitmodules\ndefinition is:\n    [submodule \"A\"]\n    name=bar\n    [submodule \"B\"]\n    name=bar\n\nIn such case A/.git and B/.git can't both be symlinks to\n.git/subprojects/bar.git, because they have different HEAD, but everything\nelse should be defined by .git/subprojects/bar.git\n\n> > > I think it will be _very_ common to store super and subprojects in\n> > > related locations.  First to be independent from third-party servers\n> > > while working on the superproject.\n> > > Second (and I think more important) because many times there will\n> > > be superproject related adaptations in the subproject.  Yes they\n> > > are independent, and exactly for that reason the subproject upstream\n> > > maintainers may not take every change which is needed to satisfy the\n> > > superproject.  We _now_ see that in all Linux distributions already.\n> > > So when you use superprojects to integrate several independent projects,\n> > > then the superproject maintainer/administrator should really keep a\n> > > clone of all subprojects handy on his site.\n> > \n> > Yes, repositories with distribution-specific patches will add a large class\n> > of cases requiring multiple sources support.\n> \n> You don't really need multiple sources for it.\n> The subproject contains both upstream and local changes, but I think\n\nUpstream + local is not the interesting case. Multiple upstreams is.\n\n> it makes sense to keep the entire object store local (the same way\n> to keep all the entire history local even if you only want to add to it\n> in a normal repository).  Those people who work on the subproject and\n> communicate with its upstream developers of course need remote entries\n> and have to synchronize the subproject with upstream.  But that is\n> not related to the superproject at all.\n> \n> So yes, you have different sources but you don't need extra support\n> in the subproject implementation for it.\n\nWell, if the subproject is not auto-fetched, there's no need for extra\nsupport. But if there is auto-fetch, it should be aware of possibility to\nhave multiple upstreams.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"43286","messageId":"20070525203505.GB4493@efreet.light.src","threadId":"8208","inReplyTo":"7viraixeme.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-25T20:35:05Z","receivedAt":"2007-05-25T20:35:05Z","isPatch":true,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Thu, May 24, 2007 at 11:26:01 -0700, Junio C Hamano wrote:\n> Martin Waitz <tali@admingilde.org> writes:\n> > On Mon, May 21, 2007 at 06:59:38PM +0200, Jan Hudec wrote:\n> [...]\n> \n> I was hoping that we can start from an initial cut that supports\n> only a superproject that had its subprojects in their places\n> from its initial commit, and did not have to worry about this\n> from day one, and deal with this kind of \"more advanced\" stuff\n> incrementally.  Unfortunately it's more fun to talk about more\n> advanced stuff than starting with small but solid stuff.\n> \n> And we would need to make sure whatever we do as the \"small but\n> solid\" initial round can later support more advanced\n> arrangements later, so we would need to think about the issues\n> now anyway to a certain degree.\n> \n> How about doing something like this, instead?\n\nIt's almost exactly what I had in mind, except much better described, so\nI definitely support this. It seems that it can work.\n\n>  (1) superproject .gitmodules (in-tree) and .git/config (local\n>      repository) use the three-level naming in $gmane/47567.\n>      Namely, (1a) .gitmodules says which subdirectory has a\n>      checkout of what project, and names the project in\n>      logical/abstract terms, not with a URL (e.g. \"kernel26\");\n>      (1b) .gitmodules also associates a set of suggested URLs\n>      for each of the logical/abstract project name; (1c)\n>      .git/config records which project are of interest.\n> \n>  (2) In superproject .git/, we would have a bare repository for\n>      each project used by the superproject.\n> \n> \t.git/subproject/kernel26/{objects,refs,...}\n> \n>      This is created by making a bare clone from the upstream\n>      URL, decided by the user with the help from suggested URL\n>      described in the superproject .gitmodules.\n> \n>      The idea is to use this repository as a long-term\n>      subproject state across branch switching.\n> \n>  (3) When we need to check out a revision of superproject whose\n>      .gitmodules has \"kernel-src/ -> kernel26\", and when we\n>      haven't done so (perhaps we are doing an initial checkout,\n>      perhaps we are switching from a different revision of the\n>      superproject that did not have \"kernel26\" project at\n>      kernel-src/ directory), we rm -f kernel-src/ and then\n>      \"git-clone -l -s\" from the repository we keep in (2) to\n>      populate kernel-src/ directory.\n\nIf the \"clone\" could also share the refs, config and everything except HEAD,\nit would make it completely (or almost so) transparent to the user. Making it\nnon-transparent will work well enough though and should not require any new\nchanges.\n\nThe problem is, that than the HEAD could get out of sync with the refs\n(because they are linked from other repo), so it would have to remember both\nthe commit name and the symbolic ref. I would behave as symref only if the\ncommit name in it and the target are the same and as hard ref otherwise.\n\n>  (4) Before performing the above step (3), we need to make sure\n>      we are not losing anything in kernel-src/ if exists.  Three\n>      cases plus one:\n> \n>      (4a) The path kernel-src/ in the old checkout was not a\n>      subproject (either it did not exist, it was a blob, or it\n>      was a directory with files that are tracked as part of the\n>      superproject).  The usual \"don't lose local modification\"\n>      rule we use try to carry local changes forward across\n>      branch switching, but in this case we shouldn't do so.\n> \n>      (4b) It has the same logical/abstract project checked out;\n>      the commit recorded in the superproject tree may or may not\n>      be the same as what its HEAD points at.  In this case we do\n>      not have to worry about swapping the git repository at\n>      kernel-src/ directory, although we would need to check out\n>      the correct revision, and worry about what to do with any\n>      local modification (I think the usual \"don't lose local\n>      modification but carry them forward\" rule would be Ok in\n>      this case).\n> \n>      (4c) It has a different project checked out; we need to be\n>      careful to keep local changes, and also we need to make\n>      sure the local changes in this subproject repository are\n>      pushed back to (2).  It could be that automated \"git push\"\n>      after making sure everything is committed is sufficient and\n>      have the user handle failure cases.\n> \n>      (4d) This applies not just \"before step (3)\", but in cases\n>      where we need to replace a checked out subproject directory\n>      with something else (e.g. blob or directory that belong to\n>      the superproject, or noneness).  We would need to make sure\n>      no local change is lost, and the repository is synched up\n>      with (2).\n> \n> I think an arrangement like this would solve \"symlink is a bitch\n> for MinGW\" problem Johannes Sixt brought up today with Sven's\n> RFC as well.\n\nIt would also solve (rare) case when for some reason the same subproject\nshould be checked out twice (different revisions).\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"43289","messageId":"7vwsywpqaj.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"20070525203505.GB4493@efreet.light.src","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-25T21:05:40Z","receivedAt":"2007-05-25T21:05:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jan Hudec <bulb@ucw.cz> writes:\n\n> It would also solve (rare) case when for some reason the same subproject\n> should be checked out twice (different revisions).\n\nI have a feeling that you are equating two subprojects that\nhappens to have the same upstream URL the same, and if that is\nthe case I think that is a mistake.\n\nIf you were doing an efficient cgi script that renders history\nof git managed projects, binding git as its subproject, and that\nsystem can be built with either 'maint' (i.e. 1.5.2 series) or\n'master' (i.e. ultrastable WIP towards 1.5.3), even though they\nboth might come from git://git.kernel.org/pub/scm/git/git.git/,\nI think they should be registered as two separate logical\nsubprojects.\n\nThe .gitmodules file might have:\n\n\t[module \"git-maint\"]\n        \tpath = git-stale/\n        \turl = git://git.kernel.org/pub/scm/git/git.git/\n                ;; branch = maint\n\n\t[module \"git-master\"]\n        \tpath = git-stable/\n        \turl = git://git.kernel.org/pub/scm/git/git.git/\n                ;; branch = master\n\nand two paths (git-stale/ and git-stable/) in the superproject\ntree would have commit object names from the named branches.\n"},{"id":"43293","messageId":"46575220.2070604@midwinter.com","threadId":"8208","inReplyTo":"7vwsywpqaj.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-05-25T21:16:16Z","receivedAt":"2007-05-25T21:16:16Z","isPatch":true,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> If you were doing an efficient cgi script that renders history\n> of git managed projects, binding git as its subproject, and that\n> system can be built with either 'maint' (i.e. 1.5.2 series) or\n> 'master' (i.e. ultrastable WIP towards 1.5.3), even though they\n> both might come from git://git.kernel.org/pub/scm/git/git.git/,\n> I think they should be registered as two separate logical\n> subprojects.\n>   \n\nI agree strongly with this, and it's another good reason that we have to \nbe able to use something other than the URL as the key to look up a \nsubproject's repository location. If you use the URL it is impossible to \ndifferentiate the two subprojects in this case.\n\n-Steve\n"},{"id":"43300","messageId":"7vsl9kpn9b.fsf@assigned-by-dhcp.cox.net","threadId":"8208","inReplyTo":"46575220.2070604@midwinter.com","subject":"Re: [PATCH 07/16] git-read-tree: take --submodules option","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-25T22:11:12Z","receivedAt":"2007-05-25T22:11:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Steven Grimm <koreth@midwinter.com> writes:\n\n> Junio C Hamano wrote:\n>> If you were doing an efficient cgi script that renders history\n>> of git managed projects, binding git as its subproject, and that\n>> system can be built with either 'maint' (i.e. 1.5.2 series) or\n>> 'master' (i.e. ultrastable WIP towards 1.5.3), even though they\n>> both might come from git://git.kernel.org/pub/scm/git/git.git/,\n>> I think they should be registered as two separate logical\n>> subprojects.\n>\n> I agree strongly with this, and it's another good reason that we have\n> to be able to use something other than the URL as the key to look up a\n> subproject's repository location. If you use the URL it is impossible\n> to differentiate the two subprojects in this case.\n\nHeh, you do not have to rub it in ;-)  I already agreed that\nyour three-level arrangement is easier to work with.\n"}]}