{"thread":{"id":"897","subject":"[PATCH] Add script for patch submission via e-mail.","startedAt":"2005-06-11T01:32:30Z","lastAt":"2005-07-05T20:19:05Z","messageCount":6,"participants":["Junio C Hamano","Petr Baudis","Jon Seymour"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"4842","messageId":"7vll5h7k5t.fsf@assigned-by-dhcp.cox.net","threadId":"897","inReplyTo":null,"subject":"[PATCH] Add script for patch submission via e-mail.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-06-11T01:32:30Z","receivedAt":"2005-06-11T01:32:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This git-format-patch-script is what I use to prepare patches\nfor e-mail submission.\n\nTypical usage is:\n\n$ git-format-patch-script -B -C --find-copies-harder HEAD linus\n\nto prepare each commit with its patch since \"HEAD\" forked from\n\"linus\", one file per patch for e-mail submission.  Each output\nfile is numbered sequentially from 1, and uses the first line of\nthe commit message (massaged for pathname safety) as the\nfilename.\n\n$ git-format-patch-script -B -C --find-copies-harder HEAD linus .patch/\n\ncreates output files in .patch/ directory.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n*** Linus I am submitting this one because some patches on\n*** read-tree I am going to send you will need this for\n*** formatting into a form that is easier to review.  And this\n*** in turn can use diff-tree --find-copies-harder, which I\n*** indeed used to generate the patches that follow.\n\n Makefile                |    3 +-\n git-format-patch-script |   93 +++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 95 insertions(+), 1 deletions(-)\n\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -23,7 +23,8 @@ INSTALL=install\n SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \\\n \tgit-pull-script git-tag-script git-resolve-script git-whatchanged \\\n \tgit-deltafy-script git-fetch-script git-status-script git-commit-script \\\n-\tgit-log-script git-shortlog git-cvsimport-script\n+\tgit-log-script git-shortlog git-cvsimport-script \\\n+\tgit-format-patch-script\n \n PROG=   git-update-cache git-diff-files git-init-db git-write-tree \\\n \tgit-read-tree git-commit-tree git-cat-file git-fsck-cache \\\ndiff --git a/git-format-patch-script b/git-format-patch-script\nnew file mode 100755\n--- /dev/null\n+++ b/git-format-patch-script\n@@ -0,0 +1,93 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano\n+#\n+# Typical usage is:\n+#\n+# $ git-format-patch-script -B -C --find-copies-harder HEAD linus\n+#\n+# to prepare each commit with its patch since \"HEAD\" forked from\n+# \"linus\", one file per patch for e-mail submission.  Each output file is\n+# numbered sequentially from 1, and uses the first line of the commit\n+# message (massaged for pathname safety) as the filename.\n+#\n+# $ git-format-patch-script -B -C --find-copies-harder HEAD linus .patch/\n+#\n+# creates output files in .patch/ directory.\n+\n+diff_opts=\n+IFS='\n+'\n+LF='\n+'\n+while case \"$#\" in 0) break;; esac\n+do\n+    case \"$1\" in\n+    -*)\tdiff_opts=\"$diff_opts$LF$1\" ;;\n+    *) break ;;\n+    esac\n+    shift\n+done\n+\n+junio=\"$1\"\n+linus=\"$2\"\n+outdir=\"${3:-./}\"\n+\n+tmp=.tmp-series$$\n+trap 'rm -f $tmp-*' 0 1 2 3 15\n+\n+series=$tmp-series\n+\n+titleScript='\n+\t1,/^$/d\n+\t: loop\n+\t/^$/b loop\n+\ts/[^-a-z.A-Z_0-9]/-/g\n+\ts/^--*//g\n+\ts/--*$//g\n+\ts/---*/-/g\n+\ts/$/.txt/\n+        s/\\.\\.\\.*/\\./g\n+\tq\n+'\n+\n+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n+_x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+stripCommitHead='/^'\"$_x40\"' (from '\"$_x40\"')$/d'\n+\n+O=\n+if test -f .git/patch-order\n+then\n+    O=-O.git/patch-order\n+fi\n+git-rev-list \"$junio\" \"^$linus\" >$series\n+total=`wc -l <$series`\n+i=$total\n+while read commit\n+do\n+    title=`git-cat-file commit \"$commit\" | sed -e \"$titleScript\"`\n+    num=`printf \"%d/%d\" $i $total`\n+    file=`printf '%04d-%s' $i \"$title\"`\n+    i=`expr \"$i\" - 1`\n+    echo \"$file\"\n+    {\n+\tmailScript='\n+\t1,/^$/d\n+\t: loop\n+\t/^$/b loop\n+\ts|^|[PATCH '\"$num\"'] |\n+\t: body\n+\tp\n+\tn\n+\tb body'\n+\n+\tgit-cat-file commit \"$commit\" | sed -ne \"$mailScript\"\n+\techo '---'\n+\techo\n+\tgit-diff-tree -p $diff_opts $O \"$commit\" | git-apply --stat\n+\techo\n+\tgit-diff-tree -p $diff_opts $O \"$commit\" | sed -e \"$stripCommitHead\"\n+\techo '------------'\n+    } >\"$outdir$file\"\n+done <$series\n+\n------------\n\n"},{"id":"5663","messageId":"20050705093441.GD6191@pasky.ji.cz","threadId":"897","inReplyTo":"7vll5h7k5t.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add script for patch submission via e-mail.","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-07-05T09:34:41Z","receivedAt":"2005-07-05T09:34:41Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sat, Jun 11, 2005 at 03:32:30AM CEST, I got a letter\nwhere Junio C Hamano <junkio@cox.net> told me that...\n> This git-format-patch-script is what I use to prepare patches\n> for e-mail submission.\n> \n> Typical usage is:\n> \n> $ git-format-patch-script -B -C --find-copies-harder HEAD linus\n> \n> to prepare each commit with its patch since \"HEAD\" forked from\n> \"linus\", one file per patch for e-mail submission.  Each output\n> file is numbered sequentially from 1, and uses the first line of\n> the commit message (massaged for pathname safety) as the\n> filename.\n> \n> $ git-format-patch-script -B -C --find-copies-harder HEAD linus .patch/\n> \n> creates output files in .patch/ directory.\n> \n> Signed-off-by: Junio C Hamano <junkio@cox.net>\n> ---\n> *** Linus I am submitting this one because some patches on\n> *** read-tree I am going to send you will need this for\n> *** formatting into a form that is easier to review.  And this\n> *** in turn can use diff-tree --find-copies-harder, which I\n> *** indeed used to generate the patches that follow.\n\nAny reason why this was not applied? It appears kind of cool. Well, I\nwill probably take it and extend cg-mkpatch with it so I don't need it\nin Git, but I'm so altruistic and want to bring at least a bit of light\nto the gloomy dark world of the poor core Git plumbing users.  ;-)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\n<Espy> be careful, some twit might quote you out of context..\n"},{"id":"5664","messageId":"2cfc40320507050239605e8d3a@mail.gmail.com","threadId":"897","inReplyTo":"20050705093441.GD6191@pasky.ji.cz","subject":"Re: [PATCH] Add script for patch submission via e-mail.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2005-07-05T09:39:10Z","receivedAt":"2005-07-05T09:39:10Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On 7/5/05, Petr Baudis <pasky@suse.cz> wrote:\n> \n> Any reason why this was not applied? It appears kind of cool. Well, I\n> will probably take it and extend cg-mkpatch with it so I don't need it\n> in Git, but I'm so altruistic and want to bring at least a bit of light\n> to the gloomy dark world of the poor core Git plumbing users.  ;-)\n\nAs one who inhabits that dark world, I second that!\n\njon.\n"},{"id":"5667","messageId":"7vekadfff6.fsf@assigned-by-dhcp.cox.net","threadId":"897","inReplyTo":"20050705093441.GD6191@pasky.ji.cz","subject":"Re: [PATCH] Add script for patch submission via e-mail.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-05T15:20:13Z","receivedAt":"2005-07-05T15:20:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"PB\" == Petr Baudis <pasky@suse.cz> writes:\n\nPB> Any reason why this was not applied? It appears kind of cool.\n\nFYI, the one in <7vll4s47p3.fsf_-_@assigned-by-dhcp.cox.net> is\nnewer than what you quoted.\n\nOne thing _I_ am unhappy about what it does is that it does not\ntry to be intelligent about merges (I haven't tried the script\non a merged head myself).\n\nWhen you think about \"project lead\" vs \"individual developer\"\nmodes of operation, the latter is primarily \"keep rebasing\ncommits in my fork and re-throwing them upstream until some of\nthem stick\", so not supporting merges specially would not be so\nbig a flaw.  However, at least it should use --merge-order to\nget the epochs decomposed right, in order to produce anything\nremotely useful when dealing with a merged head.\n"},{"id":"5668","messageId":"2cfc403205070509181469b9fa@mail.gmail.com","threadId":"897","inReplyTo":"7vekadfff6.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add script for patch submission via e-mail.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2005-07-05T16:18:15Z","receivedAt":"2005-07-05T16:18:15Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On 7/6/05, Junio C Hamano <junkio@cox.net> wrote:\n> >>>>> \"PB\" == Petr Baudis <pasky@suse.cz> writes:\n> \n> PB> Any reason why this was not applied? It appears kind of cool.\n> \n> FYI, the one in <7vll4s47p3.fsf_-_@assigned-by-dhcp.cox.net> is\n> newer than what you quoted.\n> \n> One thing _I_ am unhappy about what it does is that it does not\n> try to be intelligent about merges (I haven't tried the script\n> on a merged head myself).\n\nI am not completely sure this is really a problem. I would presume\nthat the project lead doesn't really need to use\ngit-format-patch-script and the individual developer should probably\nrebase on the latest head which is either done by trivially reapplying\nthe patches in sequence automatically or reapplying the patches in\nsequence with some edits to fix any conflicts that have arisen.\n\nSo, it is not clear to me git-format-patch-script needs to worry about\nmerge questions. It'd be better to put such logic in a separate\nrebasing script, I think. If anything, you might want to add checks to\ngit-format-patch script that refuse to generate a patch sequence for\nany sequence of patches that spans a merge commit.\n\njon.\n-- \nhomepage: http://www.zeta.org.au/~jon/\nblog: http://orwelliantremors.blogspot.com/\n"},{"id":"5675","messageId":"7v7jg5dn0m.fsf@assigned-by-dhcp.cox.net","threadId":"897","inReplyTo":"20050705093441.GD6191@pasky.ji.cz","subject":"[PATCH] Add script for patch submission via e-mail.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-05T20:19:05Z","receivedAt":"2005-07-05T20:19:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"[PATCH] git-format-patch: Prepare patches for e-mail submission.\n\nThis is the script I use to prepare patches for e-mail submission.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n*** The latest incarnation.  Uses --merge-order while generating\n*** the list of patches to number them better.\n\n Makefile                |    3 +\n git-format-patch-script |  121 +++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 123 insertions(+), 1 deletions(-)\n create mode 100755 git-format-patch-script\n\n1a3c4d6335860c7bfd09b997b19c850620c6fb50\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -31,7 +31,8 @@ SCRIPTS=git git-apply-patch-script git-m\n \tgit-fetch-script git-status-script git-commit-script \\\n \tgit-log-script git-shortlog git-cvsimport-script git-diff-script \\\n \tgit-reset-script git-add-script git-checkout-script git-clone-script \\\n-\tgitk git-cherry git-rebase-script git-relink-script git-repack-script\n+\tgitk git-cherry git-rebase-script git-relink-script git-repack-script \\\n+\tgit-format-patch-script\n \n PROG=   git-update-cache git-diff-files git-init-db git-write-tree \\\n \tgit-read-tree git-commit-tree git-cat-file git-fsck-cache \\\ndiff --git a/git-format-patch-script b/git-format-patch-script\nnew file mode 100755\n--- /dev/null\n+++ b/git-format-patch-script\n@@ -0,0 +1,121 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano\n+#\n+\n+usage () {\n+    echo >&2 \"usage: $0\"' [-n] [-o dir] [-<diff options>...] upstream [ our-head ]\n+\n+Prepare each commit with its patch since our-head forked from upstream,\n+one file per patch, for e-mail submission.  Each output file is\n+numbered sequentially from 1, and uses the first line of the commit\n+message (massaged for pathname safety) as the filename.\n+\n+When -o is specified, output files are created in that directory; otherwise in\n+the current working directory.\n+\n+When -n is specified, instead of \"[PATCH] Subject\", the first line is formatted\n+as \"[PATCH N/M] Subject\", unless you have only one patch.\n+'\n+    exit 1\n+}\n+\n+diff_opts=\n+IFS='\n+'\n+LF='\n+'\n+outdir=./\n+\n+while case \"$#\" in 0) break;; esac\n+do\n+    case \"$1\" in\n+    -n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered)\n+    numbered=t ;;\n+    -o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\\\n+    --output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\\\n+    --output-direc=*|--output-direct=*|--output-directo=*|\\\n+    --output-director=*|--output-directory=*)\n+    outdir=`expr \"$1\" : '-[^=]*=\\(.*\\)'` ;;\n+    -o|--o|--ou|--out|--outp|--outpu|--output|--output-|--output-d|\\\n+    --output-di|--output-dir|--output-dire|--output-direc|--output-direct|\\\n+    --output-directo|--output-director|--output-directory)\n+    case \"$#\" in 1) usage ;; esac; shift\n+    outdir=\"$1\" ;;\n+    -*)\tdiff_opts=\"$diff_opts$LF$1\" ;;\n+    *) break ;;\n+    esac\n+    shift\n+done\n+\n+case \"$#\" in\n+2)    linus=\"$1\" junio=\"$2\" ;;\n+1)    linus=\"$1\" junio=HEAD ;;\n+*)    usage ;;\n+esac\n+\n+case \"$outdir\" in\n+*/) ;;\n+*) outdir=\"$outdir/\" ;;\n+esac\n+test -d \"$outdir\" || mkdir -p \"$outdir\" || exit\n+\n+tmp=.tmp-series$$\n+trap 'rm -f $tmp-*' 0 1 2 3 15\n+\n+series=$tmp-series\n+\n+titleScript='\n+\t1,/^$/d\n+\t: loop\n+\t/^$/b loop\n+\ts/[^-a-z.A-Z_0-9]/-/g\n+        s/\\.\\.\\.*/\\./g\n+\ts/\\.*$//\n+\ts/--*/-/g\n+\ts/^-//\n+\ts/-$//\n+\ts/$/./\n+\tq\n+'\n+\n+_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n+_x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+stripCommitHead='/^'\"$_x40\"' (from '\"$_x40\"')$/d'\n+\n+git-rev-list --merge-order \"$junio\" \"^$linus\" >$series\n+total=`wc -l <$series`\n+i=$total\n+while read commit\n+do\n+    title=`git-cat-file commit \"$commit\" | sed -e \"$titleScript\"`\n+    case \"$numbered\" in\n+    '') num= ;;\n+    *)\n+\tcase $total in\n+\t1) num= ;;\n+\t*) num=' '`printf \"%d/%d\" $i $total` ;;\n+\tesac\n+    esac\n+    file=`printf '%04d-%stxt' $i \"$title\"`\n+    i=`expr \"$i\" - 1`\n+    echo \"$file\"\n+    {\n+\tmailScript='\n+\t1,/^$/d\n+\t: loop\n+\t/^$/b loop\n+\ts|^|[PATCH'\"$num\"'] |\n+\t: body\n+\tp\n+\tn\n+\tb body'\n+\n+\tgit-cat-file commit \"$commit\" | sed -ne \"$mailScript\"\n+\techo '---'\n+\techo\n+\tgit-diff-tree -p $diff_opts \"$commit\" | git-apply --stat --summary\n+\techo\n+\tgit-diff-tree -p $diff_opts \"$commit\" | sed -e \"$stripCommitHead\"\n+    } >\"$outdir$file\"\n+done <$series\n"}]}