{"thread":{"id":"28897","subject":"[PATCH 3/3] commit-tree: teach -x <extra>","startedAt":"2011-11-09T21:01:32Z","lastAt":"2011-11-09T22:19:00Z","messageCount":5,"participants":["Junio C Hamano","Brad King"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"179217","messageId":"1320872495-7545-1-git-send-email-gitster@pobox.com","threadId":"28897","inReplyTo":null,"subject":"[PATCH 0/3] commit-tree updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-09T21:01:32Z","receivedAt":"2011-11-09T21:01:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here are a handful of patches to the lowest level plumbing commit-tree to\nteach it to record extended headers.  With this series, scripted Porcelain\nlike rebase--am can propagate the \"mergetag\" header while rebasing.\n\nJunio C Hamano (3):\n  commit-tree: update the command line parsing\n  commit-tree: teach -m/-F options to read logs from elsewhere\n  commit-tree: teach -x <extra>\n\n Documentation/git-commit-tree.txt |   17 ++++++-\n builtin/commit-tree.c             |   92 ++++++++++++++++++++++++++++++-------\n 2 files changed, 89 insertions(+), 20 deletions(-)\n\n-- \n1.7.8.rc1.82.gde0f9\n"},{"id":"179218","messageId":"1320872495-7545-2-git-send-email-gitster@pobox.com","threadId":"28897","inReplyTo":"1320872495-7545-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/3] commit-tree: update the command line parsing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-09T21:01:33Z","receivedAt":"2011-11-09T21:01:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We have kept the original \"git commit-tree <tree> -p <parent> ...\" syntax\nforever, but \"git commit-tree -p <parent> -p <parent> ... <tree>\" would be\nmore intuitive way to spell it. Dashed flags along with their arguments\ncome first and then the \"thing\" argument after the flags.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin/commit-tree.c |   31 ++++++++++++++++++-------------\n 1 files changed, 18 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/commit-tree.c b/builtin/commit-tree.c\nindex d083795..92cfbaf 100644\n--- a/builtin/commit-tree.c\n+++ b/builtin/commit-tree.c\n@@ -27,7 +27,7 @@ static void new_parent(struct commit *parent, struct commit_list **parents_p)\n \n int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n {\n-\tint i;\n+\tint i, got_tree = 0;\n \tstruct commit_list *parents = NULL;\n \tunsigned char tree_sha1[20];\n \tunsigned char commit_sha1[20];\n@@ -37,20 +37,25 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \n \tif (argc < 2 || !strcmp(argv[1], \"-h\"))\n \t\tusage(commit_tree_usage);\n-\tif (get_sha1(argv[1], tree_sha1))\n-\t\tdie(\"Not a valid object name %s\", argv[1]);\n \n-\tfor (i = 2; i < argc; i += 2) {\n-\t\tunsigned char sha1[20];\n-\t\tconst char *a, *b;\n-\t\ta = argv[i]; b = argv[i+1];\n-\t\tif (!b || strcmp(a, \"-p\"))\n-\t\t\tusage(commit_tree_usage);\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\t\tif (!strcmp(arg, \"-p\")) {\n+\t\t\tunsigned char sha1[20];\n+\t\t\tif (argc <= ++i)\n+\t\t\t\tusage(commit_tree_usage);\n+\t\t\tif (get_sha1(argv[i], sha1))\n+\t\t\t\tdie(\"Not a valid object name %s\", argv[i]);\n+\t\t\tassert_sha1_type(sha1, OBJ_COMMIT);\n+\t\t\tnew_parent(lookup_commit(sha1), &parents);\n+\t\t\tcontinue;\n+\t\t}\n \n-\t\tif (get_sha1(b, sha1))\n-\t\t\tdie(\"Not a valid object name %s\", b);\n-\t\tassert_sha1_type(sha1, OBJ_COMMIT);\n-\t\tnew_parent(lookup_commit(sha1), &parents);\n+\t\tif (get_sha1(arg, tree_sha1))\n+\t\t\tdie(\"Not a valid object name %s\", arg);\n+\t\tif (got_tree)\n+\t\t\tdie(\"Cannot give more than one trees\");\n+\t\tgot_tree = 1;\n \t}\n \n \tif (strbuf_read(&buffer, 0, 0) < 0)\n-- \n1.7.8.rc1.82.gde0f9\n"},{"id":"179219","messageId":"1320872495-7545-3-git-send-email-gitster@pobox.com","threadId":"28897","inReplyTo":"1320872495-7545-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/3] commit-tree: teach -m/-F options to read logs from elsewhere","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-09T21:01:34Z","receivedAt":"2011-11-09T21:01:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Just like \"git commit\" does.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-commit-tree.txt |   16 +++++++++++--\n builtin/commit-tree.c             |   43 ++++++++++++++++++++++++++++++++++--\n 2 files changed, 53 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt\nindex 02133d5..cfb9906 100644\n--- a/Documentation/git-commit-tree.txt\n+++ b/Documentation/git-commit-tree.txt\n@@ -9,7 +9,8 @@ git-commit-tree - Create a new commit object\n SYNOPSIS\n --------\n [verse]\n-'git commit-tree' <tree> [(-p <parent commit>)...] < changelog\n+'git commit-tree' <tree> [(-p <parent>)...] < changelog\n+'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree>\n \n DESCRIPTION\n -----------\n@@ -17,7 +18,8 @@ This is usually not what an end user wants to run directly.  See\n linkgit:git-commit[1] instead.\n \n Creates a new commit object based on the provided tree object and\n-emits the new commit object id on stdout.\n+emits the new commit object id on stdout. The log message is read\n+from the standard input, unless `-m` or `-F` options are given.\n \n A commit object may have any number of parents. With exactly one\n parent, it is an ordinary commit. Having more than one parent makes\n@@ -39,9 +41,17 @@ OPTIONS\n <tree>::\n \tAn existing tree object\n \n--p <parent commit>::\n+-p <parent>::\n \tEach '-p' indicates the id of a parent commit object.\n \n+-m <message>::\n+\tA paragraph in the commig log message. This can be given more than\n+\tonce and each <message> becomes its own paragraph.\n+\n+-F <file>::\n+\tRead the commit log message from the given file. Use `-` to read\n+\tfrom the standard input.\n+\n \n Commit Information\n ------------------\ndiff --git a/builtin/commit-tree.c b/builtin/commit-tree.c\nindex 92cfbaf..db5b6e5 100644\n--- a/builtin/commit-tree.c\n+++ b/builtin/commit-tree.c\n@@ -9,7 +9,7 @@\n #include \"builtin.h\"\n #include \"utf8.h\"\n \n-static const char commit_tree_usage[] = \"git commit-tree <sha1> [(-p <sha1>)...] < changelog\";\n+static const char commit_tree_usage[] = \"git commit-tree [(-p <sha1>)...] [-m <message>] <sha1> < changelog\";\n \n static void new_parent(struct commit *parent, struct commit_list **parents_p)\n {\n@@ -51,6 +51,41 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \t\t}\n \n+\t\tif (!strcmp(arg, \"-m\")) {\n+\t\t\tif (argc <= ++i)\n+\t\t\t\tusage(commit_tree_usage);\n+\t\t\tif (buffer.len)\n+\t\t\t\tstrbuf_addch(&buffer, '\\n');\n+\t\t\tstrbuf_addstr(&buffer, argv[i]);\n+\t\t\tstrbuf_complete_line(&buffer);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (!strcmp(arg, \"-F\")) {\n+\t\t\tint fd;\n+\n+\t\t\tif (argc <= ++i)\n+\t\t\t\tusage(commit_tree_usage);\n+\t\t\tif (buffer.len)\n+\t\t\t\tstrbuf_addch(&buffer, '\\n');\n+\t\t\tif (!strcmp(argv[i], \"-\"))\n+\t\t\t\tfd = 0;\n+\t\t\telse {\n+\t\t\t\tfd = open(argv[i], O_RDONLY);\n+\t\t\t\tif (fd < 0)\n+\t\t\t\t\tdie_errno(\"git commit-tree: failed to open '%s'\",\n+\t\t\t\t\t\t  argv[i]);\n+\t\t\t}\n+\t\t\tif (strbuf_read(&buffer, fd, 0) < 0)\n+\t\t\t\tdie_errno(\"git commit-tree: failed to read '%s'\",\n+\t\t\t\t\t  argv[i]);\n+\t\t\tif (fd && close(fd))\n+\t\t\t\tdie_errno(\"git commit-tree: failed to close '%s'\",\n+\t\t\t\t\t  argv[i]);\n+\t\t\tstrbuf_complete_line(&buffer);\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\tif (get_sha1(arg, tree_sha1))\n \t\t\tdie(\"Not a valid object name %s\", arg);\n \t\tif (got_tree)\n@@ -58,8 +93,10 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t\tgot_tree = 1;\n \t}\n \n-\tif (strbuf_read(&buffer, 0, 0) < 0)\n-\t\tdie_errno(\"git commit-tree: failed to read\");\n+\tif (!buffer.len) {\n+\t\tif (strbuf_read(&buffer, 0, 0) < 0)\n+\t\t\tdie_errno(\"git commit-tree: failed to read\");\n+\t}\n \n \tif (commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {\n \t\tstrbuf_release(&buffer);\n-- \n1.7.8.rc1.82.gde0f9\n"},{"id":"179216","messageId":"1320872495-7545-4-git-send-email-gitster@pobox.com","threadId":"28897","inReplyTo":"1320872495-7545-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/3] commit-tree: teach -x <extra>","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-09T21:01:35Z","receivedAt":"2011-11-09T21:01:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"By feeding the header part of the original commit with this parameter,\ne.g. -x \"$(git cat-file commit $commit | sed -n -e /^$/q -e p)\", extra\nheaders of another commit can be transplanted to the resulting commit.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-commit-tree.txt |    3 ++-\n builtin/commit-tree.c             |   20 ++++++++++++++++++--\n 2 files changed, 20 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt\nindex cfb9906..060e79d 100644\n--- a/Documentation/git-commit-tree.txt\n+++ b/Documentation/git-commit-tree.txt\n@@ -10,7 +10,8 @@ SYNOPSIS\n --------\n [verse]\n 'git commit-tree' <tree> [(-p <parent>)...] < changelog\n-'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree>\n+'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...]\n+    [(-x <extra>)...]<tree>\n \n DESCRIPTION\n -----------\ndiff --git a/builtin/commit-tree.c b/builtin/commit-tree.c\nindex db5b6e5..8b0a223 100644\n--- a/builtin/commit-tree.c\n+++ b/builtin/commit-tree.c\n@@ -9,7 +9,7 @@\n #include \"builtin.h\"\n #include \"utf8.h\"\n \n-static const char commit_tree_usage[] = \"git commit-tree [(-p <sha1>)...] [-m <message>] <sha1> < changelog\";\n+static const char commit_tree_usage[] = \"git commit-tree [(-p <sha1>)...] [-m <message>] [-x <extra>] <sha1> < changelog\";\n \n static void new_parent(struct commit *parent, struct commit_list **parents_p)\n {\n@@ -32,6 +32,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \tunsigned char tree_sha1[20];\n \tunsigned char commit_sha1[20];\n \tstruct strbuf buffer = STRBUF_INIT;\n+\tstruct commit_extra_header *extra = NULL, **extra_tail = &extra;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -86,6 +87,20 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \t\t}\n \n+\t\tif (!strcmp(arg, \"-x\")) {\n+\t\t\tstruct commit_extra_header *x;\n+\t\t\tif (argc <= ++i)\n+\t\t\t\tusage(commit_tree_usage);\n+\t\t\tx = read_commit_extra_header_lines(argv[i], strlen(argv[i]));\n+\t\t\tif (x) {\n+\t\t\t\t*extra_tail = x;\n+\t\t\t\twhile (x->next)\n+\t\t\t\t\tx = x->next;\n+\t\t\t\textra_tail = &x->next;\n+\t\t\t}\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\tif (get_sha1(arg, tree_sha1))\n \t\t\tdie(\"Not a valid object name %s\", arg);\n \t\tif (got_tree)\n@@ -98,7 +113,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t\t\tdie_errno(\"git commit-tree: failed to read\");\n \t}\n \n-\tif (commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {\n+\tif (commit_tree_extended(buffer.buf, tree_sha1, parents, commit_sha1,\n+\t\t\t\t NULL, extra)) {\n \t\tstrbuf_release(&buffer);\n \t\treturn 1;\n \t}\n-- \n1.7.8.rc1.82.gde0f9\n"},{"id":"179221","messageId":"4EBAFC54.1090403@kitware.com","threadId":"28897","inReplyTo":"1320872495-7545-4-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 3/3] commit-tree: teach -x <extra>","fromName":"Brad King","fromEmail":"brad.king@kitware.com","sentAt":"2011-11-09T22:19:00Z","receivedAt":"2011-11-09T22:19:00Z","isPatch":true,"sender":{"key":"brad.king@kitware.com","avatar":"https://avatars.githubusercontent.com/u/87268?v=4"},"body":"On 11/9/2011 4:01 PM, Junio C Hamano wrote:\n> By feeding the header part of the original commit with this parameter,\n> e.g. -x \"$(git cat-file commit $commit | sed -n -e /^$/q -e p)\", extra\n> headers of another commit can be transplanted to the resulting commit.\n\nOne of the interface features typical in git plumbing that I've always liked\nis that any place that can pass long strings tends to be implemented using\npipes or files, at least optionally.  This is especially helpful for operating\nsystems that have severe limitations on total command line size.\n\nI suggest a flag (-X ?) that tells commit-tree to treat the commit message\n(from wherever it is read) in \"cat-file commit\" format.  Read the extra\nheader lines from the part before the blank line, and the rest of the message\nnormally after the blank line.  For example:\n\n  (git cat-file commit $commit | sed -n -e /^$/q -e p\n   echo ''\n   echo 'New commit message') |\n  git commit-tree -X -p $parent $tree\n\nIf we want the original extended headers and the original message:\n\n  git cat-file commit $commit | git commit-tree -X -p $parent $tree\n\n-Brad\n"}]}