{"thread":{"id":"7643","subject":"[PATCH 0/3] resend/cleanup: Fix up subproject support","startedAt":"2007-04-13T16:23:39Z","lastAt":"2007-04-13T16:26:04Z","messageCount":4,"participants":["Linus Torvalds"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"39297","messageId":"Pine.LNX.4.64.0704130919070.28042@woody.linux-foundation.org","threadId":"7643","inReplyTo":null,"subject":"[PATCH 0/3] resend/cleanup: Fix up subproject support","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-04-13T16:23:39Z","receivedAt":"2007-04-13T16:23:39Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThis series of three patches is a *replacement* for the patch series of \ntwo patches (plus one-liner fixup) I sent yesterday.\n\nIt fixes the issue I noted with \"git status\" incorrectly claiming that a \nnon-checked out subproject wasn't clean - that was just a total thinko in \nthe code (we were checking the filesystem mode against S_IFDIRLNK, which \nobviously cannot work, since S_IFDIRLINK is a git-internal state, not a \nfilesystem state).\n\nIt then re-sends the two patches on top of that, with the fix for checking \nout superprojects (we should *not* mess up any existing subproject \ndirectories, certainly not remove them - if we already have a directory in \nthe place where we now want a subproject, we should leave it well alone!)\n\nIf you already applied the patches from yesterday (and my small fix), you \nalready have the two latter ones - the only reason I added 1/3 to the \nfront of the patch-queue is that it really is a fix, and it makes the \ncommit commentary about a remaining bug in the patch I sent out yesterday \ngo away.\n\n\t\tLinus\n"},{"id":"39298","messageId":"Pine.LNX.4.64.0704130923440.28042@woody.linux-foundation.org","threadId":"7643","inReplyTo":"Pine.LNX.4.64.0704130919070.28042@woody.linux-foundation.org","subject":"[PATCH 1/3] Fix gitlink index entry filesystem matching","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-04-13T16:24:13Z","receivedAt":"2007-04-13T16:24:13Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThe code to match up index entries with the filesystem was stupidly\nbroken.  We shouldn't compare the filesystem stat() information with\nS_IFDIRLNK, since that's purely a git-internal value, and not what the\nfilesystem uses (on the filesystem, it's just a regular directory).\n\nAlso, don't bother to make the stat() time comparisons etc for DIRLNK\nentries in ce_match_stat_basic(), since we do an exact match for these\nthings, and the hints in the stat data simply doesn't matter.\n\nThis fixes \"git status\" with submodules that haven't been checked out in\nthe supermodule.\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n read-cache.c |    8 ++++----\n 1 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/read-cache.c b/read-cache.c\nindex 4040fac..72d7d7c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -123,9 +123,9 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)\n \t\tif (ce_compare_link(ce, xsize_t(st->st_size)))\n \t\t\treturn DATA_CHANGED;\n \t\tbreak;\n-\tcase S_IFDIRLNK:\n-\t\t/* No need to do anything, we did the exact compare in \"match_stat_basic\" */\n-\t\tbreak;\n+\tcase S_IFDIR:\n+\t\tif (S_ISDIRLNK(ntohl(ce->ce_mode)))\n+\t\t\treturn 0;\n \tdefault:\n \t\treturn TYPE_CHANGED;\n \t}\n@@ -156,7 +156,7 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)\n \t\t\tchanged |= TYPE_CHANGED;\n \t\telse if (ce_compare_gitlink(ce))\n \t\t\tchanged |= DATA_CHANGED;\n-\t\tbreak;\n+\t\treturn changed;\n \tdefault:\n \t\tdie(\"internal error: ce_mode is %o\", ntohl(ce->ce_mode));\n \t}\n-- \n1.5.1.1.786.gdc49a-dirty\n"},{"id":"39299","messageId":"Pine.LNX.4.64.0704130924160.28042@woody.linux-foundation.org","threadId":"7643","inReplyTo":"Pine.LNX.4.64.0704130919070.28042@woody.linux-foundation.org","subject":"[PATCH 2/3] Teach git list-objects logic to not follow gitlinks","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-04-13T16:25:01Z","receivedAt":"2007-04-13T16:25:01Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThis allows us to pack superprojects and thus clone them (but not yet\ncheck them out on the receiving side.. That's the next patch)\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n list-objects.c |   34 ++++++++++++++++++++++++++++++++++\n 1 files changed, 34 insertions(+), 0 deletions(-)\n\ndiff --git a/list-objects.c b/list-objects.c\nindex 2ba2c95..310f8d3 100644\n--- a/list-objects.c\n+++ b/list-objects.c\n@@ -25,6 +25,37 @@ static void process_blob(struct rev_info *revs,\n \tadd_object(obj, p, path, name);\n }\n \n+/*\n+ * Processing a gitlink entry currently does nothing, since\n+ * we do not recurse into the subproject.\n+ *\n+ * We *could* eventually add a flag that actually does that,\n+ * which would involve:\n+ *  - is the subproject actually checked out?\n+ *  - if so, see if the subproject has already been added\n+ *    to the alternates list, and add it if not.\n+ *  - process the commit (or tag) the gitlink points to\n+ *    recursively.\n+ *\n+ * However, it's unclear whether there is really ever any\n+ * reason to see superprojects and subprojects as such a\n+ * \"unified\" object pool (potentially resulting in a totally\n+ * humongous pack - avoiding which was the whole point of\n+ * having gitlinks in the first place!).\n+ *\n+ * So for now, there is just a note that we *could* follow\n+ * the link, and how to do it. Whether it necessarily makes\n+ * any sense what-so-ever to ever do that is another issue.\n+ */\n+static void process_gitlink(struct rev_info *revs,\n+\t\t\t    const unsigned char *sha1,\n+\t\t\t    struct object_array *p,\n+\t\t\t    struct name_path *path,\n+\t\t\t    const char *name)\n+{\n+\t/* Nothing to do */\n+}\n+\n static void process_tree(struct rev_info *revs,\n \t\t\t struct tree *tree,\n \t\t\t struct object_array *p,\n@@ -56,6 +87,9 @@ static void process_tree(struct rev_info *revs,\n \t\t\tprocess_tree(revs,\n \t\t\t\t     lookup_tree(entry.sha1),\n \t\t\t\t     p, &me, entry.path);\n+\t\telse if (S_ISDIRLNK(entry.mode))\n+\t\t\tprocess_gitlink(revs, entry.sha1,\n+\t\t\t\t\tp, &me, entry.path);\n \t\telse\n \t\t\tprocess_blob(revs,\n \t\t\t\t     lookup_blob(entry.sha1),\n-- \n1.5.1.1.786.gdc49a-dirty\n"},{"id":"39300","messageId":"Pine.LNX.4.64.0704130925040.28042@woody.linux-foundation.org","threadId":"7643","inReplyTo":"Pine.LNX.4.64.0704130919070.28042@woody.linux-foundation.org","subject":"[PATCH 3/3] Teach \"git-read-tree -u\" to check out submodules as a directory","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-04-13T16:26:04Z","receivedAt":"2007-04-13T16:26:04Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThis actually allows us to check out a supermodule after cloning, although \nthe submodules themselves will obviously not be checked out, and will just \nbe empty directories.\n\nChecking out the submodules will be up to higher levels - we may not even \nwant to!\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n entry.c |   45 ++++++++++++++++++++++++++++++++-------------\n 1 files changed, 32 insertions(+), 13 deletions(-)\n\ndiff --git a/entry.c b/entry.c\nindex d72f811..50ffae4 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -62,26 +62,33 @@ static int create_file(const char *path, unsigned int mode)\n \treturn open(path, O_WRONLY | O_CREAT | O_EXCL, mode);\n }\n \n+static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned long *size)\n+{\n+\tenum object_type type;\n+\tvoid *new = read_sha1_file(ce->sha1, &type, size);\n+\n+\tif (new) {\n+\t\tif (type == OBJ_BLOB)\n+\t\t\treturn new;\n+\t\tfree(new);\n+\t}\n+\treturn NULL;\n+}\n+\n static int write_entry(struct cache_entry *ce, char *path, struct checkout *state, int to_tempfile)\n {\n \tint fd;\n-\tvoid *new;\n-\tunsigned long size;\n \tlong wrote;\n-\tenum object_type type;\n \n-\tnew = read_sha1_file(ce->sha1, &type, &size);\n-\tif (!new || type != OBJ_BLOB) {\n-\t\tif (new)\n-\t\t\tfree(new);\n-\t\treturn error(\"git-checkout-index: unable to read sha1 file of %s (%s)\",\n-\t\t\tpath, sha1_to_hex(ce->sha1));\n-\t}\n \tswitch (ntohl(ce->ce_mode) & S_IFMT) {\n-\t\tchar *buf;\n-\t\tunsigned long nsize;\n+\t\tchar *buf, *new;\n+\t\tunsigned long size, nsize;\n \n \tcase S_IFREG:\n+\t\tnew = read_blob_entry(ce, path, &size);\n+\t\tif (!new)\n+\t\t\treturn error(\"git-checkout-index: unable to read sha1 file of %s (%s)\",\n+\t\t\t\tpath, sha1_to_hex(ce->sha1));\n \t\tif (to_tempfile) {\n \t\t\tstrcpy(path, \".merge_file_XXXXXX\");\n \t\t\tfd = mkstemp(path);\n@@ -111,6 +118,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat\n \t\t\treturn error(\"git-checkout-index: unable to write file %s\", path);\n \t\tbreak;\n \tcase S_IFLNK:\n+\t\tnew = read_blob_entry(ce, path, &size);\n+\t\tif (!new)\n+\t\t\treturn error(\"git-checkout-index: unable to read sha1 file of %s (%s)\",\n+\t\t\t\tpath, sha1_to_hex(ce->sha1));\n \t\tif (to_tempfile || !has_symlinks) {\n \t\t\tif (to_tempfile) {\n \t\t\t\tstrcpy(path, \".merge_link_XXXXXX\");\n@@ -136,8 +147,13 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat\n \t\t\t\t\t\t \"symlink %s (%s)\", path, strerror(errno));\n \t\t}\n \t\tbreak;\n+\tcase S_IFDIRLNK:\n+\t\tif (to_tempfile)\n+\t\t\treturn error(\"git-checkout-index: cannot create temporary subproject %s\", path);\n+\t\tif (mkdir(path, 0777) < 0)\n+\t\t\treturn error(\"git-checkout-index: cannot create subproject directory %s\", path);\n+\t\tbreak;\n \tdefault:\n-\t\tfree(new);\n \t\treturn error(\"git-checkout-index: unknown file mode for %s\", path);\n \t}\n \n@@ -179,6 +195,9 @@ int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath)\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\tif (!state->force)\n \t\t\t\treturn error(\"%s is a directory\", path);\n \t\t\tremove_subtree(path);\n-- \n1.5.1.1.786.gdc49a-dirty\n"}]}