{"thread":{"id":"19270","subject":"questions about git-mktree","startedAt":"2009-05-10T13:41:17Z","lastAt":"2009-05-11T00:29:59Z","messageCount":16,"participants":["Jon Seymour","Uwe Kleine-König","A Large Angry SCM","Jakub Narebski","Junio C Hamano","Josh Micich","René Scharfe"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"113459","messageId":"2cfc40320905100641v3e8742c4v1d0e1091a730970b@mail.gmail.com","threadId":"19270","inReplyTo":null,"subject":"questions about git-mktree","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2009-05-10T13:41:17Z","receivedAt":"2009-05-10T13:41:17Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"Uwe,\n\nThanks for your explanation.\n\nDoes git-mktree normalize the sort order of the input or take it as it\nis? I can see  a case for having it do normalization, if it doesn't\nalready and probably for this to be the default behaviour.\n\nAlso, I have a need for something like git-mktree that takes a\nrecursive git-lstree output as input.\n\nJunio:  assuming these features don't exist already, are you open to\nthe idea of accepting patches that add them?\n\nRegards,\n\njon.\n"},{"id":"113461","messageId":"20090510151200.GA10189@pengutronix.de","threadId":"19270","inReplyTo":"2cfc40320905100641v3e8742c4v1d0e1091a730970b@mail.gmail.com","subject":"Re: questions about git-mktree","fromName":"Uwe Kleine-König","fromEmail":"u.kleine-koenig@pengutronix.de","sentAt":"2009-05-10T15:12:00Z","receivedAt":"2009-05-10T15:12:00Z","isPatch":false,"sender":{"key":"u.kleine-koenig@pengutronix.de","avatar":"https://gravatar.com/avatar/354b5e3ceb2806a2f1e1e382ac29ddbdad18288654da62b61eb13583a857eee7?d=mp&s=160"},"body":"Hello Jon,\n\nOn Sun, May 10, 2009 at 11:41:17PM +1000, Jon Seymour wrote:\n> Thanks for your explanation.\n> \n> Does git-mktree normalize the sort order of the input or take it as it\n> is? I can see  a case for having it do normalization, if it doesn't\n> already and probably for this to be the default behaviour.\nAs git-mktree doesn't exists I cannot answer that question ...\n\nAnyhow, another possibility to construct a tree is using the (or an)\nindex.\n\ngit-update-index --add --cacheinfo <mode> <object> <file> becomes handy\nfor constructing trees.\n\nBest regards\nUwe\n\n-- \nPengutronix e.K.                              | Uwe Kleine-König            |\nIndustrial Linux Solutions                    | http://www.pengutronix.de/  |\n"},{"id":"113463","messageId":"4A06F257.4030308@gmail.com","threadId":"19270","inReplyTo":"20090510151200.GA10189@pengutronix.de","subject":"Re: questions about git-mktree","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2009-05-10T15:27:19Z","receivedAt":"2009-05-10T15:27:19Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Uwe Kleine-König wrote:\n\n> As git-mktree doesn't exists I cannot answer that question ...\n\nhttp://kernel.org/pub/software/scm/git/docs/git-mktree.html\n"},{"id":"113464","messageId":"m3d4ahm0t6.fsf@localhost.localdomain","threadId":"19270","inReplyTo":"20090510151200.GA10189@pengutronix.de","subject":"Re: questions about git-mktree","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-05-10T15:31:52Z","receivedAt":"2009-05-10T15:31:52Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Uwe Kleine-König    <u.kleine-koenig@pengutronix.de> writes:\n\n> Hello Jon,\n> \n> On Sun, May 10, 2009 at 11:41:17PM +1000, Jon Seymour wrote:\n> > Thanks for your explanation.\n> > \n> > Does git-mktree normalize the sort order of the input or take it as it\n> > is? I can see  a case for having it do normalization, if it doesn't\n> > already and probably for this to be the default behaviour.\n\n> As git-mktree doesn't exists I cannot answer that question ...\n\n$ ls $(git --exec-path)/git-mktree\n/usr/libexec/git-core/git-mktree\n\nExamining mktree.c a bit you can see that there is qsort using\nent_compare in write_tree procedure.  It is not long file: 131 lines.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"113468","messageId":"7v63g829pg.fsf@alter.siamese.dyndns.org","threadId":"19270","inReplyTo":"2cfc40320905100641v3e8742c4v1d0e1091a730970b@mail.gmail.com","subject":"Re: questions about git-mktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T16:39:55Z","receivedAt":"2009-05-10T16:39:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jon Seymour <jon.seymour@gmail.com> writes:\n\n> Does git-mktree normalize the sort order of the input or take it as it\n> is? I can see  a case for having it do normalization, if it doesn't\n> already and probably for this to be the default behaviour.\n\nIt does have \"accumulate and qsort before writing it out\", since 83f5053\n(git-mktree: reverse of git-ls-tree., 2006-02-20).\n\nThis program was done as a quick hack but it is so old that I forgot all\nabout it.  If you are going to use it, you may have to do some reality\nchecks on it first.  For example, notice that the date above predates the\nintroduction of gitlinks, so I would not be too surprised if it barfed\nwhen given a commit object in its input.\n"},{"id":"113471","messageId":"7vvdo8zxwp.fsf@alter.siamese.dyndns.org","threadId":"19270","inReplyTo":"7v63g829pg.fsf@alter.siamese.dyndns.org","subject":"Re: questions about git-mktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T17:10:46Z","receivedAt":"2009-05-10T17:10:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Jon Seymour <jon.seymour@gmail.com> writes:\n>\n>> Does git-mktree normalize the sort order of the input or take it as it\n>> is? I can see  a case for having it do normalization, if it doesn't\n>> already and probably for this to be the default behaviour.\n>\n> It does have \"accumulate and qsort before writing it out\", since 83f5053\n> (git-mktree: reverse of git-ls-tree., 2006-02-20).\n>\n> This program was done as a quick hack but it is so old that I forgot all\n> about it.  If you are going to use it, you may have to do some reality\n> checks on it first.  For example, notice that the date above predates the\n> introduction of gitlinks, so I would not be too surprised if it barfed\n> when given a commit object in its input.\n\nHeh, it does verify that the object listed exists locally in the\nrepository, so submodules would not work in general.\n\nI'm fixing it.  You _might_ get your recursive mktree as a side effect at\nthe end of the series, but no promises ;-)\n"},{"id":"113474","messageId":"1241981391-19639-1-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"7vvdo8zxwp.fsf@alter.siamese.dyndns.org","subject":"[PATCH 0/6] Modernize mktree somewhat","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:45Z","receivedAt":"2009-05-10T18:49:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This series updates mktree to make it a built-in, teaches it to use\nparse-options, and then adds tests.  These are all necessary steps to\nmodernize it.\n\nThe last one adds --missing option to make things consistent with other\nparts of the system.  The combination of update-index and write-tree has\nprovisions to record a tree of objects that we may not have, but so far it\nwas not possible with mktree.\n\nJunio C Hamano (6):\n  build-in git-mktree\n  mktree: use parse-options\n  builtin-mktree.c: use a helper function to handle one line of input\n  mktree: do not barf on a submodule commit\n  t1010: add mktree test\n  mktree --missing: allow missing objects\n\n Makefile          |    2 +-\n builtin-mktree.c  |  141 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n builtin.h         |    1 +\n git.c             |    1 +\n mktree.c          |  131 -------------------------------------------------\n t/t1010-mktree.sh |   71 +++++++++++++++++++++++++++\n 6 files changed, 215 insertions(+), 132 deletions(-)\n create mode 100644 builtin-mktree.c\n delete mode 100644 mktree.c\n create mode 100755 t/t1010-mktree.sh\n"},{"id":"113476","messageId":"1241981391-19639-2-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/6] build-in git-mktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:46Z","receivedAt":"2009-05-10T18:49:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Makefile                     |    2 +-\n mktree.c => builtin-mktree.c |   18 +++++++-----------\n builtin.h                    |    1 +\n git.c                        |    1 +\n 4 files changed, 10 insertions(+), 12 deletions(-)\n rename mktree.c => builtin-mktree.c (91%)\n\ndiff --git a/Makefile b/Makefile\nindex 6e21643..9d9f0da 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -332,7 +332,6 @@ PROGRAMS += git-index-pack$X\n PROGRAMS += git-merge-index$X\n PROGRAMS += git-merge-tree$X\n PROGRAMS += git-mktag$X\n-PROGRAMS += git-mktree$X\n PROGRAMS += git-pack-redundant$X\n PROGRAMS += git-patch-id$X\n PROGRAMS += git-shell$X\n@@ -586,6 +585,7 @@ BUILTIN_OBJS += builtin-merge-base.o\n BUILTIN_OBJS += builtin-merge-file.o\n BUILTIN_OBJS += builtin-merge-ours.o\n BUILTIN_OBJS += builtin-merge-recursive.o\n+BUILTIN_OBJS += builtin-mktree.o\n BUILTIN_OBJS += builtin-mv.o\n BUILTIN_OBJS += builtin-name-rev.o\n BUILTIN_OBJS += builtin-pack-objects.o\ndiff --git a/mktree.c b/builtin-mktree.c\nsimilarity index 91%\nrename from mktree.c\nrename to builtin-mktree.c\nindex 137a095..3d05427 100644\n--- a/mktree.c\n+++ b/builtin-mktree.c\n@@ -1,12 +1,11 @@\n /*\n  * GIT - the stupid content tracker\n  *\n- * Copyright (c) Junio C Hamano, 2006\n+ * Copyright (c) Junio C Hamano, 2006, 2009\n  */\n-#include \"cache.h\"\n+#include \"builtin.h\"\n #include \"quote.h\"\n #include \"tree.h\"\n-#include \"exec_cmd.h\"\n \n static struct treeent {\n \tunsigned mode;\n@@ -64,19 +63,15 @@ static void write_tree(unsigned char *sha1)\n \n static const char mktree_usage[] = \"git mktree [-z]\";\n \n-int main(int ac, char **av)\n+int cmd_mktree(int ac, const char **av, const char *prefix)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct strbuf p_uq = STRBUF_INIT;\n \tunsigned char sha1[20];\n \tint line_termination = '\\n';\n \n-\tgit_extract_argv0_path(av[0]);\n-\n-\tsetup_git_directory();\n-\n \twhile ((1 < ac) && av[1][0] == '-') {\n-\t\tchar *arg = av[1];\n+\t\tconst char *arg = av[1];\n \t\tif (!strcmp(\"-z\", arg))\n \t\t\tline_termination = 0;\n \t\telse\n@@ -92,8 +87,9 @@ int main(int ac, char **av)\n \t\tchar *path;\n \n \t\tptr = sb.buf;\n-\t\t/* Input is non-recursive ls-tree output format\n-\t\t * mode SP type SP sha1 TAB name\n+\t\t/*\n+\t\t * Read non-recursive ls-tree output format:\n+\t\t *     mode SP type SP sha1 TAB name\n \t\t */\n \t\tmode = strtoul(ptr, &ntr, 8);\n \t\tif (ptr == ntr || !ntr || *ntr != ' ')\ndiff --git a/builtin.h b/builtin.h\nindex 425ff8e..20427d2 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -72,6 +72,7 @@ extern int cmd_merge_base(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_ours(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_file(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_recursive(int argc, const char **argv, const char *prefix);\n+extern int cmd_mktree(int argc, const char **argv, const char *prefix);\n extern int cmd_mv(int argc, const char **argv, const char *prefix);\n extern int cmd_name_rev(int argc, const char **argv, const char *prefix);\n extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex 5a00726..7d7f949 100644\n--- a/git.c\n+++ b/git.c\n@@ -327,6 +327,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"merge-ours\", cmd_merge_ours, RUN_SETUP },\n \t\t{ \"merge-recursive\", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"merge-subtree\", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },\n+\t\t{ \"mktree\", cmd_mktree, RUN_SETUP },\n \t\t{ \"mv\", cmd_mv, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"name-rev\", cmd_name_rev, RUN_SETUP },\n \t\t{ \"pack-objects\", cmd_pack_objects, RUN_SETUP },\n-- \n1.6.3.9.g6345d\n"},{"id":"113475","messageId":"1241981391-19639-3-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-2-git-send-email-gitster@pobox.com","subject":"[PATCH 2/6] mktree: use parse-options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:47Z","receivedAt":"2009-05-10T18:49:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-mktree.c |   20 ++++++++++----------\n 1 files changed, 10 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-mktree.c b/builtin-mktree.c\nindex 3d05427..2b3145b 100644\n--- a/builtin-mktree.c\n+++ b/builtin-mktree.c\n@@ -6,6 +6,7 @@\n #include \"builtin.h\"\n #include \"quote.h\"\n #include \"tree.h\"\n+#include \"parse-options.h\"\n \n static struct treeent {\n \tunsigned mode;\n@@ -61,7 +62,10 @@ static void write_tree(unsigned char *sha1)\n \twrite_sha1_file(buf.buf, buf.len, tree_type, sha1);\n }\n \n-static const char mktree_usage[] = \"git mktree [-z]\";\n+static const char *mktree_usage[] = {\n+\t\"git mktree [-z]\",\n+\tNULL\n+};\n \n int cmd_mktree(int ac, const char **av, const char *prefix)\n {\n@@ -69,16 +73,12 @@ int cmd_mktree(int ac, const char **av, const char *prefix)\n \tstruct strbuf p_uq = STRBUF_INIT;\n \tunsigned char sha1[20];\n \tint line_termination = '\\n';\n+\tconst struct option option[] = {\n+\t\tOPT_SET_INT('z', NULL, &line_termination, \"input is NUL terminated\", '\\0'),\n+\t\tOPT_END()\n+\t};\n \n-\twhile ((1 < ac) && av[1][0] == '-') {\n-\t\tconst char *arg = av[1];\n-\t\tif (!strcmp(\"-z\", arg))\n-\t\t\tline_termination = 0;\n-\t\telse\n-\t\t\tusage(mktree_usage);\n-\t\tac--;\n-\t\tav++;\n-\t}\n+\tac = parse_options(ac, av, option, mktree_usage, 0);\n \n \twhile (strbuf_getline(&sb, stdin, line_termination) != EOF) {\n \t\tchar *ptr, *ntr;\n-- \n1.6.3.9.g6345d\n"},{"id":"113477","messageId":"1241981391-19639-4-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-3-git-send-email-gitster@pobox.com","subject":"[PATCH 3/6] builtin-mktree.c: use a helper function to handle one line of input","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:48Z","receivedAt":"2009-05-10T18:49:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The main() function used to do the whole thing; this moves the handling of\na single input line to a separate function to make it easier to read.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-mktree.c |   82 +++++++++++++++++++++++++++--------------------------\n 1 files changed, 42 insertions(+), 40 deletions(-)\n\ndiff --git a/builtin-mktree.c b/builtin-mktree.c\nindex 2b3145b..133ab4b 100644\n--- a/builtin-mktree.c\n+++ b/builtin-mktree.c\n@@ -67,10 +67,48 @@ static const char *mktree_usage[] = {\n \tNULL\n };\n \n+static void mktree_line(char *buf, size_t len, int line_termination)\n+{\n+\tchar *ptr, *ntr;\n+\tunsigned mode;\n+\tenum object_type type;\n+\tchar *path;\n+\tunsigned char sha1[20];\n+\n+\tptr = buf;\n+\t/*\n+\t * Read non-recursive ls-tree output format:\n+\t *     mode SP type SP sha1 TAB name\n+\t */\n+\tmode = strtoul(ptr, &ntr, 8);\n+\tif (ptr == ntr || !ntr || *ntr != ' ')\n+\t\tdie(\"input format error: %s\", buf);\n+\tptr = ntr + 1; /* type */\n+\tntr = strchr(ptr, ' ');\n+\tif (!ntr || buf + len <= ntr + 40 ||\n+\t    ntr[41] != '\\t' ||\n+\t    get_sha1_hex(ntr + 1, sha1))\n+\t\tdie(\"input format error: %s\", buf);\n+\ttype = sha1_object_info(sha1, NULL);\n+\tif (type < 0)\n+\t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n+\t*ntr++ = 0; /* now at the beginning of SHA1 */\n+\tif (type != type_from_string(ptr))\n+\t\tdie(\"object type %s mismatch (%s)\", ptr, typename(type));\n+\n+\tpath = ntr + 41;  /* at the beginning of name */\n+\tif (line_termination && path[0] == '\"') {\n+\t\tstruct strbuf p_uq = STRBUF_INIT;\n+\t\tif (unquote_c_style(&p_uq, path, NULL))\n+\t\t\tdie(\"invalid quoting\");\n+\t\tpath = strbuf_detach(&p_uq, NULL);\n+\t}\n+\tappend_to_tree(mode, sha1, path);\n+}\n+\n int cmd_mktree(int ac, const char **av, const char *prefix)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n-\tstruct strbuf p_uq = STRBUF_INIT;\n \tunsigned char sha1[20];\n \tint line_termination = '\\n';\n \tconst struct option option[] = {\n@@ -80,45 +118,9 @@ int cmd_mktree(int ac, const char **av, const char *prefix)\n \n \tac = parse_options(ac, av, option, mktree_usage, 0);\n \n-\twhile (strbuf_getline(&sb, stdin, line_termination) != EOF) {\n-\t\tchar *ptr, *ntr;\n-\t\tunsigned mode;\n-\t\tenum object_type type;\n-\t\tchar *path;\n-\n-\t\tptr = sb.buf;\n-\t\t/*\n-\t\t * Read non-recursive ls-tree output format:\n-\t\t *     mode SP type SP sha1 TAB name\n-\t\t */\n-\t\tmode = strtoul(ptr, &ntr, 8);\n-\t\tif (ptr == ntr || !ntr || *ntr != ' ')\n-\t\t\tdie(\"input format error: %s\", sb.buf);\n-\t\tptr = ntr + 1; /* type */\n-\t\tntr = strchr(ptr, ' ');\n-\t\tif (!ntr || sb.buf + sb.len <= ntr + 40 ||\n-\t\t    ntr[41] != '\\t' ||\n-\t\t    get_sha1_hex(ntr + 1, sha1))\n-\t\t\tdie(\"input format error: %s\", sb.buf);\n-\t\ttype = sha1_object_info(sha1, NULL);\n-\t\tif (type < 0)\n-\t\t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n-\t\t*ntr++ = 0; /* now at the beginning of SHA1 */\n-\t\tif (type != type_from_string(ptr))\n-\t\t\tdie(\"object type %s mismatch (%s)\", ptr, typename(type));\n-\n-\t\tpath = ntr + 41;  /* at the beginning of name */\n-\t\tif (line_termination && path[0] == '\"') {\n-\t\t\tstrbuf_reset(&p_uq);\n-\t\t\tif (unquote_c_style(&p_uq, path, NULL)) {\n-\t\t\t\tdie(\"invalid quoting\");\n-\t\t\t}\n-\t\t\tpath = p_uq.buf;\n-\t\t}\n-\n-\t\tappend_to_tree(mode, sha1, path);\n-\t}\n-\tstrbuf_release(&p_uq);\n+\twhile (strbuf_getline(&sb, stdin, line_termination) != EOF)\n+\t\tmktree_line(sb.buf, sb.len, line_termination);\n+\n \tstrbuf_release(&sb);\n \n \twrite_tree(sha1);\n-- \n1.6.3.9.g6345d\n"},{"id":"113478","messageId":"1241981391-19639-5-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-4-git-send-email-gitster@pobox.com","subject":"[PATCH 4/6] mktree: do not barf on a submodule commit","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:49Z","receivedAt":"2009-05-10T18:49:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"It is perfectly normal if a tree entry points at a missing commit as long\nas the mode of the entry says it is a submodule.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-mktree.c |    9 ++++++++-\n 1 files changed, 8 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-mktree.c b/builtin-mktree.c\nindex 133ab4b..17cdb3d 100644\n--- a/builtin-mktree.c\n+++ b/builtin-mktree.c\n@@ -89,9 +89,16 @@ static void mktree_line(char *buf, size_t len, int line_termination)\n \t    ntr[41] != '\\t' ||\n \t    get_sha1_hex(ntr + 1, sha1))\n \t\tdie(\"input format error: %s\", buf);\n-\ttype = sha1_object_info(sha1, NULL);\n+\n+\t/* It is perfectly normal if we do not have a commit from a submodule */\n+\tif (!S_ISGITLINK(mode))\n+\t\ttype = sha1_object_info(sha1, NULL);\n+\telse\n+\t\ttype = OBJ_COMMIT;\n+\n \tif (type < 0)\n \t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n+\n \t*ntr++ = 0; /* now at the beginning of SHA1 */\n \tif (type != type_from_string(ptr))\n \t\tdie(\"object type %s mismatch (%s)\", ptr, typename(type));\n-- \n1.6.3.9.g6345d\n"},{"id":"113479","messageId":"1241981391-19639-6-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-5-git-send-email-gitster@pobox.com","subject":"[PATCH 5/6] t1010: add mktree test","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:50Z","receivedAt":"2009-05-10T18:49:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"So far mktree (which has always been a quick hack) had no test.\nAt least give it a bit of test coverage.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t1010-mktree.sh |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 61 insertions(+), 0 deletions(-)\n create mode 100755 t/t1010-mktree.sh\n\ndiff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh\nnew file mode 100755\nindex 0000000..4d9b138\n--- /dev/null\n+++ b/t/t1010-mktree.sh\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+\n+test_description='git mktree'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\tfor d in a a. a0\n+\tdo\n+\t\tmkdir \"$d\" && echo \"$d/one\" >\"$d/one\" &&\n+\t\tgit add \"$d\"\n+\tdone &&\n+\techo one >one &&\n+\tgit add one &&\n+\tgit write-tree >tree &&\n+\tgit ls-tree $(cat tree) >top &&\n+\tgit ls-tree -r $(cat tree) >all &&\n+\ttest_tick &&\n+\tgit commit -q -m one &&\n+\tH=$(git rev-parse HEAD) &&\n+\tgit update-index --add --cacheinfo 160000 $H sub &&\n+\ttest_tick &&\n+\tgit commit -q -m two &&\n+\tgit rev-parse HEAD^{tree} >tree.withsub &&\n+\tgit ls-tree HEAD >top.withsub &&\n+\tgit ls-tree -r HEAD >all.withsub\n+'\n+\n+test_expect_success 'ls-tree piped to mktree (1)' '\n+\tgit mktree <top >actual &&\n+\ttest_cmp tree actual\n+'\n+\n+test_expect_success 'ls-tree piped to mktree (2)' '\n+\tgit mktree <top.withsub >actual &&\n+\ttest_cmp tree.withsub actual\n+'\n+\n+test_expect_success 'ls-tree output in wrong order given to mktree (1)' '\n+\tperl -e \"print reverse <>\" <top |\n+\tgit mktree >actual &&\n+\ttest_cmp tree actual\n+'\n+\n+test_expect_success 'ls-tree output in wrong order given to mktree (2)' '\n+\tperl -e \"print reverse <>\" <top.withsub |\n+\tgit mktree >actual &&\n+\ttest_cmp tree.withsub actual\n+'\n+\n+test_expect_failure 'mktree reads ls-tree -r output (1)' '\n+\tgit mktree <all >actual &&\n+\ttest_cmp tree actual\n+'\n+\n+test_expect_failure 'mktree reads ls-tree -r output (2)' '\n+\tgit mktree <all.withsub >actual &&\n+\ttest_cmp tree.withsub actual\n+'\n+\n+test_done\n-- \n1.6.3.9.g6345d\n"},{"id":"113480","messageId":"1241981391-19639-7-git-send-email-gitster@pobox.com","threadId":"19270","inReplyTo":"1241981391-19639-6-git-send-email-gitster@pobox.com","subject":"[PATCH 6/6] mktree --missing: allow missing objects","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-10T18:49:51Z","receivedAt":"2009-05-10T18:49:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We need to allow input lines that point at objects that we do not\nhave when dealing with submodule entries anyway.  This adds an explicit\noption to allow missing objects of other types, to be consistent with\nthe use of --info-only option to the update-index command and --missing-ok\noption to the write-tree command.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-mktree.c  |   11 ++++++++---\n t/t1010-mktree.sh |   10 ++++++++++\n 2 files changed, 18 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin-mktree.c b/builtin-mktree.c\nindex 17cdb3d..c2fd0f2 100644\n--- a/builtin-mktree.c\n+++ b/builtin-mktree.c\n@@ -67,7 +67,7 @@ static const char *mktree_usage[] = {\n \tNULL\n };\n \n-static void mktree_line(char *buf, size_t len, int line_termination)\n+static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing)\n {\n \tchar *ptr, *ntr;\n \tunsigned mode;\n@@ -92,9 +92,12 @@ static void mktree_line(char *buf, size_t len, int line_termination)\n \n \t/* It is perfectly normal if we do not have a commit from a submodule */\n \tif (!S_ISGITLINK(mode))\n+\t\tallow_missing = 1;\n+\n+\tif (!allow_missing)\n \t\ttype = sha1_object_info(sha1, NULL);\n \telse\n-\t\ttype = OBJ_COMMIT;\n+\t\ttype = object_type(mode);\n \n \tif (type < 0)\n \t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n@@ -118,15 +121,17 @@ int cmd_mktree(int ac, const char **av, const char *prefix)\n \tstruct strbuf sb = STRBUF_INIT;\n \tunsigned char sha1[20];\n \tint line_termination = '\\n';\n+\tint allow_missing = 0;\n \tconst struct option option[] = {\n \t\tOPT_SET_INT('z', NULL, &line_termination, \"input is NUL terminated\", '\\0'),\n+\t\tOPT_SET_INT( 0 , \"missing\", &allow_missing, \"allow missing objects\", 1),\n \t\tOPT_END()\n \t};\n \n \tac = parse_options(ac, av, option, mktree_usage, 0);\n \n \twhile (strbuf_getline(&sb, stdin, line_termination) != EOF)\n-\t\tmktree_line(sb.buf, sb.len, line_termination);\n+\t\tmktree_line(sb.buf, sb.len, line_termination, allow_missing);\n \n \tstrbuf_release(&sb);\n \ndiff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh\nindex 4d9b138..9956e3a 100755\n--- a/t/t1010-mktree.sh\n+++ b/t/t1010-mktree.sh\n@@ -10,6 +10,11 @@ test_expect_success setup '\n \t\tmkdir \"$d\" && echo \"$d/one\" >\"$d/one\" &&\n \t\tgit add \"$d\"\n \tdone &&\n+\techo zero >one &&\n+\tgit update-index --add --info-only one &&\n+\tgit write-tree --missing-ok >tree.missing &&\n+\tgit ls-tree $(cat tree.missing) >top.missing &&\n+\tgit ls-tree -r $(cat tree.missing) >all.missing &&\n \techo one >one &&\n \tgit add one &&\n \tgit write-tree >tree &&\n@@ -48,6 +53,11 @@ test_expect_success 'ls-tree output in wrong order given to mktree (2)' '\n \ttest_cmp tree.withsub actual\n '\n \n+test_expect_success 'allow missing object with --missing' '\n+\tgit mktree --missing <top.missing >actual &&\n+\ttest_cmp tree.missing actual\n+'\n+\n test_expect_failure 'mktree reads ls-tree -r output (1)' '\n \tgit mktree <all >actual &&\n \ttest_cmp tree actual\n-- \n1.6.3.9.g6345d\n"},{"id":"113481","messageId":"loom.20090510T184606-644@post.gmane.org","threadId":"19270","inReplyTo":"7vvdo8zxwp.fsf@alter.siamese.dyndns.org","subject":"Re: questions about git-mktree - [PATCH] proposed '--batch' option","fromName":"Josh Micich","fromEmail":"josh.micich@gmail.com","sentAt":"2009-05-10T18:54:25Z","receivedAt":"2009-05-10T18:54:25Z","isPatch":true,"sender":{"key":"josh.micich@gmail.com","avatar":null},"body":"Junio C Hamano <gitster <at> pobox.com> writes:\n> \n> I'm fixing it.  You _might_ get your recursive mktree as a side effect at\n> the end of the series, but no promises \n\nIs it possible add a '--batch' option to git-mktree? Here is a change I made \nlocally which seems to work.  Hopefully it's not too hard to incorporate with \nyour other changes.\n-josh\n\n Documentation/git-mktree.txt |   14 +++++-\n mktree.c                     |   98 +++++++++++++++++++++++++----------------\ndiff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.txt\nindex af19f06..1aa24b5 100644\n--- a/Documentation/git-mktree.txt\n+++ b/Documentation/git-mktree.txt\n@@ -8,18 +8,25 @@ git-mktree - Build a tree-object from ls-tree formatted text\n \n SYNOPSIS\n --------\n-'git mktree' [-z]\n+'git mktree' [-z] [--batch]\n \n DESCRIPTION\n -----------\n Reads standard input in non-recursive `ls-tree` output format,\n-and creates a tree object.  The object name of the tree object\n-built is written to the standard output.\n+and creates a tree object.  The order of the tree entries is \n+normalised by mktree so pre-sorting the input is not required.\n+The object name of the tree object built is written to the\n+standard output.\n \n OPTIONS\n -------\n -z::\n \tRead the NUL-terminated `ls-tree -z` output instead.\n+--batch::\n+\tAllow building of more than one tree object before exiting.\n+\tEach tree is separated by as single blank line. The final\n+\tnew-line is optional.  Note - if the '-z' option is used,\n+\tlines are terminated with NUL.\n \n Author\n ------\ndiff --git a/mktree.c b/mktree.c\nindex 137a095..2743aaa 100644\n--- a/mktree.c\n+++ b/mktree.c\n@@ -62,7 +62,7 @@ static void write_tree(unsigned char *sha1)\n \twrite_sha1_file(buf.buf, buf.len, tree_type, sha1);\n }\n \n-static const char mktree_usage[] = \"git mktree [-z]\";\n+static const char mktree_usage[] = \"git mktree [-z] [--batch]\";\n \n int main(int ac, char **av)\n {\n@@ -70,6 +70,7 @@ int main(int ac, char **av)\n \tstruct strbuf p_uq = STRBUF_INIT;\n \tunsigned char sha1[20];\n \tint line_termination = '\\n';\n+\tint is_batch_mode = 0;\n \n \tgit_extract_argv0_path(av[0]);\n \n@@ -79,53 +80,74 @@ int main(int ac, char **av)\n \t\tchar *arg = av[1];\n \t\tif (!strcmp(\"-z\", arg))\n \t\t\tline_termination = 0;\n+\t\telse if (!strcmp(\"--batch\", arg))\n+\t\t\tis_batch_mode = 1;\n \t\telse\n \t\t\tusage(mktree_usage);\n \t\tac--;\n \t\tav++;\n \t}\n \n-\twhile (strbuf_getline(&sb, stdin, line_termination) != EOF) {\n-\t\tchar *ptr, *ntr;\n-\t\tunsigned mode;\n-\t\tenum object_type type;\n-\t\tchar *path;\n-\n-\t\tptr = sb.buf;\n-\t\t/* Input is non-recursive ls-tree output format\n-\t\t * mode SP type SP sha1 TAB name\n-\t\t */\n-\t\tmode = strtoul(ptr, &ntr, 8);\n-\t\tif (ptr == ntr || !ntr || *ntr != ' ')\n-\t\t\tdie(\"input format error: %s\", sb.buf);\n-\t\tptr = ntr + 1; /* type */\n-\t\tntr = strchr(ptr, ' ');\n-\t\tif (!ntr || sb.buf + sb.len <= ntr + 40 ||\n-\t\t    ntr[41] != '\\t' ||\n-\t\t    get_sha1_hex(ntr + 1, sha1))\n-\t\t\tdie(\"input format error: %s\", sb.buf);\n-\t\ttype = sha1_object_info(sha1, NULL);\n-\t\tif (type < 0)\n-\t\t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n-\t\t*ntr++ = 0; /* now at the beginning of SHA1 */\n-\t\tif (type != type_from_string(ptr))\n-\t\t\tdie(\"object type %s mismatch (%s)\", ptr, \ntypename(type));\n-\n-\t\tpath = ntr + 41;  /* at the beginning of name */\n-\t\tif (line_termination && path[0] == '\"') {\n-\t\t\tstrbuf_reset(&p_uq);\n-\t\t\tif (unquote_c_style(&p_uq, path, NULL)) {\n-\t\t\t\tdie(\"invalid quoting\");\n+\tint got_eof = 0;\n+\twhile (!got_eof) {\n+\t\twhile (1) {\n+\t\t\tif (strbuf_getline(&sb, stdin, line_termination) == \nEOF) {\n+\t\t\t\tgot_eof = 1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (sb.buf[0] == '\\0') {\n+\t\t\t\t// empty lines denote tree boundaries in batch \nmode\n+\t\t\t\tif (is_batch_mode) {\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tdie(\"input format error: (blank line only valid \nin batch mode)\");\n+\t\t\t}\n+\t\t\tchar *ptr, *ntr;\n+\t\t\tunsigned mode;\n+\t\t\tenum object_type type;\n+\t\t\tchar *path;\n+\t\n+\t\t\tptr = sb.buf;\n+\t\t\t/* Input is non-recursive ls-tree output format\n+\t\t\t * mode SP type SP sha1 TAB name\n+\t\t\t */\n+\t\t\tmode = strtoul(ptr, &ntr, 8);\n+\t\t\tif (ptr == ntr || !ntr || *ntr != ' ')\n+\t\t\t\tdie(\"input format error: %s\", sb.buf);\n+\t\t\tptr = ntr + 1; /* type */\n+\t\t\tntr = strchr(ptr, ' ');\n+\t\t\tif (!ntr || sb.buf + sb.len <= ntr + 40 ||\n+\t\t\t\tntr[41] != '\\t' ||\n+\t\t\t\tget_sha1_hex(ntr + 1, sha1))\n+\t\t\t\tdie(\"input format error: %s\", sb.buf);\n+\t\t\ttype = sha1_object_info(sha1, NULL);\n+\t\t\tif (type < 0)\n+\t\t\t\tdie(\"object %s unavailable\", \nsha1_to_hex(sha1));\n+\t\t\t*ntr++ = 0; /* now at the beginning of SHA1 */\n+\t\t\tif (type != type_from_string(ptr))\n+\t\t\t\tdie(\"object type %s mismatch (%s)\", ptr, \ntypename(type));\n+\n+\t\t\tpath = ntr + 41;  /* at the beginning of name */\n+\t\t\tif (line_termination && path[0] == '\"') {\n+\t\t\t\tstrbuf_reset(&p_uq);\n+\t\t\t\tif (unquote_c_style(&p_uq, path, NULL)) {\n+\t\t\t\t\tdie(\"invalid quoting\");\n+\t\t\t\t}\n+\t\t\t\tpath = p_uq.buf;\n \t\t\t}\n-\t\t\tpath = p_uq.buf;\n-\t\t}\n \n-\t\tappend_to_tree(mode, sha1, path);\n+\t\t\tappend_to_tree(mode, sha1, path);\n+\t\t}\n+\t\tif (is_batch_mode && got_eof && used < 1) {\n+\t\t\t// allow input to finish with a new-line (or not)\n+\t\t} else {\n+\t\t\twrite_tree(sha1);\n+\t\t\tputs(sha1_to_hex(sha1));\n+\t\t\tfflush(stdout);\n+\t\t}\n+\t\tused=0; // reset tree entry buffer for re-use in batch mode\n \t}\n \tstrbuf_release(&p_uq);\n \tstrbuf_release(&sb);\n-\n-\twrite_tree(sha1);\n-\tputs(sha1_to_hex(sha1));\n \texit(0);\n }\n"},{"id":"113493","messageId":"4A075195.5020508@lsrfire.ath.cx","threadId":"19270","inReplyTo":"1241981391-19639-7-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 6/6] mktree --missing: allow missing objects","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2009-05-10T22:13:41Z","receivedAt":"2009-05-10T22:13:41Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Junio C Hamano schrieb:\n> -static void mktree_line(char *buf, size_t len, int line_termination)\n> +static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing)\n>  {\n>  \tchar *ptr, *ntr;\n>  \tunsigned mode;\n> @@ -92,9 +92,12 @@ static void mktree_line(char *buf, size_t len, int line_termination)\n>  \n>  \t/* It is perfectly normal if we do not have a commit from a submodule */\n>  \tif (!S_ISGITLINK(mode))\n> +\t\tallow_missing = 1;\n> +\n> +\tif (!allow_missing)\n>  \t\ttype = sha1_object_info(sha1, NULL);\n>  \telse\n> -\t\ttype = OBJ_COMMIT;\n> +\t\ttype = object_type(mode);\n>  \n>  \tif (type < 0)\n>  \t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n\nDon't you need this, above?\n\n-  \tif (!S_ISGITLINK(mode))\n+\tif (S_ISGITLINK(mode))\n\nRené\n"},{"id":"113502","messageId":"7vocu0traw.fsf@alter.siamese.dyndns.org","threadId":"19270","inReplyTo":"4A075195.5020508@lsrfire.ath.cx","subject":"Re: [PATCH 6/6] mktree --missing: allow missing objects","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-05-11T00:29:59Z","receivedAt":"2009-05-11T00:29:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:\n\n> Junio C Hamano schrieb:\n>> -static void mktree_line(char *buf, size_t len, int line_termination)\n>> +static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing)\n>>  {\n>>  \tchar *ptr, *ntr;\n>>  \tunsigned mode;\n>> @@ -92,9 +92,12 @@ static void mktree_line(char *buf, size_t len, int line_termination)\n>>  \n>>  \t/* It is perfectly normal if we do not have a commit from a submodule */\n>>  \tif (!S_ISGITLINK(mode))\n>> +\t\tallow_missing = 1;\n>> +\n>> +\tif (!allow_missing)\n>>  \t\ttype = sha1_object_info(sha1, NULL);\n>>  \telse\n>> -\t\ttype = OBJ_COMMIT;\n>> +\t\ttype = object_type(mode);\n>>  \n>>  \tif (type < 0)\n>>  \t\tdie(\"object %s unavailable\", sha1_to_hex(sha1));\n>\n> Don't you need this, above?\n>\n> -  \tif (!S_ISGITLINK(mode))\n> +\tif (S_ISGITLINK(mode))\n\nAgh; you are of course right.\n"}]}