{"thread":{"id":"17308","subject":"[RFC/PATCH v3 2/3] sha1_file: prepare for adding alternates on demand","startedAt":"2009-01-22T21:17:48Z","lastAt":"2009-01-24T20:02:39Z","messageCount":19,"participants":["Lars Hjemli","Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":3},"messages":[{"id":"101564","messageId":"1232659071-14401-1-git-send-email-hjemli@gmail.com","threadId":"17308","inReplyTo":null,"subject":"[RFC/PATCH v3 0/3] Add support for `git archive --submodules`","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-22T21:17:48Z","receivedAt":"2009-01-22T21:17:48Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This series teaches read_tree_recursive() how to traverse gitlink entries\nwhen explicitly instructed to do so (by the return value from the provided\ncallback function) and then uses this functionallity in git-archive to\nimplement a basic --submodules option (as suggested by RenÃ© in\nhttp://thread.gmane.org/gmane.comp.version-control.git/106167/focus=106235).\n\nThe commit message of the third patch has some suggestions on how the new\nfeature may be extended to support more use cases - hopefully this will\ncover the issues mentioned by Johannes and Junio in the same thread.\n\nLars Hjemli (3):\n  tree.c: teach read_tree_recursive how to traverse gitlink entries\n  sha1_file: prepare for adding alternates on demand\n  archive.c: add basic support for submodules\n\n Documentation/git-archive.txt |    3 +\n archive.c                     |   53 ++++++++++++++++++-\n archive.h                     |    1 +\n builtin-ls-tree.c             |    9 +---\n cache.h                       |    1 +\n merge-recursive.c             |    2 +-\n sha1_file.c                   |   40 +++++++++-----\n t/t5001-archive-submodules.sh |  121 +++++++++++++++++++++++++++++++++++++++++\n tree.c                        |   28 ++++++++++\n 9 files changed, 236 insertions(+), 22 deletions(-)\n create mode 100755 t/t5001-archive-submodules.sh\n"},{"id":"101565","messageId":"1232659071-14401-2-git-send-email-hjemli@gmail.com","threadId":"17308","inReplyTo":"1232659071-14401-1-git-send-email-hjemli@gmail.com","subject":"[RFC/PATCH v3 1/3] tree.c: teach read_tree_recursive how to traverse gitlink entries","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-22T21:17:49Z","receivedAt":"2009-01-22T21:17:49Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"When the callback function invoked from read_tree_recursive() returns\n`READ_TREE_RECURSIVE` for a gitlink entry, the traversal will now\ncontinue into the tree connected to the gitlinked commit. It is the\nresponsibility of the callback function to somehow make the gitlinked\ncommit (and corresponding tree/blob) objects available, possibly by\ninserting the submodule object database as an alternate odb.\n\nAlso, all existing callback function has been updated to only return\nREAD_TREE_RECURSIVE for directory entries, so this patch should not\nintroduce any changes to current behavior.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n archive.c         |    2 +-\n builtin-ls-tree.c |    9 ++-------\n merge-recursive.c |    2 +-\n tree.c            |   28 ++++++++++++++++++++++++++++\n 4 files changed, 32 insertions(+), 9 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 9ac455d..e6de039 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -132,7 +132,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,\n \t\terr = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);\n \t\tif (err)\n \t\t\treturn err;\n-\t\treturn READ_TREE_RECURSIVE;\n+\t\treturn (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);\n \t}\n \n \tbuffer = sha1_file_to_archive(path_without_prefix, sha1, mode,\ndiff --git a/builtin-ls-tree.c b/builtin-ls-tree.c\nindex 5b63e6e..fca4631 100644\n--- a/builtin-ls-tree.c\n+++ b/builtin-ls-tree.c\n@@ -68,13 +68,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,\n \t\t *\n \t\t * Something similar to this incomplete example:\n \t\t *\n-\t\tif (show_subprojects(base, baselen, pathname)) {\n-\t\t\tstruct child_process ls_tree;\n-\n-\t\t\tls_tree.dir = base;\n-\t\t\tls_tree.argv = ls-tree;\n-\t\t\tstart_command(&ls_tree);\n-\t\t}\n+\t\tif (show_subprojects(base, baselen, pathname))\n+\t\t\tretval = READ_TREE_RECURSIVE;\n \t\t *\n \t\t */\n \t\ttype = commit_type;\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex b97026b..ee853b9 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -237,7 +237,7 @@ static int save_files_dirs(const unsigned char *sha1,\n \t\tstring_list_insert(newpath, &o->current_file_set);\n \tfree(newpath);\n \n-\treturn READ_TREE_RECURSIVE;\n+\treturn (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);\n }\n \n static int get_files_dirs(struct merge_options *o, struct tree *tree)\ndiff --git a/tree.c b/tree.c\nindex 03e782a..dfe4d5f 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -131,6 +131,34 @@ int read_tree_recursive(struct tree *tree,\n \t\t\tif (retval)\n \t\t\t\treturn -1;\n \t\t\tcontinue;\n+\t\t} else if (S_ISGITLINK(entry.mode)) {\n+\t\t\tint retval;\n+\t\t\tstruct strbuf path;\n+\t\t\tunsigned int entrylen;\n+\t\t\tstruct commit *commit;\n+\n+\t\t\tentrylen = tree_entry_len(entry.path, entry.sha1);\n+\t\t\tstrbuf_init(&path, baselen + entrylen + 1);\n+\t\t\tstrbuf_add(&path, base, baselen);\n+\t\t\tstrbuf_add(&path, entry.path, entrylen);\n+\t\t\tstrbuf_addch(&path, '/');\n+\n+\t\t\tcommit = lookup_commit(entry.sha1);\n+\t\t\tif (!commit)\n+\t\t\t\tdie(\"Commit %s in submodule path %s not found\",\n+\t\t\t\t    sha1_to_hex(entry.sha1), path.buf);\n+\n+\t\t\tif (parse_commit(commit))\n+\t\t\t\tdie(\"Invalid commit %s in submodule path %s\",\n+\t\t\t\t    sha1_to_hex(entry.sha1), path.buf);\n+\n+\t\t\tretval = read_tree_recursive(commit->tree,\n+\t\t\t\t\t\t     path.buf, path.len,\n+\t\t\t\t\t\t     stage, match, fn, context);\n+\t\t\tstrbuf_release(&path);\n+\t\t\tif (retval)\n+\t\t\t\treturn -1;\n+\t\t\tcontinue;\n \t\t}\n \t}\n \treturn 0;\n-- \n1.6.1.150.g5e733b\n"},{"id":"101562","messageId":"1232659071-14401-3-git-send-email-hjemli@gmail.com","threadId":"17308","inReplyTo":"1232659071-14401-2-git-send-email-hjemli@gmail.com","subject":"[RFC/PATCH v3 2/3] sha1_file: prepare for adding alternates on demand","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-22T21:17:50Z","receivedAt":"2009-01-22T21:17:50Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"The new function add_alt_odb() can be used to add alternate object\ndatabases dynamically (i.e. after parsing of objects/info/alternates).\nIt will be used by git-archive to implement inclusion of submodules\nby adding submodule object databases during tree traversal.\n\nTo make the function usable from call-sites which doesn't require the\nadd_alt_odb() to succeed, it takes a 'quiet' parameter which is passed\non to the underlying alt-odb-related functions.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n cache.h     |    1 +\n sha1_file.c |   40 +++++++++++++++++++++++++++-------------\n 2 files changed, 28 insertions(+), 13 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 8e1af26..ccfad5f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -724,6 +724,7 @@ extern struct alternate_object_database {\n \tchar base[FLEX_ARRAY]; /* more */\n } *alt_odb_list;\n extern void prepare_alt_odb(void);\n+extern int add_alt_odb(char *path, int quiet);\n extern void add_to_alternates_file(const char *reference);\n typedef int alt_odb_fn(struct alternate_object_database *, void *);\n extern void foreach_alt_odb(alt_odb_fn, void*);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex f08493f..8b5540d 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -235,7 +235,7 @@ char *sha1_pack_index_name(const unsigned char *sha1)\n struct alternate_object_database *alt_odb_list;\n static struct alternate_object_database **alt_odb_tail;\n \n-static void read_info_alternates(const char * alternates, int depth);\n+static void read_info_alternates(const char * alternates, int depth, int quiet);\n \n /*\n  * Prepare alternate object database registry.\n@@ -252,7 +252,8 @@ static void read_info_alternates(const char * alternates, int depth);\n  * SHA1, an extra slash for the first level indirection, and the\n  * terminating NUL.\n  */\n-static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)\n+static int link_alt_odb_entry(const char * entry, int len,\n+\t\t\t      const char * relative_base, int depth, int quiet)\n {\n \tconst char *objdir = get_object_directory();\n \tstruct alternate_object_database *ent;\n@@ -285,9 +286,10 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative\n \n \t/* Detect cases where alternate disappeared */\n \tif (!is_directory(ent->base)) {\n-\t\terror(\"object directory %s does not exist; \"\n-\t\t      \"check .git/objects/info/alternates.\",\n-\t\t      ent->base);\n+\t\tif (!quiet)\n+\t\t\terror(\"object directory %s does not exist; \"\n+\t\t\t      \"check .git/objects/info/alternates.\",\n+\t\t\t      ent->base);\n \t\tfree(ent);\n \t\treturn -1;\n \t}\n@@ -312,7 +314,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative\n \tent->next = NULL;\n \n \t/* recursively add alternates */\n-\tread_info_alternates(ent->base, depth + 1);\n+\tread_info_alternates(ent->base, depth + 1, quiet);\n \n \tent->base[pfxlen] = '/';\n \n@@ -320,7 +322,8 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative\n }\n \n static void link_alt_odb_entries(const char *alt, const char *ep, int sep,\n-\t\t\t\t const char *relative_base, int depth)\n+\t\t\t\t const char *relative_base, int depth,\n+\t\t\t\t int quiet)\n {\n \tconst char *cp, *last;\n \n@@ -343,11 +346,12 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,\n \t\t\tcp++;\n \t\tif (last != cp) {\n \t\t\tif (!is_absolute_path(last) && depth) {\n+\t\t\t\tif (!quiet)\n \t\t\t\terror(\"%s: ignoring relative alternate object store %s\",\n \t\t\t\t\t\trelative_base, last);\n \t\t\t} else {\n \t\t\t\tlink_alt_odb_entry(last, cp - last,\n-\t\t\t\t\t\trelative_base, depth);\n+\t\t\t\t\t\trelative_base, depth, quiet);\n \t\t\t}\n \t\t}\n \t\twhile (cp < ep && *cp == sep)\n@@ -356,7 +360,8 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,\n \t}\n }\n \n-static void read_info_alternates(const char * relative_base, int depth)\n+static void read_info_alternates(const char * relative_base, int depth,\n+\t\t\t\t int quiet)\n {\n \tchar *map;\n \tsize_t mapsz;\n@@ -380,7 +385,8 @@ static void read_info_alternates(const char * relative_base, int depth)\n \tmap = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);\n \tclose(fd);\n \n-\tlink_alt_odb_entries(map, map + mapsz, '\\n', relative_base, depth);\n+\tlink_alt_odb_entries(map, map + mapsz, '\\n', relative_base, depth,\n+\t\t\t     quiet);\n \n \tmunmap(map, mapsz);\n }\n@@ -394,7 +400,7 @@ void add_to_alternates_file(const char *reference)\n \tif (commit_lock_file(lock))\n \t\tdie(\"could not close alternates file\");\n \tif (alt_odb_tail)\n-\t\tlink_alt_odb_entries(alt, alt + strlen(alt), '\\n', NULL, 0);\n+\t\tlink_alt_odb_entries(alt, alt + strlen(alt), '\\n', NULL, 0, 0);\n }\n \n void foreach_alt_odb(alt_odb_fn fn, void *cb)\n@@ -418,9 +424,9 @@ void prepare_alt_odb(void)\n \tif (!alt) alt = \"\";\n \n \talt_odb_tail = &alt_odb_list;\n-\tlink_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0);\n+\tlink_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0, 0);\n \n-\tread_info_alternates(get_object_directory(), 0);\n+\tread_info_alternates(get_object_directory(), 0, 0);\n }\n \n static int has_loose_object_local(const unsigned char *sha1)\n@@ -2573,3 +2579,11 @@ int read_pack_header(int fd, struct pack_header *header)\n \t\treturn PH_ERROR_PROTOCOL;\n \treturn 0;\n }\n+\n+int add_alt_odb(char *path, int quiet)\n+{\n+\tint err = link_alt_odb_entry(path, strlen(path), NULL, 0, quiet);\n+\tif (!err)\n+\t\tprepare_packed_git_one(path, 0);\n+\treturn err;\n+}\n-- \n1.6.1.150.g5e733b\n"},{"id":"101563","messageId":"1232659071-14401-4-git-send-email-hjemli@gmail.com","threadId":"17308","inReplyTo":"1232659071-14401-3-git-send-email-hjemli@gmail.com","subject":"[RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-22T21:17:51Z","receivedAt":"2009-01-22T21:17:51Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"The new --submodules option is used to trigger inclusion of checked\nout submodules in the archive.\n\nThe implementation currently does not verify that the submodule has\nbeen registered as 'interesting' in .git/config, neither does it resolve\nthe currently checked out submodule HEAD but instead uses the commit SHA1\nrecorded in the gitlink entry to identify the submodule root tree.\n\nThe plan is to fix these limitations by extending --submodules to allow\ncertain flags/options:\n  a|c|r     include any|checked out|registered submodules\n  H         resolve submodule HEAD to decide which tree to include\n  g:<name>  only include submodules in group <name>\n\nThe syntax would then become '--submodules[=[a|c|r][H][g:<name>]]' and\ngroup membership could be specified in .git/config and/or .gitmodules.\nThe current behavior would then match '--submodules=c' (which might be a\nsensible default when only --submodules is specified).\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/git-archive.txt |    3 +\n archive.c                     |   53 ++++++++++++++++++-\n archive.h                     |    1 +\n t/t5001-archive-submodules.sh |  121 +++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 177 insertions(+), 1 deletions(-)\n create mode 100755 t/t5001-archive-submodules.sh\n\ndiff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt\nindex 41cbf9c..ddfa343 100644\n--- a/Documentation/git-archive.txt\n+++ b/Documentation/git-archive.txt\n@@ -51,6 +51,9 @@ OPTIONS\n \tThis can be any options that the archiver backend understand.\n \tSee next section.\n \n+--submodules::\n+\tInclude all checked out submodules in the archive.\n+\n --remote=<repo>::\n \tInstead of making a tar archive from local repository,\n \tretrieve a tar archive from a remote repository.\ndiff --git a/archive.c b/archive.c\nindex e6de039..1709a01 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -96,6 +96,52 @@ struct archiver_context {\n \twrite_archive_entry_fn_t write_entry;\n };\n \n+/* Given the root directory of a non-bare repository, return the path\n+ * to the corresponding GITDIR, or NULL if not found. The return-value\n+ * is malloc'd by this function and should be free'd by the caller.\n+ */\n+static char *get_gitdir(const char *root)\n+{\n+\tconst char *path, *tmp;\n+\tstruct stat st;\n+\n+\tif (!root)\n+\t\treturn NULL;\n+\n+\tif (root[strlen(root) - 1] == '/')\n+\t\tpath = mkpath(\"%s.git\", root);\n+\telse\n+\t\tpath = mkpath(\"%s/.git\", root);\n+\n+\ttmp = read_gitfile_gently(path);\n+\tif (tmp)\n+\t\tpath = tmp;\n+\n+\tif (stat(path, &st) || !S_ISDIR(st.st_mode))\n+\t\treturn NULL;\n+\treturn xstrdup(path);\n+}\n+\n+/* Return READ_TREE_RECURSIVE if we should recurse into the gitlinked\n+ * repository or 0 if it should be skipped.\n+ */\n+static int recurse_gitlink(struct archiver_args *args, const char *path)\n+{\n+\tchar *gitdir;\n+\tchar *objdir;\n+\n+\tif (!args->submodules)\n+\t\treturn 0;\n+\tgitdir = get_gitdir(path);\n+\tif (!gitdir)\n+\t\treturn 0;\n+\tobjdir = mkpath(\"%s/objects\", gitdir);\n+\tfree(gitdir);\n+\tif (add_alt_odb(objdir, 0))\n+\t\treturn -1;\n+\treturn READ_TREE_RECURSIVE;\n+}\n+\n static int write_archive_entry(const unsigned char *sha1, const char *base,\n \t\tint baselen, const char *filename, unsigned mode, int stage,\n \t\tvoid *context)\n@@ -132,7 +178,8 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,\n \t\terr = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);\n \t\tif (err)\n \t\t\treturn err;\n-\t\treturn (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);\n+\t\treturn (S_ISDIR(mode) ? READ_TREE_RECURSIVE :\n+\t\t\t\t\trecurse_gitlink(args, path.buf));\n \t}\n \n \tbuffer = sha1_file_to_archive(path_without_prefix, sha1, mode,\n@@ -255,6 +302,7 @@ static int parse_archive_args(int argc, const char **argv,\n \tconst char *exec = NULL;\n \tint compression_level = -1;\n \tint verbose = 0;\n+\tint submodules = 0;\n \tint i;\n \tint list = 0;\n \tstruct option opts[] = {\n@@ -262,6 +310,8 @@ static int parse_archive_args(int argc, const char **argv,\n \t\tOPT_STRING(0, \"format\", &format, \"fmt\", \"archive format\"),\n \t\tOPT_STRING(0, \"prefix\", &base, \"prefix\",\n \t\t\t\"prepend prefix to each pathname in the archive\"),\n+\t\tOPT_BOOLEAN(0, \"submodules\", &submodules,\n+\t\t\t\"include checked out submodules in the archive\"),\n \t\tOPT__VERBOSE(&verbose),\n \t\tOPT__COMPR('0', &compression_level, \"store only\", 0),\n \t\tOPT__COMPR('1', &compression_level, \"compress faster\", 1),\n@@ -319,6 +369,7 @@ static int parse_archive_args(int argc, const char **argv,\n \targs->verbose = verbose;\n \targs->base = base;\n \targs->baselen = strlen(base);\n+\targs->submodules = submodules;\n \n \treturn argc;\n }\ndiff --git a/archive.h b/archive.h\nindex 0b15b35..aff3fcd 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -11,6 +11,7 @@ struct archiver_args {\n \tconst char **pathspec;\n \tunsigned int verbose : 1;\n \tint compression_level;\n+\tint submodules;\n };\n \n typedef int (*write_archive_fn_t)(struct archiver_args *);\ndiff --git a/t/t5001-archive-submodules.sh b/t/t5001-archive-submodules.sh\nnew file mode 100755\nindex 0000000..6471984\n--- /dev/null\n+++ b/t/t5001-archive-submodules.sh\n@@ -0,0 +1,121 @@\n+#!/bin/sh\n+\n+test_description='git archive can include submodule content'\n+\n+. ./test-lib.sh\n+\n+add_file()\n+{\n+\tgit add $1 &&\n+\tgit commit -m \"added $1\"\n+}\n+\n+add_submodule()\n+{\n+\tmkdir $1 && (\n+\t\tcd $1 &&\n+\t\tgit init &&\n+\t\techo \"File $2\" >$2 &&\n+\t\tadd_file $2\n+\t) &&\n+\tadd_file $1\n+}\n+\n+test_expect_success 'by default, all submodules are ignored' '\n+\techo \"File 1\" >1 &&\n+\tadd_file 1 &&\n+\tadd_submodule 2 3 &&\n+\tadd_submodule 4 5 &&\n+\tcat <<EOF >expected &&\n+1\n+2/\n+4/\n+EOF\n+\tgit archive HEAD >normal.tar &&\n+\ttar -tf normal.tar >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_debug 'tar -tf normal.tar'\n+\n+test_expect_success 'with --submodules, checked-out submodules are included' '\n+\tcat <<EOF >expected &&\n+1\n+2/\n+2/3\n+4/\n+4/5\n+EOF\n+\tgit archive --submodules HEAD >full.tar &&\n+\ttar -tf full.tar >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_debug 'tar -tf full.tar'\n+\n+test_expect_success 'submodules in submodules are supported' '\n+\t(cd 4 && add_submodule 6 7) &&\n+\tadd_file 4 &&\n+\tcat <<EOF >expected &&\n+1\n+2/\n+2/3\n+4/\n+4/5\n+4/6/\n+4/6/7\n+EOF\n+\tgit archive --submodules HEAD >recursive.tar &&\n+\ttar -tf recursive.tar >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_debug 'tar -tf recursive.tar'\n+\n+test_expect_success 'packed submodules are supported' '\n+\tcat <<EOF >expected &&\n+1\n+2/\n+2/3\n+4/\n+4/5\n+4/6/\n+4/6/7\n+EOF\n+\tmsg=$(cd 2 && git repack -ad && git count-objects) &&\n+\ttest \"$msg\" = \"0 objects, 0 kilobytes\" &&\n+\tgit archive --submodules HEAD >packed.tar &&\n+\ttar -tf packed.tar >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_debug 'tar -tf packed.tar'\n+\n+test_expect_success 'a missing submodule pack triggers an error' '\n+\tfind 2/.git/objects/pack -type f | xargs rm &&\n+\ttest_must_fail git archive --submodules HEAD\n+'\n+\n+test_expect_success 'non-checked out submodules are ignored' '\n+\tcat <<EOF >expected &&\n+1\n+2/\n+4/\n+4/5\n+4/6/\n+4/6/7\n+EOF\n+\trm -rf 2/.git &&\n+\tgit archive --submodules HEAD >partial.tar &&\n+\ttar -tf partial.tar >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_debug 'tar -tf partial.tar'\n+\n+test_expect_success 'missing objects in a submodule triggers an error' '\n+\tfind 4/.git/objects -type f | xargs rm &&\n+\ttest_must_fail git archive --submodules HEAD\n+'\n+\n+test_done\n-- \n1.6.1.150.g5e733b\n"},{"id":"101579","messageId":"alpine.DEB.1.00.0901230041500.3586@pacific.mpi-cbg.de","threadId":"17308","inReplyTo":"1232659071-14401-3-git-send-email-hjemli@gmail.com","subject":"Re: [RFC/PATCH v3 2/3] sha1_file: prepare for adding alternates on demand","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-22T23:43:29Z","receivedAt":"2009-01-22T23:43:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 22 Jan 2009, Lars Hjemli wrote:\n\n> @@ -285,9 +286,10 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative\n>  \n>  \t/* Detect cases where alternate disappeared */\n>  \tif (!is_directory(ent->base)) {\n> -\t\terror(\"object directory %s does not exist; \"\n> -\t\t      \"check .git/objects/info/alternates.\",\n> -\t\t      ent->base);\n> +\t\tif (!quiet)\n> +\t\t\terror(\"object directory %s does not exist; \"\n> +\t\t\t      \"check .git/objects/info/alternates.\",\n> +\t\t\t      ent->base);\n>  \t\tfree(ent);\n>  \t\treturn -1;\n>  \t}\n> [...]\n> @@ -2573,3 +2579,11 @@ int read_pack_header(int fd, struct pack_header *header)\n>  \t\treturn PH_ERROR_PROTOCOL;\n>  \treturn 0;\n>  }\n> +\n> +int add_alt_odb(char *path, int quiet)\n> +{\n> +\tint err = link_alt_odb_entry(path, strlen(path), NULL, 0, quiet);\n> +\tif (!err)\n> +\t\tprepare_packed_git_one(path, 0);\n> +\treturn err;\n> +}\n\nFWIW my concern is not at all addressed.  A future user of add_alt_odb() \n(and possibly your users in rare cases, too) can trigger the error that \nsuggests looking into the alternates.  Leaving the human user puzzled.\n\nCiao,\nDscho\n"},{"id":"101580","messageId":"alpine.DEB.1.00.0901230044300.3586@pacific.mpi-cbg.de","threadId":"17308","inReplyTo":"1232659071-14401-4-git-send-email-hjemli@gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-22T23:44:54Z","receivedAt":"2009-01-22T23:44:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 22 Jan 2009, Lars Hjemli wrote:\n\n> The new --submodules option is used to trigger inclusion of checked out \n> submodules in the archive.\n> \n> The implementation currently does not verify that the submodule has been \n> registered as 'interesting' in .git/config, neither does it resolve the \n> currently checked out submodule HEAD but instead uses the commit SHA1 \n> recorded in the gitlink entry to identify the submodule root tree.\n\nPlease understand that I skipped the rest of the patch.\n\nCiao,\nDscho\n"},{"id":"101675","messageId":"8c5c35580901231035j31484249nf96e0e659b119a2b@mail.gmail.com","threadId":"17308","inReplyTo":"alpine.DEB.1.00.0901230041500.3586@pacific.mpi-cbg.de","subject":"Re: [RFC/PATCH v3 2/3] sha1_file: prepare for adding alternates on demand","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-23T18:35:27Z","receivedAt":"2009-01-23T18:35:27Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Fri, Jan 23, 2009 at 00:43, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On Thu, 22 Jan 2009, Lars Hjemli wrote:\n>> +             if (!quiet)\n>> +                     error(\"object directory %s does not exist; \"\n>> +                           \"check .git/objects/info/alternates.\",\n>> +                           ent->base);\n>\n> FWIW my concern is not at all addressed.  A future user of add_alt_odb()\n> (and possibly your users in rare cases, too) can trigger the error that\n> suggests looking into the alternates.  Leaving the human user puzzled.\n\nIs it the phrasing of the error message that concerns you (when\ninvoked from add_alt_odb())?\n\nIf so, would something like this be ok/better?\n\n>> +             if (!quiet)\n>> +                     error(\"Alternate object directory %s does not exist \",\n>> +                           ent->base);\n\n--\nlarsh\n"},{"id":"101676","messageId":"8c5c35580901231040i380c6458x1a6103cd6f55c479@mail.gmail.com","threadId":"17308","inReplyTo":"alpine.DEB.1.00.0901230044300.3586@pacific.mpi-cbg.de","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-23T18:40:00Z","receivedAt":"2009-01-23T18:40:00Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Fri, Jan 23, 2009 at 00:44, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On Thu, 22 Jan 2009, Lars Hjemli wrote:\n>\n>> The new --submodules option is used to trigger inclusion of checked out\n>> submodules in the archive.\n>>\n>> The implementation currently does not verify that the submodule has been\n>> registered as 'interesting' in .git/config, neither does it resolve the\n>> currently checked out submodule HEAD but instead uses the commit SHA1\n>> recorded in the gitlink entry to identify the submodule root tree.\n>\n> Please understand that I skipped the rest of the patch.\n\nThat's too bad, I hoped on some feedback from you on the part of the\ncommit message which you didn't quote:\n\n>> The plan is to fix these limitations by extending --submodules to allow\n>> certain flags/options:\n>> a|c|r     include any|checked out|registered submodules\n>> H         resolve submodule HEAD to decide which tree to include\n>> g:<name>  only include submodules in group <name>\n>>\n>> The syntax would then become '--submodules[=[a|c|r][H][g:<name>]]' and\n>> group membership could be specified in .git/config and/or .gitmodules.\n>> The current behavior would then match '--submodules=c' (which might be a\n>> sensible default when only --submodules is specified).\n\nWouldn't such an option address your concern about the\nconsistency/semantics of the --submodules operation?\n\n--\nlarsh\n"},{"id":"101681","messageId":"7vzlhhu8qo.fsf@gitster.siamese.dyndns.org","threadId":"17308","inReplyTo":"8c5c35580901231040i380c6458x1a6103cd6f55c479@mail.gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-01-23T19:23:43Z","receivedAt":"2009-01-23T19:23:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lars Hjemli <hjemli@gmail.com> writes:\n\n>>> The plan is to fix these limitations by extending --submodules to allow\n>>> certain flags/options:\n>>> a|c|r     include any|checked out|registered submodules\n>>> H         resolve submodule HEAD to decide which tree to include\n\nWhat do you mean by \"decide\"?  If HEAD exists (iow, the submodule is\nchecked out), the tree of the commit recorded in the superproject's\ngitlink entry is included in the result?\n\nAs I already said before, I doubt it makes much sense in the context of\nthe current git-archive to base the choise on checkout status.\n\nUnless you are extending git-archive and giving it an ability to write out\nthe superproject index or the work tree as an archive, that is.\n\nJust like git-grep lets you grep in the work tree files (limited to paths\nthat appear in the index), or grep in the contents registered to the index\nwhen run with --cached, git-archive could make an archive out of your work\ntree files or your index contents.  Such an extension to git-archive may\nbe quite useful with or without submodules.\n\nIn such mode of operation, because you are dealing with the work tree when\nrun without --cached, it would make sense to say \"Ah, the superproject\nindex wants v1.0 of the submodule, but the work tree has v2.0 of it\nchecked out, and we are writing out the work tree, so let's include v2.0\ninstead\", and as a side effect of deciding which commit's tree to include\nfrom each submodule, it naturally makes sense to exclude submodules that\nare not checked out.\n\nBut otherwise I am not so sure what the point of H option would be.\n"},{"id":"101682","messageId":"alpine.DEB.1.00.0901232054090.21467@intel-tinevez-2-302","threadId":"17308","inReplyTo":"8c5c35580901231035j31484249nf96e0e659b119a2b@mail.gmail.com","subject":"Re: [RFC/PATCH v3 2/3] sha1_file: prepare for adding alternates on demand","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-23T19:54:30Z","receivedAt":"2009-01-23T19:54:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 23 Jan 2009, Lars Hjemli wrote:\n\n> On Fri, Jan 23, 2009 at 00:43, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> > On Thu, 22 Jan 2009, Lars Hjemli wrote:\n> >> +             if (!quiet)\n> >> +                     error(\"object directory %s does not exist; \"\n> >> +                           \"check .git/objects/info/alternates.\",\n> >> +                           ent->base);\n> >\n> > FWIW my concern is not at all addressed.  A future user of add_alt_odb()\n> > (and possibly your users in rare cases, too) can trigger the error that\n> > suggests looking into the alternates.  Leaving the human user puzzled.\n> \n> Is it the phrasing of the error message that concerns you (when\n> invoked from add_alt_odb())?\n> \n> If so, would something like this be ok/better?\n> \n> >> +             if (!quiet)\n> >> +                     error(\"Alternate object directory %s does not exist \",\n> >> +                           ent->base);\n\nThat would almost certainly be better.\n\nCiao,\nDscho\n"},{"id":"101683","messageId":"alpine.DEB.1.00.0901232054360.21467@intel-tinevez-2-302","threadId":"17308","inReplyTo":"8c5c35580901231040i380c6458x1a6103cd6f55c479@mail.gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-23T19:57:55Z","receivedAt":"2009-01-23T19:57:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 23 Jan 2009, Lars Hjemli wrote:\n\n> On Fri, Jan 23, 2009 at 00:44, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> > On Thu, 22 Jan 2009, Lars Hjemli wrote:\n> >\n> >> The new --submodules option is used to trigger inclusion of checked out\n> >> submodules in the archive.\n> >>\n> >> The implementation currently does not verify that the submodule has \n> >> been registered as 'interesting' in .git/config, neither does it \n> >> resolve the currently checked out submodule HEAD but instead uses the \n> >> commit SHA1 recorded in the gitlink entry to identify the submodule \n> >> root tree.\n> >\n> > Please understand that I skipped the rest of the patch.\n> \n> That's too bad, I hoped on some feedback from you on the part of the \n> commit message which you didn't quote:\n\nWell, you ignored my comments, so what do you expect me to do?  Be happy?\n\nThere are two issues there:\n\n- presence of a specific commit object being present in the repository \n  does not necessarily mean that it is reachable by any ref, and therefore \n  can mean that the tree/blob objects are not reachable, because it could \n  be an interrupted fetch; in all of Git, we try to assume that only \n  reachable objects are valid objects.\n\n- presence of a specific commit in the supermodule is a _lousy_ indicator \n  that the user wants to include that submodule in the archive.\n\nUntil both issues are addresse, I will not dance a little song and be \nmerry over this issue.\n\nCiao,\nDscho\n"},{"id":"101687","messageId":"8c5c35580901231215q2be36abbla443975cdbb031f0@mail.gmail.com","threadId":"17308","inReplyTo":"7vzlhhu8qo.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-23T20:15:16Z","receivedAt":"2009-01-23T20:15:16Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Fri, Jan 23, 2009 at 20:23, Junio C Hamano <gitster@pobox.com> wrote:\n> Lars Hjemli <hjemli@gmail.com> writes:\n>\n>>>> The plan is to fix these limitations by extending --submodules to allow\n>>>> certain flags/options:\n>>>> a|c|r     include any|checked out|registered submodules\n>>>> H         resolve submodule HEAD to decide which tree to include\n>\n> What do you mean by \"decide\"?  If HEAD exists (iow, the submodule is\n> checked out), the tree of the commit recorded in the superproject's\n> gitlink entry is included in the result?\n\nNo, when H is specified the tree of the currently checked out\nsubmodule commit would be included (this obviously shouldn't be the\ndefault mode of operation, hence a flag to trigger it if that is what\nthe user wants).\n\n>\n> As I already said before, I doubt it makes much sense in the context of\n> the current git-archive to base the choise on checkout status.\n>\n> Unless you are extending git-archive and giving it an ability to write out\n> the superproject index or the work tree as an archive, that is.\n>\n> Just like git-grep lets you grep in the work tree files (limited to paths\n> that appear in the index), or grep in the contents registered to the index\n> when run with --cached, git-archive could make an archive out of your work\n> tree files or your index contents.  Such an extension to git-archive may\n> be quite useful with or without submodules.\n\nAbsolutely.\n\n>\n> In such mode of operation, because you are dealing with the work tree when\n> run without --cached, it would make sense to say \"Ah, the superproject\n> index wants v1.0 of the submodule, but the work tree has v2.0 of it\n> checked out, and we are writing out the work tree, so let's include v2.0\n> instead\", and as a side effect of deciding which commit's tree to include\n> from each submodule, it naturally makes sense to exclude submodules that\n> are not checked out.\n>\n> But otherwise I am not so sure what the point of H option would be.\n\nI would find the H flag practical for my own usage of submodules. I\nalmost never modify the content of the currently checked out submodule\nbut I often check out a different HEAD than what is registered in the\ngitlink in the superproject (typically due to testing the superproject\nagainst different versions of the submodule). And for such a use case,\nbeing able to create a tarball of my currently checked out state seems\nuseful to me.\n\nAnyways, if we get as far as adding a --submodules option to git\narchive, I believe its default mode should be to archive the\nsuperproject HEAD state together with the gitlink'd state of each\nsubmodule registered in .git/config instead of --submodules=c which is\nwhat this patch implements. But I wanted to get some feedback on this\nplan before trying to implement it.\n\n--\nlarsh\n"},{"id":"101688","messageId":"7vljt1u4pc.fsf@gitster.siamese.dyndns.org","threadId":"17308","inReplyTo":"8c5c35580901231215q2be36abbla443975cdbb031f0@mail.gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-01-23T20:50:55Z","receivedAt":"2009-01-23T20:50:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lars Hjemli <hjemli@gmail.com> writes:\n\n> On Fri, Jan 23, 2009 at 20:23, Junio C Hamano <gitster@pobox.com> wrote:\n>> Lars Hjemli <hjemli@gmail.com> writes:\n>>\n>>>>> The plan is to fix these limitations by extending --submodules to allow\n>>>>> certain flags/options:\n>>>>> a|c|r     include any|checked out|registered submodules\n>>>>> H         resolve submodule HEAD to decide which tree to include\n>>\n>> What do you mean by \"decide\"?  If HEAD exists (iow, the submodule is\n>> checked out), the tree of the commit recorded in the superproject's\n>> gitlink entry is included in the result?\n>\n> No, when H is specified the tree of the currently checked out\n> submodule commit would be included.\n\nThat makes even less sense.  At that point you are mixing a tree with\nrandom state from a work tree, and doing so only for submodules.  If you\nwant a work tree snapshot, it should be a work tree snapshot, and should\nnot be labelled as a snapshot out of a tree object of the superproject.\n\n> I would find the H flag practical for my own usage of submodules. I\n> almost never modify the content of the currently checked out submodule\n> but I often check out a different HEAD than what is registered in the\n> gitlink in the superproject (typically due to testing the superproject\n> against different versions of the submodule). And for such a use case,\n> being able to create a tarball of my currently checked out state seems\n> useful to me.\n\nThat would be more like an enhanced version of \"git archive\" that takes\nthe work tree state, similar to how \"git grep\" operates on the work tree\ntoday.\n\nI agree that would be useful, but I have a moderately strong suspition\nthat your \"H\" hack that includes the work tree state for checked out\nsubmodules into a view that is primarily about the \"tree\" object in the\nsuperproject, without the same \"take from the work tree\" semantics for\npaths in the superproject, is more harmful than being helpful to the users\nin the longer term.  It might be simple to implement, but I do not think\nits semantics can be explained sanely.\n"},{"id":"101691","messageId":"8c5c35580901231315va79d89bu6e323d47a1b3547e@mail.gmail.com","threadId":"17308","inReplyTo":"7vljt1u4pc.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-23T21:15:21Z","receivedAt":"2009-01-23T21:15:21Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Fri, Jan 23, 2009 at 21:50, Junio C Hamano <gitster@pobox.com> wrote:\n> Lars Hjemli <hjemli@gmail.com> writes:\n>> I would find the H flag practical for my own usage of submodules. I\n>> almost never modify the content of the currently checked out submodule\n>> but I often check out a different HEAD than what is registered in the\n>> gitlink in the superproject (typically due to testing the superproject\n>> against different versions of the submodule). And for such a use case,\n>> being able to create a tarball of my currently checked out state seems\n>> useful to me.\n>\n> That would be more like an enhanced version of \"git archive\" that takes\n> the work tree state, similar to how \"git grep\" operates on the work tree\n> today.\n>\n> I agree that would be useful, but I have a moderately strong suspition\n> that your \"H\" hack that includes the work tree state for checked out\n> submodules into a view that is primarily about the \"tree\" object in the\n> superproject, without the same \"take from the work tree\" semantics for\n> paths in the superproject, is more harmful than being helpful to the users\n> in the longer term.  It might be simple to implement, but I do not think\n> its semantics can be explained sanely.\n\nOk. When someone gets the itch for 'git archive --worktree', it would\nbe easy enough to resurrect the idea of including the tree of the\ncurrently checked out HEAD in selected submodules.\n\nDo you think the other options makes any sense, i.e. is it any point\nin me trying to implement this?\n\n--\nlarsh\n"},{"id":"101734","messageId":"8c5c35580901240044y452b465fj94df82fc2b8f7ee9@mail.gmail.com","threadId":"17308","inReplyTo":"alpine.DEB.1.00.0901232054360.21467@intel-tinevez-2-302","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-24T08:44:35Z","receivedAt":"2009-01-24T08:44:35Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Fri, Jan 23, 2009 at 20:57, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> On Fri, 23 Jan 2009, Lars Hjemli wrote:\n>>\n>> That's too bad, I hoped on some feedback from you on the part of the\n>> commit message which you didn't quote:\n>\n> Well, you ignored my comments,\n\nI might have misunderstood your comments, but I certainly didn't\nignore them. I actually tried to come up with a solution that would\nsolve your concerns about which submodules to include in the archive\n(which is why I hoped for some feedback on that proposal).\n\n\n> so what do you expect me to do?  Be happy?\n>\n> There are two issues there:\n>\n> - presence of a specific commit object being present in the repository\n>  does not necessarily mean that it is reachable by any ref, and therefore\n>  can mean that the tree/blob objects are not reachable, because it could\n>  be an interrupted fetch;\n\nThis part I agree with.\n\n\n>  in all of Git, we try to assume that only\n>  reachable objects are valid objects.\n\nI don't think this is true (most git commands accepts their arguments\nas valid objects without verifying if they are reachable from a ref).\nDo you feel it is necessary to perform a reachability check of the\ngitlink'd commit before traversing into a submodule tree?\n\n\n> - presence of a specific commit in the supermodule is a _lousy_ indicator\n>  that the user wants to include that submodule in the archive.\n\nThis is the issue I tried to address with my\n`--submodules=[a|c|r][g:<name>]` proposal in the commit message for\nthis patch. I hoped you would find it interesting, given your comments\nin http://thread.gmane.org/gmane.comp.version-control.git/106167/focus=106235\n(i.e. my 'a' flag would match your 'look-in-superprojects-odb', while\nthe 'c', 'r' and 'g' options would address your issues about how to\nselect the correct set of submodules).\n\n--\nlarsh\n"},{"id":"101740","messageId":"alpine.DEB.1.00.0901241443270.13232@racer","threadId":"17308","inReplyTo":"8c5c35580901240044y452b465fj94df82fc2b8f7ee9@mail.gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-24T13:51:53Z","receivedAt":"2009-01-24T13:51:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 24 Jan 2009, Lars Hjemli wrote:\n\n> On Fri, Jan 23, 2009 at 20:57, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> >  in all of Git, we try to assume that only reachable objects are valid \n> >  objects.\n> \n> I don't think this is true (most git commands accepts their arguments\n> as valid objects without verifying if they are reachable from a ref).\n\nThe fact that a user can ask for some object directly, and that we do not \ntry to validate it in that case has nothing to do with said assumption.\n\nIf something is pushed to a remote, and the connection fails, some commit \ncould be pushed already, but some of its reachable objects lacking.\n\nThe user on the remote side can still try to salvage parts by accessing \nthe objects directly, by their name.\n\nBut the only guarantee that the objects are reachable is to start from a \nref.\n\nConcretely, if your patch is applied as-is, such a half-pushed state could \naffect git-archive in a nasty way: even if the user started from a ref, \nthere could be missing objects!\n\n> Do you feel it is necessary to perform a reachability check of the \n> gitlink'd commit before traversing into a submodule tree?\n\nNo.  Because HEAD is a ref, too.\n\nNow, there is still a problem when your submodule is missing the objects \nfor the commit your superproject is referring to.\n\nIMO that is a serious issue, as it just asks for confused users.\n\n> > - presence of a specific commit in the supermodule is a _lousy_ \n> >   indicator that the user wants to include that submodule in the \n> >   archive.\n> \n> This is the issue I tried to address with my\n> `--submodules=[a|c|r][g:<name>]` proposal in the commit message for\n> this patch.\n\nNope, doing this \"in the future\" does not please me one bit.\n\nBesides, I find the semantics, uhm, \"interesting\".  (The other word would \nbe \"unintuitive\".  Why do you have to be so cryptic that I have to read \nthe proposal to understand what the heck \"c\" is about?)\n\nCiao,\nDscho\n"},{"id":"101768","messageId":"8c5c35580901241126q2da83f50m1472ed017b92c982@mail.gmail.com","threadId":"17308","inReplyTo":"alpine.DEB.1.00.0901241443270.13232@racer","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-24T19:26:05Z","receivedAt":"2009-01-24T19:26:05Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Sat, Jan 24, 2009 at 14:51, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> Now, there is still a problem when your submodule is missing the objects\n> for the commit your superproject is referring to.\n>\n> IMO that is a serious issue, as it just asks for confused users.\n\nThis made me finally understand your concern (sorry for being slow):\nyou want the command to behave in a predictable/consistent way while\nmy implementation would end up making an archive with basically random\ncontent.\n\n\n>> > - presence of a specific commit in the supermodule is a _lousy_\n>> >   indicator that the user wants to include that submodule in the\n>> >   archive.\n>>\n>> This is the issue I tried to address with my\n>> `--submodules=[a|c|r][g:<name>]` proposal in the commit message for\n>> this patch.\n>\n> Nope, doing this \"in the future\" does not please me one bit.\n>\n> Besides, I find the semantics, uhm, \"interesting\".  (The other word would\n> be \"unintuitive\".  Why do you have to be so cryptic that I have to read\n> the proposal to understand what the heck \"c\" is about?)\n\nI thought it would be nifty to be able to combine different flags\nwhich would affect the behaviour/semantics of the command, but given\nthe comments from you and Junio, I think I'll end up with something\nlike this:\n\n$ git archive --submodules <tree-ish>: Create an archive which\nincludes the trees of all gitlink entries in <tree-ish>, fail unless\nall the required objects are available.\n\n$ git archive --submodules=<group>: Same as above, but only traverse\nsubmodules in the specified group (as defined in $GIT_CONFIG).\n\n--\nlarsh\n"},{"id":"101773","messageId":"alpine.DEB.1.00.0901242049580.14855@racer","threadId":"17308","inReplyTo":"8c5c35580901241126q2da83f50m1472ed017b92c982@mail.gmail.com","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-24T19:52:07Z","receivedAt":"2009-01-24T19:52:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 24 Jan 2009, Lars Hjemli wrote:\n\n> $ git archive --submodules <tree-ish>: Create an archive which\n> includes the trees of all gitlink entries in <tree-ish>, fail unless\n> all the required objects are available.\n> \n> $ git archive --submodules=<group>: Same as above, but only traverse\n> submodules in the specified group (as defined in $GIT_CONFIG).\n\nHow about having the former with --submodules='*' and let --submodules \nwithout argument include those submodules that are checked out (none in a \nbare repository)?\n\nThanks,\nDscho\n"},{"id":"101774","messageId":"8c5c35580901241202k5ed436d7y2fafded2f0883c48@mail.gmail.com","threadId":"17308","inReplyTo":"alpine.DEB.1.00.0901242049580.14855@racer","subject":"Re: [RFC/PATCH v3 3/3] archive.c: add basic support for submodules","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2009-01-24T20:02:39Z","receivedAt":"2009-01-24T20:02:39Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Sat, Jan 24, 2009 at 20:52, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Sat, 24 Jan 2009, Lars Hjemli wrote:\n>\n>> $ git archive --submodules <tree-ish>: Create an archive which\n>> includes the trees of all gitlink entries in <tree-ish>, fail unless\n>> all the required objects are available.\n>>\n>> $ git archive --submodules=<group>: Same as above, but only traverse\n>> submodules in the specified group (as defined in $GIT_CONFIG).\n>\n> How about having the former with --submodules='*' and let --submodules\n> without argument include those submodules that are checked out (none in a\n> bare repository)?\n\nYeah, that might make more sense (since you'd normally not have access\nto the content of non-checked out submodules). I'm also considering\nsomething like --submodules[=(all|checkedout|[group:]<name>)], i.e.\nthe 'group:'-part could be optional as long as <name> is unambiguous.\n\n--\nlarsh\n"}]}