--- /dev/null
+Return-Path: <wking@tremily.us>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id EE642431FBD\r
+ for <notmuch@notmuchmail.org>; Sat, 8 Feb 2014 14:22:11 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.1\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.1 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id 8qDefOaO-4zx for <notmuch@notmuchmail.org>;\r
+ Sat, 8 Feb 2014 14:22:04 -0800 (PST)\r
+Received: from qmta06.westchester.pa.mail.comcast.net\r
+ (qmta06.westchester.pa.mail.comcast.net [76.96.62.56])\r
+ by olra.theworths.org (Postfix) with ESMTP id 9E88A431FBC\r
+ for <notmuch@notmuchmail.org>; Sat, 8 Feb 2014 14:22:04 -0800 (PST)\r
+Received: from omta10.westchester.pa.mail.comcast.net ([76.96.62.28])\r
+ by qmta06.westchester.pa.mail.comcast.net with comcast\r
+ id PyKz1n0050cZkys56yN4fV; Sat, 08 Feb 2014 22:22:04 +0000\r
+Received: from odin.tremily.us ([24.18.63.50])\r
+ by omta10.westchester.pa.mail.comcast.net with comcast\r
+ id PyN21n011152l3L3WyN3qs; Sat, 08 Feb 2014 22:22:04 +0000\r
+Received: by odin.tremily.us (Postfix, from userid 1000)\r
+ id 9B1B9100CE27; Sat, 8 Feb 2014 14:22:02 -0800 (PST)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tremily.us; s=odin;\r
+ t=1391898122; bh=o75bWkeWM0p2RXTBJ3lBe0hiw5/97kKcUod/5gi1uD8=;\r
+ h=From:To:Cc:Subject:Date;\r
+ b=KRXpRjE4Mv9/mJpgRox6+mlXco3JJiXrqqpsHzliMDmB7vneLeY4BwVbKznDTU8ty\r
+ 9YnZAOGwIwXEr7WF5NXL7I9Vq1UAMoWV2nkXqiiT4sErFi9BHxp8Clr8lWrAPtxJ1p\r
+ zTVIdOBHdCi+mMbsvK84Kbj4+R7buwgSil6O0VE4=\r
+From: "W. Trevor King" <wking@tremily.us>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] nmbug: Add 'clone' and replace FETCH_HEAD with @{upstream}\r
+Date: Sat, 8 Feb 2014 14:21:56 -0800\r
+Message-Id:\r
+ <80db13662a0313711ca3a91e338a63d35e64a83c.1391898002.git.wking@tremily.us>\r
+X-Mailer: git-send-email 1.8.3.2\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=UTF-8\r
+Content-Transfer-Encoding: 8bit\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=comcast.net;\r
+ s=q20121106; t=1391898124;\r
+ bh=bmBTU1oJm+L9LEh/+EQcR5h/juBlcwMTDf00HAHRAno=;\r
+ h=Received:Received:Received:From:To:Subject:Date:Message-Id:\r
+ MIME-Version:Content-Type;\r
+ b=MJ458FFdKX88XxPL/2j3r2/GBNZRYbeIFZiX0HonsxyFnPxxeOCM4SMmW1gCYQu3E\r
+ H7Wjm9kgJEXerpWXhVRk6iJ4YbxYYPW23n8lt8edTUuEHuXS1ibHm98gb3PjWhKsNo\r
+ TYumjEjbmlG2wSwxKp1QErDbuVTkoke9zJ4pUQtonlK+MOaEyiR3l7XUW3l62SuH1Q\r
+ 42H0O0uIGRw24jpRLpttGx2CUQIf6fqhZspCfE8khPDuD0pr78cGx/jIOeBg8JRcj9\r
+ /jHAZ7vHHSUJ5vnWbYrMAdNX9CrO+5pIK0B5OKUTEhT+ohTIdv0aAJ5Nwx1HHqICJG\r
+ AHg2WH4ozuJeg==\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sat, 08 Feb 2014 22:22:12 -0000\r
+\r
+From: "W. Trevor King" <wking@tremily.us>\r
+\r
+With two branches getting fetched (master and config), the branch\r
+referenced by FETCH_HEAD is ambiguous. For example, I have:\r
+\r
+ $ cat FETCH_HEAD\r
+ 41d7bfa7184cc93c9dac139d1674e9530799e3b0 \\r
+ not-for-merge branch 'config' of http://nmbug.tethera.net/git/nmbug-tags\r
+ acd379ccb973c45713eee9db177efc530f921954 \\r
+ not-for-merge branch 'master' of http://nmbug.tethera.net/git/nmbug-tags\r
+\r
+(where I wrapped the line by hand). This means that FETCH_HEAD\r
+references the config branch:\r
+\r
+ $ git rev-parse FETCH_HEAD\r
+ 41d7bfa7184cc93c9dac139d1674e9530799e3b0\r
+\r
+which breaks all of the FETCH_HEAD logic in nmbug (where FETCH_HEAD is\r
+assumed to point to the master branch).\r
+\r
+Instead of relying on FETCH_HEAD, use @{upstream} as the\r
+remote-tracking branch that should be merged/diffed/integrated into\r
+HEAD. @{upstream} was added in Git v1.7.0 (2010-02-12) [1], so\r
+relying on it should be fairly safe. One tricky bit is that bare\r
+repositories don't set upstream tracking branches by default:\r
+\r
+ $ git clone --bare http://nmbug.tethera.net/git/nmbug-tags.git nmbug-bare\r
+ $ cd nmbug-bare\r
+ $ git remote show origin\r
+ * remote origin\r
+ Fetch URL: http://nmbug.tethera.net/git/nmbug-tags.git\r
+ Push URL: http://nmbug.tethera.net/git/nmbug-tags.git\r
+ HEAD branch: master\r
+ Local refs configured for 'git push':\r
+ config pushes to config (up to date)\r
+ master pushes to master (up to date)\r
+\r
+While in a non-bare clone:\r
+\r
+ $ git clone http://nmbug.tethera.net/git/nmbug-tags.git\r
+ $ cd nmbug-tags\r
+ $ git remote show origin\r
+ * remote origin\r
+ Fetch URL: http://nmbug.tethera.net/git/nmbug-tags.git\r
+ Push URL: http://nmbug.tethera.net/git/nmbug-tags.git\r
+ HEAD branch: master\r
+ Remote branches:\r
+ config tracked\r
+ master tracked\r
+ Local branch configured for 'git pull':\r
+ master merges with remote master\r
+ Local ref configured for 'git push':\r
+ master pushes to master (up to date)\r
+\r
+>From the clone docs [2]:\r
+\r
+ --bare::\r
+ Make a 'bare' Git repository…\r
+ Also the branch heads at the remote are copied directly\r
+ to corresponding local branch heads, without mapping\r
+ them to `refs/remotes/origin/`. When this option is\r
+ used, neither remote-tracking branches nor the related\r
+ configuration variables are created.\r
+\r
+To use @{upstream}, we need to restore the local vs. remote-tracking\r
+distinction, so this commit adds 'nmbug clone', which adds the\r
+following configuration adjustments:\r
+\r
+ $ git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'\r
+ $ git config branch.$branch.remote origin\r
+ $ git config branch.$branch.merge refs/heads/$branch\r
+\r
+where $branch is the branch referenced by the remote's HEAD, which\r
+'git clone' uses to setup the local branch. After tweaking the\r
+config, we populate the new remote-tracking branches with:\r
+\r
+ $ git fetch origin\r
+\r
+After which:\r
+\r
+ $ git rev-parse @{upstream}\r
+ acd379ccb973c45713eee9db177efc530f921954\r
+\r
+gives us the master-branch commit. Existing nmbug users will have to\r
+run the configuration tweaks and re-fetch by hand. If you don't have\r
+any local commits, you could also blow away your NMBGIT repository and\r
+re-clone from scratch:\r
+\r
+ $ nmbug clone http://nmbug.tethera.net/git/nmbug-tags.git\r
+\r
+Besides removing the ambiguity of FETCH_HEAD, this commit allows users\r
+to configure which upstream branch they want nmbug to track via 'git\r
+config', in case they want to change their upstream repository.\r
+\r
+[1]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/RelNotes/1.7.0.txt\r
+[2]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/git-clone.txt\r
+---\r
+ devel/nmbug/nmbug | 49 +++++++++++++++++++++++++++++++++++--------------\r
+ 1 file changed, 35 insertions(+), 14 deletions(-)\r
+\r
+diff --git a/devel/nmbug/nmbug b/devel/nmbug/nmbug\r
+index 90d98b6..3c1d597 100755\r
+--- a/devel/nmbug/nmbug\r
++++ b/devel/nmbug/nmbug\r
+@@ -26,6 +26,7 @@ my $ESCAPED_RX = qr{$ESCAPE_CHAR([A-Fa-f0-9]{2})};\r
+ my %command = (\r
+ archive => \&do_archive,\r
+ checkout => \&do_checkout,\r
++ clone => \&do_clone,\r
+ commit => \&do_commit,\r
+ fetch => \&do_fetch,\r
+ help => \&do_help,\r
+@@ -125,6 +126,17 @@ sub do_archive {\r
+ system ('git', "--git-dir=$NMBGIT", 'archive', 'HEAD');\r
+ }\r
+ \r
++sub do_clone {\r
++ my $repository = shift;\r
++ system ('git', 'clone', '--bare', $repository, $NMBGIT) == 0\r
++ or die "'git clone' exited with nonzero value\n";\r
++ my $branch = git ('symbolic-ref', 'HEAD');\r
++ $branch =~ s|^refs/heads/||;\r
++ git ('config', 'remote.origin.fetch', '+refs/heads/*:refs/remotes/origin/*');\r
++ git ('config', "branch.$branch.remote", 'origin');\r
++ git ('config', "branch.$branch.merge", 'refs/heads/$branch');\r
++ do_fetch();\r
++}\r
+ \r
+ sub is_committed {\r
+ my $status = shift;\r
+@@ -332,21 +344,24 @@ To discard your changes, run 'nmbug checkout'\r
+ \r
+ sub do_pull {\r
+ my $remote = shift || 'origin';\r
++ my $branch = shift || 'master';\r
+ \r
+ git ( 'fetch', $remote);\r
+ \r
+- do_merge ();\r
++ do_merge ("$remote/$branch");\r
+ }\r
+ \r
+ \r
+ sub do_merge {\r
++ my $commit = shift || '@{upstream}';\r
++\r
+ insist_committed ();\r
+ \r
+ my $tempwork = tempdir ('/tmp/nmbug-merge.XXXXXX', CLEANUP => 1);\r
+ \r
+ git ( { GIT_WORK_TREE => $tempwork }, 'checkout', '-f', 'HEAD');\r
+ \r
+- git ( { GIT_WORK_TREE => $tempwork }, 'merge', 'FETCH_HEAD');\r
++ git ( { GIT_WORK_TREE => $tempwork }, 'merge', $commit);\r
+ \r
+ do_checkout ();\r
+ }\r
+@@ -407,13 +422,12 @@ sub do_status {\r
+ \r
+ \r
+ sub is_unmerged {\r
++ my $commit = shift || '@{upstream}';\r
+ \r
+- return 0 if (! -f $NMBGIT.'/FETCH_HEAD');\r
+-\r
+- my $fetch_head = git ('rev-parse', 'FETCH_HEAD');\r
+- my $base = git ( 'merge-base', 'HEAD', 'FETCH_HEAD');\r
++ my $upstream = git ('rev-parse', $commit);\r
++ my $base = git ( 'merge-base', 'HEAD', $commit);\r
+ \r
+- return ($base ne $fetch_head);\r
++ return ($base ne $upstream);\r
+ \r
+ }\r
+ \r
+@@ -473,7 +487,7 @@ sub diff_index {\r
+ sub diff_refs {\r
+ my $filter = shift;\r
+ my $ref1 = shift || 'HEAD';\r
+- my $ref2 = shift || 'FETCH_HEAD';\r
++ my $ref2 = shift || '@{upstream}';\r
+ \r
+ my $fh= git_pipe ( 'diff', "--diff-filter=$filter", '--name-only',\r
+ $ref1, $ref2);\r
+@@ -561,10 +575,11 @@ git. Any extra arguments are used (one per line) as a commit message.\r
+ \r
+ push local nmbug git state to remote repo\r
+ \r
+-=item B<pull> [remote]\r
++=item B<pull> [remote] [branch]\r
+ \r
+ pull (merge) remote repo changes to notmuch. B<pull> is equivalent to\r
+-B<fetch> followed by B<merge>.\r
++B<fetch> followed by B<merge>. The default remote is C<origin>, and\r
++the default branch is C<master>.\r
+ \r
+ =back\r
+ \r
+@@ -572,6 +587,12 @@ B<fetch> followed by B<merge>.\r
+ \r
+ =over 8\r
+ \r
++=item B<clone> repository\r
++\r
++Create a local nmbug repository from a remote source. This wraps\r
++C<git clone --bare>, adding some configuration adjustments to setup\r
++remote-tracking branches and upstreams.\r
++\r
+ =item B<checkout>\r
+ \r
+ Update the notmuch database from git. This is mainly useful to discard\r
+@@ -589,12 +610,12 @@ print help [for subcommand]\r
+ =item B<log> [parameters]\r
+ \r
+ A simple wrapper for git log. After running C<nmbug fetch>, you can\r
+-inspect the changes with C<nmbug log HEAD..FETCH_HEAD>\r
++inspect the changes with C<nmbug log HEAD..@{upstream}>\r
+ \r
+-=item B<merge>\r
++=item B<merge> [commit]\r
+ \r
+-Merge changes from FETCH_HEAD into HEAD, and load the result into\r
+-notmuch.\r
++Merge changes from C<commit> into HEAD, and load the result into\r
++notmuch. The default commit is C<@{upstream}>.\r
+ \r
+ =item B<status>\r
+ \r
+-- \r
+1.8.3.2\r
+\r