{"thread":{"id":"18556","subject":"[PATCH 01/10] refs: add \"for_each_bisect_ref\" function","startedAt":"2009-03-26T04:55:09Z","lastAt":"2009-03-27T07:22:00Z","messageCount":12,"participants":["Christian Couder","Sverre Rabbelier","Michael J Gruber","Johannes Schindelin","Julian Phillips"],"isPatch":true,"patchVersion":1,"patchTotal":10},"messages":[{"id":"109477","messageId":"20090326055509.1bc16b28.chriscool@tuxfamily.org","threadId":"18556","inReplyTo":null,"subject":"[PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-26T04:55:09Z","receivedAt":"2009-03-26T04:55:09Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n refs.c |    5 +++++\n refs.h |    1 +\n 2 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 8d3c502..2b21148 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -662,6 +662,11 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data)\n \treturn do_for_each_ref(\"refs/remotes/\", fn, 13, 0, cb_data);\n }\n \n+int for_each_bisect_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn do_for_each_ref(\"refs/bisect/\", fn, 12, 0, cb_data);\n+}\n+\n int for_each_rawref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(\"refs/\", fn, 0,\ndiff --git a/refs.h b/refs.h\nindex 29bdcec..e5d6e80 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -23,6 +23,7 @@ extern int for_each_ref(each_ref_fn, void *);\n extern int for_each_tag_ref(each_ref_fn, void *);\n extern int for_each_branch_ref(each_ref_fn, void *);\n extern int for_each_remote_ref(each_ref_fn, void *);\n+extern int for_each_bisect_ref(each_ref_fn, void *);\n \n /* can be used to learn about broken ref and symref */\n extern int for_each_rawref(each_ref_fn, void *);\n-- \n1.6.2.1.317.g3d804\n"},{"id":"109489","messageId":"fabb9a1e0903252320j2edf4a8ct39f784c4319c3cb0@mail.gmail.com","threadId":"18556","inReplyTo":"20090326055509.1bc16b28.chriscool@tuxfamily.org","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-03-26T06:20:25Z","receivedAt":"2009-03-26T06:20:25Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya\n\nOn Thu, Mar 26, 2009 at 05:55, Christian Couder <chriscool@tuxfamily.org> wrote:\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n\nA 10 patches series with no cover letter? And no description of the\nindividual patches either! C'mon Christian, you know better than that\n;).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"109499","messageId":"200903260848.42104.chriscool@tuxfamily.org","threadId":"18556","inReplyTo":"fabb9a1e0903252320j2edf4a8ct39f784c4319c3cb0@mail.gmail.com","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-26T07:48:41Z","receivedAt":"2009-03-26T07:48:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Sverre,\n\nLe jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n> Heya\n>\n> On Thu, Mar 26, 2009 at 05:55, Christian Couder <chriscool@tuxfamily.org> \nwrote:\n> > Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>\n> A 10 patches series with no cover letter? \n\nI am not a big fan of cover letters. Usually I prefer adding comments in the \npatches.\n\n> And no description of the \n> individual patches either! \n\nThere is a commit message in each patch. And many of the patches are very \nsmall.\n\n> C'mon Christian, you know better than that \n> ;).\n\nIf some commit messages are not clear enough, please tell me and I will try \nto improve them ;)\n\nRegards,\nChristian.\n"},{"id":"109524","messageId":"fabb9a1e0903260537r61647d82t4ffb6b8b67d5c2f1@mail.gmail.com","threadId":"18556","inReplyTo":"200903260848.42104.chriscool@tuxfamily.org","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-03-26T12:37:14Z","receivedAt":"2009-03-26T12:37:14Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Mar 26, 2009 at 08:48, Christian Couder <chriscool@tuxfamily.org> wrote:\n> I am not a big fan of cover letters. Usually I prefer adding comments in the\n> patches.\n\nThe downside of that is that it makes it harder to quickly scan the\nseries; now I have to go through each patch (which involves trying\nfinding which patch is next, as my MUA is retarded and doesn't\nunderstand proper threading).\n\n>> And no description of the\n>> individual patches either!\n>\n> There is a commit message in each patch. And many of the patches are very\n> small.\n\nHehe, my bad; the first one didn't have a commit message, which is the\none I looked at first.\n\n> If some commit messages are not clear enough, please tell me and I will try\n> to improve them ;)\n\nThe rest of the series is nicely readable, I guess I shouldn't send\nwhine mails before reading the entire series next time :).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"109547","messageId":"49CBA42D.3000404@drmicha.warpmail.net","threadId":"18556","inReplyTo":"200903260848.42104.chriscool@tuxfamily.org","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-03-26T15:50:05Z","receivedAt":"2009-03-26T15:50:05Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Christian Couder venit, vidit, dixit 26.03.2009 08:48:\n> Hi Sverre,\n> \n> Le jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n>> Heya\n>>\n>> On Thu, Mar 26, 2009 at 05:55, Christian Couder <chriscool@tuxfamily.org> \n> wrote:\n>>> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n>>\n>> A 10 patches series with no cover letter? \n> \n> I am not a big fan of cover letters. Usually I prefer adding comments in the \n> patches.\n\nI'm sorry I have to say that, but your individual preferences don't\nmatter. Many of us would do things differently, each in their own way,\nbut people adjust to the list's preferences. It's a matter of attitude.\nSo, please...\n\nCheers,\nMichael\n\n> \n>> And no description of the \n>> individual patches either! \n> \n> There is a commit message in each patch. And many of the patches are very \n> small.\n> \n>> C'mon Christian, you know better than that \n>> ;).\n> \n> If some commit messages are not clear enough, please tell me and I will try \n> to improve them ;)\n> \n> Regards,\n> Christian.\n"},{"id":"109553","messageId":"alpine.DEB.1.00.0903261748280.12753@intel-tinevez-2-302","threadId":"18556","inReplyTo":"49CBA42D.3000404@drmicha.warpmail.net","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-26T16:52:21Z","receivedAt":"2009-03-26T16:52:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 26 Mar 2009, Michael J Gruber wrote:\n\n> Christian Couder venit, vidit, dixit 26.03.2009 08:48:\n> \n> > Le jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n> >\n> >> A 10 patches series with no cover letter?\n> > \n> > I am not a big fan of cover letters. Usually I prefer adding comments \n> > in the patches.\n> \n> I'm sorry I have to say that, but your individual preferences don't \n> matter. Many of us would do things differently, each in their own way, \n> but people adjust to the list's preferences. It's a matter of attitude. \n> So, please...\n\nActually, a better way to ask for a cover letter would have been to \nconvince Christian.  So I'll try that.\n\n>From the patch series' titles (especially when they are cropped due to the \ntext window being too small to fit the indented thread), it is not all \nthat obvious what you want to achieve with those 10 patches.\n\n>From recent discussions, I seem to remember that you wanted to have some \ncute way to mark commits as non-testable during a bisect, and I further \nseem to remember that Junio said that very method should be usable outside \nof bisect, too.\n\nUnfortunately, that does not reveal to me, quickly, what is the current \nstate of affairs, and what you changed since the last time.\n\nIn addition, I am very sorry that I cannot review your patches; day job is \nkilling me right now.\n\nCiao,\nDscho\n"},{"id":"109554","messageId":"fabb9a1e0903260954u23bd7c7aq505e016e7a5c0c29@mail.gmail.com","threadId":"18556","inReplyTo":"alpine.DEB.1.00.0903261748280.12753@intel-tinevez-2-302","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-03-26T16:54:40Z","receivedAt":"2009-03-26T16:54:40Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Mar 26, 2009 at 17:52, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> > From the patch series' titles\n(especially when they are cropped due to the\n> text window being too small to fit the indented thread), it is not all\n> that obvious what you want to achieve with those 10 patches.\n\n<snip>\n\n> Unfortunately, that does not reveal to me, quickly, what is the current\n> state of affairs, and what you changed since the last time.\n\nThis is exactly what I meant to say, only worded much much better,\nthanks Johannes! :)\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"109587","messageId":"200903270141.57426.chriscool@tuxfamily.org","threadId":"18556","inReplyTo":"alpine.DEB.1.00.0903261748280.12753@intel-tinevez-2-302","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-27T00:41:57Z","receivedAt":"2009-03-27T00:41:57Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Le jeudi 26 mars 2009, Johannes Schindelin a écrit :\n> Hi,\n>\n> On Thu, 26 Mar 2009, Michael J Gruber wrote:\n> > Christian Couder venit, vidit, dixit 26.03.2009 08:48:\n> > > Le jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n> > >> A 10 patches series with no cover letter?\n> > >\n> > > I am not a big fan of cover letters. Usually I prefer adding comments\n> > > in the patches.\n> >\n> > I'm sorry I have to say that, but your individual preferences don't\n> > matter. Many of us would do things differently, each in their own way,\n> > but people adjust to the list's preferences. It's a matter of attitude.\n> > So, please...\n>\n> Actually, a better way to ask for a cover letter would have been to\n> convince Christian.  So I'll try that.\n\nThanks.\n\nAs you know, I have been sending patches since nearly 3 years ago to this \nlist. And it's only since a few weeks ago that I am asked to send cover \nletters...\n\n> From the patch series' titles (especially when they are cropped due to\n> the text window being too small to fit the indented thread), it is not\n> all that obvious what you want to achieve with those 10 patches.\n>\n> From recent discussions, I seem to remember that you wanted to have some\n> cute way to mark commits as non-testable during a bisect, and I further\n> seem to remember that Junio said that very method should be usable\n> outside of bisect, too.\n\nWell, we want to move \"git bisect skip\" code from shell (in \"git-bisect.sh\") \nto C. So this patch series does that by creating a new \"git bisect--helper\" \ncommand in C that contains the new code and using that new command \nin \"git-bisect.sh\".\n\n> Unfortunately, that does not reveal to me, quickly, what is the current\n> state of affairs, and what you changed since the last time.\n\nYeah, I should have at least put something in the comment section of my \nfirst patch in this series.\n\nAnd I try to improve, you know, I even tried to use \"git send-email\" again \nthis morning to see if perhaps I could use it to send my patch series.\n\nI did:\n\n$ git send-email --compose --dry-run bh15/*\nCan't call method \"repo_path\" on an undefined value \nat /home/christian/libexec/git-core//git-send-email line 160.\n\nand then I gave up, because I don't like spending a lot of my free time to \nfight with tools I don't like.\n\nIf someone knows some other tools that can easily send a threaded patch \nseries, I will try to see if I can use them...\n\nThanks in advance,\nChristian.\n"},{"id":"109589","messageId":"alpine.LNX.2.00.0903270126210.25399@reaper.quantumfyre.co.uk","threadId":"18556","inReplyTo":"200903270141.57426.chriscool@tuxfamily.org","subject":"sending patch sets (was: Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function)","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2009-03-27T01:32:10Z","receivedAt":"2009-03-27T01:32:10Z","isPatch":true,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 27 Mar 2009, Christian Couder wrote:\n\n> If someone knows some other tools that can easily send a threaded patch\n> series, I will try to see if I can use them...\n\nI long ago gave up on send-email, as it seemed to cumbersome for what I \nwanted, and my perl had got so rusty I really couldn't face trying to \nimprove it.\n\nSo I wrote a replacement in Python (attached), which I have subsequently \nused for all patches I've sent.  It calls format-patch, passing through \narguments (and you can use -- to let it pass options too).\n\n(the only setting it reads from git config atm is mail-commit.to)\n\nI find it much easier to use than send-email, but as usual YMMV ...\n\n-- \nJulian\n\n  ---\nHave you seen the latest Japanese camera?  Apparently it is so fast it can\nphotograph an American with his mouth shut!\n\n#!/usr/bin/python\n\nimport optparse\nimport os\nimport random\nimport re\nimport smtplib\nimport socket\nimport sys\nimport tempfile\nimport time\n\nfrom cStringIO import StringIO\nfrom email.Generator import Generator\nfrom email.Message import Message\nfrom email.Parser import FeedParser, Parser\nfrom email.Utils import parseaddr, parsedate, formatdate, \\\n                        getaddresses, formataddr\n\nmy_version = \"0.1\"\nmy_name = \"git-mail-commits\"\nthis_script = \"%s v%s\" % (my_name, my_version)\n\ngci_re = re.compile(\"^(?P<email>(.*) <(.*)>) (\\d+ [+-]\\d{4})$\")\n\nsmtp_server = \"neutron\"\n\n# -----------------------------------------------------------------------------\ndef get_message_text(message):\n    text_msg = StringIO()\n    gen = Generator(text_msg, mangle_from_=False)\n    gen.flatten(message)\n    return text_msg.getvalue()\n# -----------------------------------------------------------------------------\n\n# -----------------------------------------------------------------------------\ndef send_message(msg):\n    sent = (None, 'No destination address given')\n\n    (a, fromaddr) = parseaddr(msg.get('From'))\n    toaddr_list = msg.get_all('To', [])\n    ccaddr_list = msg.get_all('CC', [])\n    bccaddr_list = msg.get_all('BCC', [])\n    all_recips = getaddresses(toaddr_list + ccaddr_list + bccaddr_list)\n    to_list = [ email for (name, email) in all_recips ]\n\n    if len(to_list) > 0:\n        server = smtplib.SMTP(smtp_server)\n        try:\n            errors = server.sendmail(fromaddr, to_list, get_message_text(msg))\n            sent = (errors, \"Failed to send to one or more recipients\")\n        except smtplib.SMTPRecipientsRefused, rr:\n            sent = (rr.recipients, \"Failed to send to all recipients\")\n        server.quit()\n\n    return sent\n# -----------------------------------------------------------------------------\n\n# -----------------------------------------------------------------------------\ndef get_msgid(idstring=None, idhost=socket.getfqdn(), email=None):\n    \"\"\"Returns a string suitable for RFC 2822 compliant Message-ID, e.g:\n\n    <20020201195627.33539.96671@nightshade.la.mastaler.com>\n\n    Optional idstring if given is a string used to strengthen the\n    uniqueness of the message id.\n\n    Based on email.Utils.make_msgid\n    \"\"\"\n    timeval = time.time()\n    utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval))\n    pid = os.getpid()\n    randint = random.randrange(100000)\n    if email is not None:\n        ids = \".%s\" % (email)\n    else:\n        if idstring is None:\n            idstring = ''\n        else:\n            idstring = '.' + idstring\n        ids = \"%s@%s\" % (idstring, idhost)\n    msgid = '<%s.%s.%s%s>' % (utcdate, pid, randint, ids)\n    return msgid\n# -----------------------------------------------------------------------------\n\ndef get_patches(args, numbered=True, signoff=True):\n    patches = []\n    cur_patch = None\n#    print args\n    opts = ['-M']\n    if numbered:\n        opts.append(\"-n\")\n    if signoff:\n        opts.append(\"-s\")\n    fp = os.popen(\"git format-patch --stdout %s %s\" % (' '.join(opts),\n                                                       ' '.join(args)))\n    for line in fp.readlines():\n        if line[:5] == \"From \":\n            if cur_patch is not None:\n                patches.append(cur_patch.close())\n            cur_patch = FeedParser()\n        cur_patch.feed(line)\n    fp.close()\n    if cur_patch is not None:\n        patches.append(cur_patch.close())\n    return patches\n\ndef format_patches(patches, to, initial_msg_id=None,\n                   addr=None, cc_list=[]):\n    refs = []\n    if initial_msg_id is not None:\n        refs.append(initial_msg_id)\n    for patch in patches:\n        if addr is not None:\n            patch.replace_header(\"From\", addr)\n        if len(cc_list) > 0:\n            cc = [x.strip() for x in patch.get(\"CC\", \"\").split(\",\")]\n            if len(cc) == 1 and cc[0] == \"\":\n                cc = cc_list\n            else:\n                cc.extend(cc_list)\n            del patch['CC']\n            print cc\n            patch.add_header(\"CC\", \",\".join(cc))\n        subject = patch.get(\"Subject\")\n        (name, email) = parseaddr(patch.get(\"From\"))\n        sha1 = patch.get_unixfrom()[5:46]\n        msg_id = get_msgid(email=email)\n        patch.add_header(\"To\", to)\n        del patch['Message-Id']\n        patch.add_header(\"Message-Id\", msg_id)\n        patch.add_header(\"X-git-sha1\", sha1)\n        del patch['X-Mailer']\n        patch.add_header(\"X-Mailer\", this_script)\n        if len(refs) > 0:\n            del patch['In-Reply-To']\n            del patch['References']\n            patch.add_header(\"In-Reply-To\", refs[-1])\n            patch.add_header(\"References\", ' '.join(refs))\n        refs.append(msg_id)\n#        print \"%s - %s\" %(sha1[0:7], subject)\n#        print patch\n\ndef get_git_committer_email():\n    gv = os.popen(\"git var GIT_COMMITTER_IDENT\")\n    gci = gv.readline()\n    gv.close()\n#    print gci\n    gci_m = gci_re.search(gci)\n    if gci_m:\n        return gci_m.group('email')\n    else:\n        print \"Unable to get/parse GIT_COMMITTER_IDENT\"\n        sys.exit(-1)\n\ndef get_intro_msg(to, frm_addr, count, filename=None):\n    if filename is None:\n        if 'EDITOR' not in os.environ:\n            print \"$EDITOR not set, please set.\"\n            sys.exit(-1)\n        (fd, fname) = tempfile.mkstemp()\n        f = os.fdopen(fd)\n        ret = os.system(\"%s %s\" % (os.environ['EDITOR'], fname))\n        if not (os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0):\n            print \"Failed to edit intro message.\"\n            sys.exit(-1)\n    else:\n        f = open(filename)\n    slist = []\n    blist = []\n    cur = slist\n    for line in f.readlines():\n        if line == \"\\n\":\n            cur = blist\n            continue\n        cur.append(line)\n    f.close()\n    if filename is None:\n        os.remove(fname)\n    subject = ''.join(slist).replace('\\n', ' ')\n    body = ''.join(blist)\n    if subject == \"\":\n        print \"No subject for intro message, aborting.\"\n        sys.exit(-1)\n    msg = Message()\n    msg.add_header('From', frm_addr)\n    msg.add_header('To', to)\n    (name, email) = parseaddr(msg.get(\"From\"))\n    msg.add_header('Message-Id', get_msgid(email=email))\n    msg.set_payload(body)\n    msg.add_header('Subject', \"[PATCH 0/%d] %s\" % (count, subject))\n    msg.add_header(\"X-Mailer\", this_script)\n    return msg\n\ndef reply_to(fname):\n    p = Parser()\n    f = open(fname)\n    msg = p.parse(f)\n    f.close()\n    cc = [x.strip() for x in msg['CC'].split(',')]\n    return (msg['From'], msg['Message-ID'], cc)\n\ndef main():\n    description = \"send the given commits as patch emails to the specified \" \\\n                  \"address, all non-option arguments are passed to \" \\\n                  \"git-format-patch (\\\"--\\\" can be used to indicate the end \" \\\n                  \"of the options for this script).\"\n    \n    parser = optparse.OptionParser(description=description)\n    parser.disable_interspersed_args()\n\n    parser.add_option(\"\", \"--to\", action=\"store\", default=None,\n                      help=\"the address to send the mails to\")\n\n    parser.add_option(\"\", \"--cc\", action=\"append\", default=[],\n                      help=\"copy the mails to this address\")\n\n    parser.add_option(\"\", \"--reply-to\", action=\"store\", default=None,\n                      help=\"reply to the given mail (rather than use an intro)\")\n\n    parser.add_option(\"-n\", \"--numbered\", action=\"store_true\", default=False,\n                      help=\"send numbered patches (adds -n to the \"\n                      \"git-format-patch options)\")\n\n    parser.add_option(\"-f\", \"--from\", dest=\"frm_addr\", action=\"store\",\n                      default=None,\n                      help=\"set FROM as the from address, otherwise use \"\n                      \"GIT_COMMITTER_IDENT\")\n\n    parser.add_option(\"-i\", \"--intro\", dest=\"intro\", action=\"store_true\",\n                      help=\"start with a 0/n intro message using $EDITOR to \"\n                      \"write the message (implies -n).\")\n    parser.add_option(\"-I\", \"--intro-file\", dest=\"intro\", action=\"store\",\n                      help=\"start with a 0/n intro message read from INTRO \"\n                      \"(implies -n).\")\n    parser.set_defaults(intro=None)\n\n    parser.add_option(\"-e\", \"--edit\", action=\"store_true\", default=False,\n                      help=\"edit the patches before sending\")\n\n    parser.add_option(\"-S\", \"--no-signoff\", dest=\"signoff\",\n                      action=\"store_false\", default=True,\n                      help=\"Don't signoff the patches\")\n\n    (options, args) = parser.parse_args()\n\n    if len(args) < 1:\n        print \"You must specify at least one commit to send ...\"\n        sys.exit(-1)\n\n    if options.to is None:\n        gc = os.popen(\"git config mail-commits.to\")\n        to = gc.read()\n        gc.close()\n        if to == \"\":\n            print \"you must specify the destination using --to\"\n            sys.exit(-1)\n        else:\n            options.to = to.strip()\n\n    print \"Sending to: %s\\n\" % options.to\n\n    if options.frm_addr is not None:\n        frm_addr = options.frm_addr\n    else:        \n        frm_addr = get_git_committer_email()\n\n    if options.intro is not None:\n        options.numbered = True\n\n    patches = get_patches(args, options.numbered, signoff=options.signoff)\n\n    intro_msg = None\n    intro_msg_id = None\n    if options.intro is not None:\n        fname = None\n        if options.intro is not True:\n            fname = options.intro\n        intro_msg = get_intro_msg(options.to, frm_addr, len(patches),\n                                  filename=fname)\n        intro_msg_id = intro_msg.get('Message-Id')\n\n    if options.reply_to is not None:\n        (options.to, intro_msg_id, cc) = reply_to(options.reply_to)\n        options.cc.extend(cc)\n\n#    print intro_msg\n\n    format_patches(patches, to=options.to, cc_list=options.cc,\n                   initial_msg_id=intro_msg_id,\n                   addr=frm_addr)\n\n    if options.edit:\n        new_patches = []\n        for patch in patches:\n            (fd, fname) = tempfile.mkstemp()\n            f = os.fdopen(fd, \"w+\")\n            f.write(get_message_text(patch))\n            f.close()\n            if 'EDITOR' not in os.environ:\n                print \"$EDITOR not set, please set.\"\n                sys.exit(-1)\n            ret = os.system(\"%s %s\" % (os.environ['EDITOR'], fname))\n            if not (os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0):\n                print \"Failed to edit patch (%d).\" % ret\n                sys.exit(-1)\n            p = FeedParser()\n            f = open(fname)\n            for line in f:\n                p.feed(line)\n            m = p.close()\n            if m:\n                new_patches.append(m)\n            f.close()\n            os.remove(fname)\n        patches = new_patches\n\n    if intro_msg:\n        print intro_msg['Subject']\n    for patch in patches:\n        print patch['Subject']\n    print\n    print \"Press [Enter] to send patches, Ctrl-C to cancel.\"\n    try:\n        raw_input()\n    except KeyboardInterrupt:\n        print \"Not sending patches.\"\n        sys.exit(-1)\n\n    print \"Sending patches ...\\n\"\n\n    msgs=[intro_msg]\n    msgs.extend(patches)\n    for msg in msgs:\n        if msg is None:\n            continue\n        (errors, errmsg) = send_message(msg)\n        if len(errors) == 0:\n            print \"sent %s\" % msg['Subject']\n        else:\n            print \"error sending %s\" % msg['Subject']\n            for (name, (ecode, emsg)) in errors.items():\n                print \"  %s: %s %s\" % (name, ecode, emsg)\n\nif __name__ == \"__main__\":\n    main()\n"},{"id":"109592","messageId":"alpine.DEB.1.00.0903270305340.10279@pacific.mpi-cbg.de","threadId":"18556","inReplyTo":"200903270141.57426.chriscool@tuxfamily.org","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-03-27T02:08:55Z","receivedAt":"2009-03-27T02:08:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 27 Mar 2009, Christian Couder wrote:\n\n> Le jeudi 26 mars 2009, Johannes Schindelin a écrit :\n>\n> > On Thu, 26 Mar 2009, Michael J Gruber wrote:\n> > > Christian Couder venit, vidit, dixit 26.03.2009 08:48:\n> > > > Le jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n> > > >> A 10 patches series with no cover letter?\n> > > >\n> > > > I am not a big fan of cover letters. Usually I prefer adding \n> > > > comments in the patches.\n> > >\n> > > I'm sorry I have to say that, but your individual preferences don't \n> > > matter. Many of us would do things differently, each in their own \n> > > way, but people adjust to the list's preferences. It's a matter of \n> > > attitude. So, please...\n> >\n> > Actually, a better way to ask for a cover letter would have been to \n> > convince Christian.  So I'll try that.\n> \n> Thanks.\n> \n> As you know, I have been sending patches since nearly 3 years ago to \n> this list. And it's only since a few weeks ago that I am asked to send \n> cover letters...\n\nHeh, I have the feeling that your patch series were much shorter, and did \nnot have many revisions, until a few weeks ago ;-)\n\n> > From the patch series' titles (especially when they are cropped due to \n> > the text window being too small to fit the indented thread), it is not \n> > all that obvious what you want to achieve with those 10 patches.\n> >\n> > From recent discussions, I seem to remember that you wanted to have \n> > some cute way to mark commits as non-testable during a bisect, and I \n> > further seem to remember that Junio said that very method should be \n> > usable outside of bisect, too.\n> \n> Well, we want to move \"git bisect skip\" code from shell (in \n> \"git-bisect.sh\") to C. So this patch series does that by creating a new \n> \"git bisect--helper\" command in C that contains the new code and using \n> that new command in \"git-bisect.sh\".\n\nOh?  I _completely_ missed that.  And that's being one of the original \nCc:ed persons...\n\n> > Unfortunately, that does not reveal to me, quickly, what is the \n> > current state of affairs, and what you changed since the last time.\n> \n> Yeah, I should have at least put something in the comment section of my \n> first patch in this series.\n\nNo.  I would still have missed it.\n\nThe cover letter is outside of any patch, because it describes the purpose \nof the _whole_ patch series, not just one patch.\n\nSo, it would have been nice to get a heads-up that this is not your \nbisect-skip-a-whole-bunch-of-commits series, but a new animal.\n\nThis way, I decided I do not have time for something I do not need, and \ndeleted it without having a look.\n\nCiao,\nDscho\n"},{"id":"109617","messageId":"200903270821.03521.chriscool@tuxfamily.org","threadId":"18556","inReplyTo":"alpine.DEB.1.00.0903270305340.10279@pacific.mpi-cbg.de","subject":"Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-27T07:21:03Z","receivedAt":"2009-03-27T07:21:03Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Le vendredi 27 mars 2009, Johannes Schindelin a écrit :\n> Hi,\n>\n> On Fri, 27 Mar 2009, Christian Couder wrote:\n> > Le jeudi 26 mars 2009, Johannes Schindelin a écrit :\n> > > On Thu, 26 Mar 2009, Michael J Gruber wrote:\n> > > > Christian Couder venit, vidit, dixit 26.03.2009 08:48:\n> > > > > Le jeudi 26 mars 2009, Sverre Rabbelier a écrit :\n> > > > >> A 10 patches series with no cover letter?\n> > > > >\n> > > > > I am not a big fan of cover letters. Usually I prefer adding\n> > > > > comments in the patches.\n> > > >\n> > > > I'm sorry I have to say that, but your individual preferences don't\n> > > > matter. Many of us would do things differently, each in their own\n> > > > way, but people adjust to the list's preferences. It's a matter of\n> > > > attitude. So, please...\n> > >\n> > > Actually, a better way to ask for a cover letter would have been to\n> > > convince Christian.  So I'll try that.\n> >\n> > Thanks.\n> >\n> > As you know, I have been sending patches since nearly 3 years ago to\n> > this list. And it's only since a few weeks ago that I am asked to send\n> > cover letters...\n>\n> Heh, I have the feeling that your patch series were much shorter, and did\n> not have many revisions, until a few weeks ago ;-)\n\nPlease try to look for a 9 patch long series that you reviewed around \noctober 2007 with \"dunno\" or \"skip\" in the title ;-)\n\n> > > From the patch series' titles (especially when they are cropped due\n> > > to the text window being too small to fit the indented thread), it is\n> > > not all that obvious what you want to achieve with those 10 patches.\n> > >\n> > > From recent discussions, I seem to remember that you wanted to have\n> > > some cute way to mark commits as non-testable during a bisect, and I\n> > > further seem to remember that Junio said that very method should be\n> > > usable outside of bisect, too.\n> >\n> > Well, we want to move \"git bisect skip\" code from shell (in\n> > \"git-bisect.sh\") to C. So this patch series does that by creating a new\n> > \"git bisect--helper\" command in C that contains the new code and using\n> > that new command in \"git-bisect.sh\".\n>\n> Oh?  I _completely_ missed that.  And that's being one of the original\n> Cc:ed persons...\n>\n> > > Unfortunately, that does not reveal to me, quickly, what is the\n> > > current state of affairs, and what you changed since the last time.\n> >\n> > Yeah, I should have at least put something in the comment section of my\n> > first patch in this series.\n>\n> No.  I would still have missed it.\n>\n> The cover letter is outside of any patch, because it describes the\n> purpose of the _whole_ patch series, not just one patch.\n>\n> So, it would have been nice to get a heads-up that this is not your\n> bisect-skip-a-whole-bunch-of-commits series, but a new animal.\n>\n> This way, I decided I do not have time for something I do not need, and\n> deleted it without having a look.\n\nWell as I said in my previous email I am willing to improve. So perhaps next \ntime.\n\nBest regards,\nChristian.\n"},{"id":"109618","messageId":"200903270822.01209.chriscool@tuxfamily.org","threadId":"18556","inReplyTo":"alpine.LNX.2.00.0903270126210.25399@reaper.quantumfyre.co.uk","subject":"Re: sending patch sets (was: Re: [PATCH 01/10] refs: add \"for_each_bisect_ref\" function)","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-03-27T07:22:00Z","receivedAt":"2009-03-27T07:22:00Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Le vendredi 27 mars 2009, Julian Phillips a écrit :\n> On Fri, 27 Mar 2009, Christian Couder wrote:\n> > If someone knows some other tools that can easily send a threaded patch\n> > series, I will try to see if I can use them...\n>\n> I long ago gave up on send-email, as it seemed to cumbersome for what I\n> wanted, and my perl had got so rusty I really couldn't face trying to\n> improve it.\n>\n> So I wrote a replacement in Python (attached), which I have subsequently\n> used for all patches I've sent.  It calls format-patch, passing through\n> arguments (and you can use -- to let it pass options too).\n>\n> (the only setting it reads from git config atm is mail-commit.to)\n>\n> I find it much easier to use than send-email, but as usual YMMV ...\n\nThanks I will try to have a look at it,\nChristian.\n"}]}