{"thread":{"id":"14895","subject":"[TopGit PATCH 2/2] tg-import.sh: A dump quilt queue importer","startedAt":"2008-08-08T18:19:47Z","lastAt":"2008-08-09T07:56:58Z","messageCount":4,"participants":["Bert Wesarg","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"86536","messageId":"1218219588-6849-1-git-send-email-bert.wesarg@googlemail.com","threadId":"14895","inReplyTo":null,"subject":"[TopGit PATCH 1/2] Factor out the template generation for the .topmsg file","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2008-08-08T18:19:47Z","receivedAt":"2008-08-08T18:19:47Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"Provide a function for the .topmsg template file.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n\n---\n tg-create.sh |   29 ++---------------------------\n tg.sh        |   30 ++++++++++++++++++++++++++++++\n 2 files changed, 32 insertions(+), 27 deletions(-)\n\ndiff --git a/tg-create.sh b/tg-create.sh\nindex d47959b..e30a014 100644\n--- a/tg-create.sh\n+++ b/tg-create.sh\n@@ -100,33 +100,8 @@ git checkout -b \"$name\"\n echo \"$deps\" | sed 's/ /\\n/g' >\"$root_dir/.topdeps\"\n git add \"$root_dir/.topdeps\"\n \n-# Print each config value for a key ($1, without \"topgit.\" prefix)\n-# with the given prefix ($2)\n-get_multi_config()\n-{\n-\t# escape any / in prefix for sed\n-\tprefix=\"$(echo \"$2\" | sed -e 's/\\//\\\\\\\\\\//g')\"\n-\n-\tgit config --get-all topgit.$1 2>/dev/null |\n-\t\tsed -e \"s/^/$prefix /g\"\n-}\n-\n-author=\"$(git var GIT_AUTHOR_IDENT)\"\n-author_addr=\"${author%> *}>\"\n-{\n-\techo \"From: $author_addr\"\n-\tget_multi_config to  \"To:\"\n-\tget_multi_config cc  \"Cc:\"\n-\tget_multi_config bcc \"Bcc:\"\n-\t! subject_prefix=\"$(git config topgit.subjectprefix)\" || subject_prefix=\"$subject_prefix \"\n-\techo \"Subject: [${subject_prefix}PATCH] $name\"\n-\techo\n-\tcat <<EOT\n-<patch description>\n-\n-Signed-off-by: $author_addr\n-EOT\n-} >\"$root_dir/.topmsg\"\n+echo \"<patch description>\" |\n+\tmake_topmsg \"$name\" >\"$root_dir/.topmsg\"\n git add \"$root_dir/.topmsg\"\n \n \ndiff --git a/tg.sh b/tg.sh\nindex 03a392b..8384b79 100644\n--- a/tg.sh\n+++ b/tg.sh\n@@ -148,6 +148,36 @@ switch_to_base()\n \tgit symbolic-ref HEAD \"$_base\"\n }\n \n+# Print each config value for a key ($1, without \"topgit.\" prefix)\n+# with the given prefix ($2)\n+get_multi_config()\n+{\n+\t# escape any / in prefix for sed\n+\tprefix=\"$(echo \"$2\" | sed -e 's/\\//\\\\\\\\\\//g')\"\n+\n+\tgit config --get-all topgit.$1 2>/dev/null |\n+\t\tsed -e \"s/^/$prefix /g\"\n+}\n+\n+# Make initial .topmsg template with content from stdin\n+# optional first argument is subject line\n+make_topmsg()\n+{\n+\tauthor=\"$(git var GIT_AUTHOR_IDENT)\"\n+\tauthor_addr=\"${author%> *}>\"\n+\n+\techo \"From: $author_addr\"\n+\tget_multi_config to  \"To:\"\n+\tget_multi_config cc  \"Cc:\"\n+\tget_multi_config bcc \"Bcc:\"\n+\t! subject_prefix=\"$(git config topgit.subjectprefix)\" || subject_prefix=\"$subject_prefix \"\n+\techo \"Subject: [${subject_prefix}PATCH] $1\"\n+\techo\n+\tcat\n+\techo\n+\techo \"Signed-off-by: $author_addr\"\n+}\n+\n # Show the help messages.\n do_help()\n {\n-- \ntg: (2a28314..) t/make-.topmsg-gen-a-function (depends on: t/support-for-multiple-to-cc-bcc-options)\n"},{"id":"86535","messageId":"1218219588-6849-2-git-send-email-bert.wesarg@googlemail.com","threadId":"14895","inReplyTo":"1218219588-6849-1-git-send-email-bert.wesarg@googlemail.com","subject":"[TopGit PATCH 2/2] tg-import.sh: A dump quilt queue importer","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2008-08-08T18:19:48Z","receivedAt":"2008-08-08T18:19:48Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"A simple, non smart, quilt importer.\n\nSigned-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n\n---\n .gitignore   |    2 +\n Makefile     |    3 +-\n README       |   15 ++++++++\n tg-import.sh |  115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 134 insertions(+), 1 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 6f0727f..5f1831b 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -3,6 +3,8 @@ tg-create\n tg-create.txt\n tg-delete\n tg-delete.txt\n+tg-import\n+tg-import.txt\n tg-info\n tg-info.txt\n tg-patch\ndiff --git a/Makefile b/Makefile\nindex dba5f20..671beab 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -6,7 +6,8 @@ sharedir = $(PREFIX)/share/topgit\n hooksdir = $(cmddir)/hooks\n \n \n-commands_in = tg-create.sh tg-delete.sh tg-info.sh tg-patch.sh tg-summary.sh tg-update.sh\n+commands_in = tg-create.sh tg-delete.sh tg-info.sh tg-patch.sh tg-summary.sh \\\n+              tg-update.sh tg-import.sh\n hooks_in = hooks/pre-commit.sh\n \n commands_out = $(patsubst %.sh,%,$(commands_in))\ndiff --git a/README b/README\nindex dc0045f..3fc6d18 100644\n--- a/README\n+++ b/README\n@@ -275,6 +275,21 @@ tg update\n \n \tTODO: tg update -a for updating all topic branches\n \n+tg import\n+~~~~~~~~~\n+\tImport a quilt queue into TopGit. First argument is the series\n+\tfile from quilt. Second is the prefix for the topic names\n+\t(i.e. \"t/\"). All remaining arguments are the dependencies for\n+\tthe first patch in the series. Use '-s' if you want to strip\n+\tcommon patch suffixes from the patch file name (like .diff and\n+\t.patch).\n+\n+\tTODO: be smart (merge conflicts, patch rejects, ...)\n+\tTODO: be interactive, let the user edit .topmsg for first commit\n+\tTODO: be resumable\n+\tTODO: use a dependency file, for creating non linear dependencies\n+\t      of the patches (maybe generated from quilt graph)\n+\n TODO: Some infrastructure for sharing topic branches between\n \trepositories easily\n TODO: tg depend for adding/removing dependencies smoothly\ndiff --git a/tg-import.sh b/tg-import.sh\nnew file mode 100644\nindex 0000000..f9403b9\n--- /dev/null\n+++ b/tg-import.sh\n@@ -0,0 +1,115 @@\n+#!/bin/sh\n+# TopGit - A different patch queue manager\n+# (c) Petr Baudis <pasky@suse.cz>  2008\n+# (c) Bert Wesarg <Bert.Wesarg@googlemail.com>  2008\n+# GPLv2\n+\n+series= # series file of patch queue\n+prefix= # prefix for branch names (i.e. \"t/\")\n+strip_suffixes= # strip suffixes like .{diff,patch}\n+\n+## Parse options\n+\n+while [ -n \"$1\" ]; do\n+\targ=\"$1\"\n+\tcase \"$arg\" in\n+\t-s)\n+\t\tstrip_suffixes=1\n+\t\tshift;;\n+\t-*)\n+\t\techo \"Usage: tg import [-s] SERIES PREFIX [DEPS...]\" >&2\n+\t\texit 1;;\n+\t*)\n+\t\tbreak;;\n+\tesac\n+done\n+\n+series=\"$1\"\n+prefix=\"$2\"\n+shift 2\n+# remaining args in \"$@\" are deps for first patch\n+\n+# check series file for existens and reading\n+[ -r \"$series\" ] ||\n+\tdie \"can't read series file '$series'\"\n+\n+# get dir of series file\n+dir=\"$(dirname \"$series\")\" ||\n+\tdie \"can't parse dir of series file '$series'\"\n+\n+# These two functions are from quilt, and we can use more from there\n+patch_header()\n+{\n+\tawk '\n+\t/^(---|\\*\\*\\*|Index:)[ \\t][^ \\t]|^diff -/ \\\n+\t\t{ exit }\n+\t\t{ print }\n+\t'\n+}\n+\n+strip_diffstat()\n+{\n+\tawk '\n+\t/#? .* \\| / \\\n+\t\t{ eat = eat $0 \"\\n\"\n+\t\t  next }\n+\t/^#? .* files? changed(, .* insertions?\\(\\+\\))?(, .* deletions?\\(-\\))?/ \\\n+\t\t{ eat = \"\"\n+\t\t  next }\n+\t\t{ print eat $0\n+\t\t  eat = \"\" }\n+\t'\n+}\n+\n+# escape $root_dir for sed expression\n+root_dir_esc=\"$(echo \"$root_dir\" | sed -e 's/\\//\\\\\\\\\\//g')\"\n+\n+cat \"$series\" |\n+\tsed -e 's/#.*//' \\      # remove any comments\n+\t    -e 's/^[ \\t]*//' \\  # remove leading whitespace\n+\t    -e 's/[ \\t].*//' |  # remove all after none leading whitespace\n+\tsed -e '/^$/d' |        # remove empty lines\n+\twhile read patch; do\n+\n+\t\tpatchfile=\"$dir/$patch\"\n+\t\t[ -r \"$patchfile\" ] ||\n+\t\t\tdie \"can't access patch file for '$patch'\"\n+\n+\t\t# strip suffixes\n+\t\tname=\"$patch\"\n+\t\t[ -n \"$strip_suffixes\" ] && {\n+\t\t\tname=\"${name%.patch}\"\n+\t\t\tname=\"${name%.diff}\"\n+\t\t}\n+\n+\t\t# for the first patch \"$@\" are the deps from the command line\n+\t\t# all others get zero deps\n+\t\ttg create \"${prefix}${name}\" \"$@\"\n+\n+\t\t# apply patch\n+\t\t# be stupid, hard coded -p1\n+\t\t# currently no support for compressed patch files\n+\t\tpatch -p1 -d \"$root_dir\" < \"$patchfile\"\n+\n+\t\t# extract header from patch file and feed it into .topmsg\n+\t\t# TODO: extract mail headers\n+\t\tcat \"$patchfile\" |\n+\t\t\tpatch_header |\n+\t\t\tstrip_diffstat |\n+\t\t\tmake_topmsg \"$name\" > \"$root_dir/.topmsg\"\n+\t\t# overwrite .topmsg from tg create in index\n+\t\tgit add \"$root_dir/.topmsg\"\n+\n+\t\t# add all modified files from patch to index\n+\t\t# (and prepending it with $root_dir)\n+\t\t# be stupid, hard coded -p1 --strip=1\n+\t\tlsdiff --strip=1 \"$patchfile\" |\n+\t\t\tsed -e \"s/^/$root_dir_esc\\//\" |\n+\t\t\txargs git add\n+\n+\t\t# commit changes to git\n+\t\tgit commit -m \"import of quilt patch '$patch'\"\n+\n+\t\t# clean deps after first create\n+\t\tset --\n+\tdone\n-- \ntg: (63c1934..) t/tg-import (depends on: t/auto-generate-command-list-for-tg.sh t/check-read-permissions-of-help-files t/mkdir-bindir t/make-.topmsg-gen-a-function t/its-info-attributes)\n"},{"id":"86566","messageId":"20080809005736.GR10151@machine.or.cz","threadId":"14895","inReplyTo":"1218219588-6849-2-git-send-email-bert.wesarg@googlemail.com","subject":"Re: [TopGit PATCH 2/2] tg-import.sh: A dump quilt queue importer","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-08-09T00:57:36Z","receivedAt":"2008-08-09T00:57:36Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Aug 08, 2008 at 08:19:48PM +0200, Bert Wesarg wrote:\n> A simple, non smart, quilt importer.\n> \n> Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>\n> \n> ---\n>  .gitignore   |    2 +\n>  Makefile     |    3 +-\n>  README       |   15 ++++++++\n>  tg-import.sh |  115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n>  4 files changed, 134 insertions(+), 1 deletions(-)\n> \n> diff --git a/.gitignore b/.gitignore\n> index 6f0727f..5f1831b 100644\n> --- a/.gitignore\n> +++ b/.gitignore\n> @@ -3,6 +3,8 @@ tg-create\n>  tg-create.txt\n>  tg-delete\n>  tg-delete.txt\n> +tg-import\n> +tg-import.txt\n>  tg-info\n>  tg-info.txt\n>  tg-patch\n> diff --git a/Makefile b/Makefile\n> index dba5f20..671beab 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -6,7 +6,8 @@ sharedir = $(PREFIX)/share/topgit\n>  hooksdir = $(cmddir)/hooks\n>  \n>  \n> -commands_in = tg-create.sh tg-delete.sh tg-info.sh tg-patch.sh tg-summary.sh tg-update.sh\n> +commands_in = tg-create.sh tg-delete.sh tg-info.sh tg-patch.sh tg-summary.sh \\\n> +              tg-update.sh tg-import.sh\n>  hooks_in = hooks/pre-commit.sh\n>  \n>  commands_out = $(patsubst %.sh,%,$(commands_in))\n> diff --git a/README b/README\n> index dc0045f..3fc6d18 100644\n> --- a/README\n> +++ b/README\n> @@ -275,6 +275,21 @@ tg update\n>  \n>  \tTODO: tg update -a for updating all topic branches\n>  \n> +tg import\n> +~~~~~~~~~\n> +\tImport a quilt queue into TopGit. First argument is the series\n> +\tfile from quilt. Second is the prefix for the topic names\n> +\t(i.e. \"t/\"). All remaining arguments are the dependencies for\n> +\tthe first patch in the series.\n\nSensible usage, but I'm not happy with making tg import quilt-only;\nwhat if we will say want to import to topgit from existing branches,\nor from StGIT or something else? The command name is good, but maybe\nI'd add a required --quilt switch. After all, this is not a command you\nrun three times a day by hand.\n\n> + Use '-s' if you want to strip\n> +\tcommon patch suffixes from the patch file name (like .diff and\n> +\t.patch).\n\nWhen *wouldn't* we want to do this? Doesn't it make sense to make this\nthe default?\n\n> diff --git a/tg-import.sh b/tg-import.sh\n> new file mode 100644\n> index 0000000..f9403b9\n> --- /dev/null\n> +++ b/tg-import.sh\n\nI think the functionality is good to have, but you are also reinventing\nthe wheel here. Git can already import quilt series by git-quiltimport.\nSo what about a more general approach?\n\n* Build tg-import so that it primarily just imports given set of\n  existing commits.\n* Then, StGIT and Quilt importers are trivial extensions?\n\n> +\t\t# strip suffixes\n> +\t\tname=\"$patch\"\n> +\t\t[ -n \"$strip_suffixes\" ] && {\n> +\t\t\tname=\"${name%.patch}\"\n> +\t\t\tname=\"${name%.diff}\"\n> +\t\t}\n\nI think in these cases, it's better style to use plain if.\n\n> +\t\t# apply patch\n> +\t\t# be stupid, hard coded -p1\n> +\t\t# currently no support for compressed patch files\n> +\t\tpatch -p1 -d \"$root_dir\" < \"$patchfile\"\n> +\n> +\t\t# extract header from patch file and feed it into .topmsg\n> +\t\t# TODO: extract mail headers\n> +\t\tcat \"$patchfile\" |\n> +\t\t\tpatch_header |\n> +\t\t\tstrip_diffstat |\n> +\t\t\tmake_topmsg \"$name\" > \"$root_dir/.topmsg\"\n> +\t\t# overwrite .topmsg from tg create in index\n> +\t\tgit add \"$root_dir/.topmsg\"\n> +\n> +\t\t# add all modified files from patch to index\n> +\t\t# (and prepending it with $root_dir)\n> +\t\t# be stupid, hard coded -p1 --strip=1\n> +\t\tlsdiff --strip=1 \"$patchfile\" |\n> +\t\t\tsed -e \"s/^/$root_dir_esc\\//\" |\n> +\t\t\txargs git add\n\nlsdiff? I don't have this tool. And this won't work with file removals\nproperly anyway.\n\nI guess git add -u is too new for us, so you might opt for this snippet\nI've used in git-filter-branch:\n\n\t(\n\t\tgit diff-index -r --name-only HEAD\n\t\tgit ls-files --others\n\t) |\n\tgit update-index --add --replace --remove --stdin\n\nOr even better, use git apply?\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nThe next generation of interesting software will be done\non the Macintosh, not the IBM PC.  -- Bill Gates\n"},{"id":"86582","messageId":"36ca99e90808090056n63ce97bduc64a24a524eae2b9@mail.gmail.com","threadId":"14895","inReplyTo":"20080809005736.GR10151@machine.or.cz","subject":"Re: [TopGit PATCH 2/2] tg-import.sh: A dump quilt queue importer","fromName":"Bert Wesarg","fromEmail":"bert.wesarg@googlemail.com","sentAt":"2008-08-09T07:56:58Z","receivedAt":"2008-08-09T07:56:58Z","isPatch":true,"sender":{"key":"bert.wesarg@googlemail.com","avatar":"https://avatars.githubusercontent.com/u/111934?v=4"},"body":"On Sat, Aug 9, 2008 at 02:57, Petr Baudis <pasky@suse.cz> wrote:\n> On Fri, Aug 08, 2008 at 08:19:48PM +0200, Bert Wesarg wrote:\n>> +tg import\n>> +~~~~~~~~~\n>> +     Import a quilt queue into TopGit. First argument is the series\n>> +     file from quilt. Second is the prefix for the topic names\n>> +     (i.e. \"t/\"). All remaining arguments are the dependencies for\n>> +     the first patch in the series.\n>\n> Sensible usage, but I'm not happy with making tg import quilt-only;\n> what if we will say want to import to topgit from existing branches,\n> or from StGIT or something else? The command name is good, but maybe\n> I'd add a required --quilt switch. After all, this is not a command you\n> run three times a day by hand.\nYour absolutly right, that import should not be quilt specific. It was\njust what I currently need, so I made it.\n\n>\n>> + Use '-s' if you want to strip\n>> +     common patch suffixes from the patch file name (like .diff and\n>> +     .patch).\n>\n> When *wouldn't* we want to do this? Doesn't it make sense to make this\n> the default?\nI suggest never ;-)\n\n>> +             # add all modified files from patch to index\n>> +             # (and prepending it with $root_dir)\n>> +             # be stupid, hard coded -p1 --strip=1\n>> +             lsdiff --strip=1 \"$patchfile\" |\n>> +                     sed -e \"s/^/$root_dir_esc\\//\" |\n>> +                     xargs git add\n>\n> lsdiff? I don't have this tool. And this won't work with file removals\n> properly anyway.\nlsdiff comes with the patchutils package.\n\n>\n> I guess git add -u is too new for us, so you might opt for this snippet\n> I've used in git-filter-branch:\n>\n>        (\n>                git diff-index -r --name-only HEAD\n>                git ls-files --others\n>        ) |\n>        git update-index --add --replace --remove --stdin\n>\n> Or even better, use git apply?\nOhh yeah, that sounds reasonable. Sometimes it an be so easy.\n\nThanks for the comments and input.\n\nBert\n>\n> --\n>                                Petr \"Pasky\" Baudis\n"}]}