{"thread":{"id":"24085","subject":"[PATCH v2 2/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","startedAt":"2010-06-12T09:59:10Z","lastAt":"2010-06-18T21:02:11Z","messageCount":22,"participants":["Thomas Rast","Junio C Hamano","Andrew Sayers","Michael Witten","Erik Faye-Lund","SZEDER Gábor"],"isPatch":true,"patchVersion":2,"patchTotal":2},"messages":[{"id":"143561","messageId":"74f186ce201602262fe3df71d4fa22e8184608ec.1276336602.git.trast@student.ethz.ch","threadId":"24085","inReplyTo":"cover.1276336602.git.trast@student.ethz.ch","subject":"[PATCH v2 1/2] rev-list: introduce --count option","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-12T09:59:10Z","receivedAt":"2010-06-12T09:59:10Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Add a --count option that, instead of actually listing the commits,\nmerely counts them.\n\nThis is mostly geared towards script use, and to this end it acts\nspecially when used with --left-right: it outputs the left and right\ncounts separately.  Previously, scripts would have to run a shell loop\nor small inline script over to achieve the same.  (Without\n--left-right, a simple |wc -l does the job.)\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/rev-list-options.txt   |    9 +++++++++\n builtin/rev-list.c                   |   16 ++++++++++++++++\n revision.c                           |    2 ++\n revision.h                           |    5 +++++\n t/t6007-rev-list-cherry-pick-file.sh |   29 +++++++++++++++++++++++++++++\n 5 files changed, 61 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex b9fb7a8..066ade9 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -98,6 +98,15 @@ you would get an output like this:\n This implies the '--topo-order' option by default, but the\n '--date-order' option may also be specified.\n \n+ifdef::git-rev-list[]\n+--count::\n+\tPrint a number stating how many commits would have been\n+\tlisted, and suppress all other output.  When used together\n+\twith '--left-right', instead print the counts for left and\n+\tright commits, separated by a tab.\n+endif::git-rev-list[]\n+\n+\n ifndef::git-rev-list[]\n Diff Formatting\n ~~~~~~~~~~~~~~~\ndiff --git a/builtin/rev-list.c b/builtin/rev-list.c\nindex 51ceb19..efe9360 100644\n--- a/builtin/rev-list.c\n+++ b/builtin/rev-list.c\n@@ -50,6 +50,15 @@ static void show_commit(struct commit *commit, void *data)\n \n \tgraph_show_commit(revs->graph);\n \n+\tif (revs->count) {\n+\t\tif (commit->object.flags & SYMMETRIC_LEFT)\n+\t\t\trevs->count_left++;\n+\t\telse\n+\t\t\trevs->count_right++;\n+\t\tfinish_commit(commit, data);\n+\t\treturn;\n+\t}\n+\n \tif (info->show_timestamp)\n \t\tprintf(\"%lu \", commit->date);\n \tif (info->header_prefix)\n@@ -400,5 +409,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)\n \t\t\t     quiet ? finish_object : show_object,\n \t\t\t     &info);\n \n+\tif (revs.count) {\n+\t\tif (revs.left_right)\n+\t\t\tprintf(\"%d\\t%d\\n\", revs.count_left, revs.count_right);\n+\t\telse\n+\t\t\tprintf(\"%d\\n\", revs.count_left + revs.count_right);\n+\t}\n+\n \treturn 0;\n }\ndiff --git a/revision.c b/revision.c\nindex f4b8b38..21b133c 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1146,6 +1146,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->boundary = 1;\n \t} else if (!strcmp(arg, \"--left-right\")) {\n \t\trevs->left_right = 1;\n+\t} else if (!strcmp(arg, \"--count\")) {\n+\t\trevs->count = 1;\n \t} else if (!strcmp(arg, \"--cherry-pick\")) {\n \t\trevs->cherry_pick = 1;\n \t\trevs->limited = 1;\ndiff --git a/revision.h b/revision.h\nindex 568f1c9..bafa728 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -57,6 +57,7 @@ struct rev_info {\n \t\t\tlimited:1,\n \t\t\tunpacked:1,\n \t\t\tboundary:2,\n+\t\t\tcount:1,\n \t\t\tleft_right:1,\n \t\t\trewrite_parents:1,\n \t\t\tprint_parents:1,\n@@ -131,6 +132,10 @@ struct rev_info {\n \n \t/* notes-specific options: which refs to show */\n \tstruct display_notes_opt notes_opt;\n+\n+\t/* commit counts */\n+\tint count_left;\n+\tint count_right;\n };\n \n #define REV_TREE_SAME\t\t0\ndiff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh\nindex 4b8611c..b565638 100755\n--- a/t/t6007-rev-list-cherry-pick-file.sh\n+++ b/t/t6007-rev-list-cherry-pick-file.sh\n@@ -32,6 +32,23 @@ test_expect_success setup '\n \tgit tag B\n '\n \n+cat >expect <<EOF\n+<tags/B\n+>tags/C\n+EOF\n+\n+test_expect_success '--left-right' '\n+\tgit rev-list --left-right B...C > actual &&\n+\tgit name-rev --stdin --name-only --refs=\"*tags/*\" \\\n+\t\t< actual > actual.named &&\n+\ttest_cmp actual.named expect\n+'\n+\n+test_expect_success '--count' '\n+\tgit rev-list --count B...C > actual &&\n+\ttest \"$(cat actual)\" = 2\n+'\n+\n test_expect_success '--cherry-pick foo comes up empty' '\n \ttest -z \"$(git rev-list --left-right --cherry-pick B...C -- foo)\"\n '\n@@ -54,4 +71,16 @@ test_expect_success '--cherry-pick with independent, but identical branches' '\n \t\tHEAD...master -- foo)\"\n '\n \n+cat >expect <<EOF\n+1\t2\n+EOF\n+\n+# Insert an extra commit to break the symmetry\n+test_expect_success '--count --left-right' '\n+\tgit checkout branch &&\n+\ttest_commit D &&\n+\tgit rev-list --count --left-right B...D > actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n1.7.1.561.g94582\n"},{"id":"143560","messageId":"93842467ca22405712cab23a9b3920c106df0f17.1276336602.git.trast@student.ethz.ch","threadId":"24085","inReplyTo":"cover.1276336602.git.trast@student.ethz.ch","subject":"[PATCH v2 2/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-12T09:59:11Z","receivedAt":"2010-06-12T09:59:11Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Andrew Sayers <andrew-git@pileofstuff.org>\n\nAdd a notification in the command prompt specifying whether you're\nahead of or behind your upstream.  This is especially helpful in small\nteams that (forget to) push to each other very frequently.\n\nSupport git-svn upstream detection as a special case, as migrators\nfrom centralised version control systems are especially likely to\nforget to push.\n\nAlso provide ways for the user to specify a custom upstream, or code\nthat figures out the upstream.\n\nSupport for other types of upstream than SVN should be easy to add if\nanyone is so inclined.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n contrib/completion/git-completion.bash |   89 +++++++++++++++++++++++++++++++-\n 1 files changed, 88 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 57245a8..a6cb435 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -42,6 +42,17 @@\n #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n #       untracked files, then a '%' will be shown next to the branch name.\n #\n+#       If you would like to see the difference between HEAD and its upstream,\n+#       set GIT_PS1_SHOWUPSTREAM to one of the following:\n+#           git          use @{upstream}\n+#           svn          attempt to DWIM svn upstream for normal and --stdlayout\n+#           ref <ref>    unconditionally use <ref>\n+#           eval <code>  evaluate <code> which should print the commit to use\n+#       Any other value DWIMs either svn or git, preferring svn if configured.\n+#\n+#       The difference will be shown as, e.g., \"u+7-5\" meaning that you are 7\n+#       commits ahead of and 5 commits behind the upstream.\n+#\n # To submit patches:\n #\n #    *) Read Documentation/SubmittingPatches\n@@ -78,6 +89,77 @@ __gitdir ()\n \tfi\n }\n \n+__git_ps1_divergence_from_upstream ()\n+{\n+\tlocal cfg\n+\tif cfg=\"$(git config --get bash.showUpstream)\"\n+\tthen\n+\t\tGIT_PS1_SHOWUPSTREAM=\"$cfg\"\n+\tfi\n+\tif [ -n \"${GIT_PS1_SHOWUPSTREAM}\" ]; then\n+\t\tlocal upstream count\n+\t\tcase \"${GIT_PS1_SHOWUPSTREAM}\" in\n+\t\tsvn|git|\"ref \"*|\"eval \"*)\n+\t\t\t;;\n+\t\t*)\n+\t\t\t# try to dwim the type\n+\t\t\tif git config --get svn-remote.svn.url >/dev/null; then\n+\t\t\t\tGIT_PS1_SHOWUPSTREAM=svn\n+\t\t\telse\n+\t\t\t\tGIT_PS1_SHOWUPSTREAM=git\n+\t\t\tfi\n+\t\t\t;;\n+\t\tesac\n+\t\tcase \"${GIT_PS1_SHOWUPSTREAM}\" in\n+\t\tgit)\n+\t\t\tupstream=\"@{upstream}\"\n+\t\t\t;;\n+\t\tsvn)\n+\t\t\tlocal url\n+\t\t\t# git-svn upstream checking: if it has a\n+\t\t\t# remotes/git-svn, that is probably the upstream.\n+\t\t\t# Otherwise try to figure out the branch for\n+\t\t\t# --stdlayout repos.\n+\t\t\tif ! upstream=\"$(git rev-parse remotes/git-svn 2>/dev/null)\"; then\n+\t\t\t\turl=\"$(git config --get svn-remote.svn.url)\"\n+\t\t\t\tupstream=( $(git log --first-parent -1 \\\n+\t\t\t\t\t\t --grep=\"^git-svn-id: $url\") )\n+\t\t\t\tif [ -n \"$upstream\" ]; then\n+\t\t\t\t\tupstream=${upstream[ ${#upstream[@]} - 2 ]}\n+\t\t\t\t\tupstream=${upstream%@*}\n+\t\t\t\t\tupstream=${upstream#*$url/}\n+\t\t\t\tfi\n+\t\t\tfi\n+\t\t\t;;\n+\t\t\"eval \"*)\n+\t\t\t# custom shell command that determines upstream\n+\t\t\tupstream=\"$(eval \"${GIT_PS1_SHOWUPSTREAM#eval }\")\"\n+\t\t\t;;\n+\t\t\"ref \"*)\n+\t\t\tupstream=\"${GIT_PS1_SHOWUPSTREAM#ref }\"\n+\t\t\t;;\n+\t\tesac\n+\n+\t\tcount=$(git rev-list --count --left-right \\\n+\t\t\t\t\"$upstream\"...HEAD 2>/dev/null)\n+\t\tcase \"$count\" in\n+\t\t\"0\t0\"|\"\")\n+\t\t\t# empty = no upstream or no --count\n+\t\t\t;;\n+\t\t\"0\t\"*)\n+\t\t\techo \"+${count#0\t}\"\n+\t\t\t;;\n+\t\t*\"\t0\")\n+\t\t\techo \"-${count%\t0}\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\techo \"+${count#*\t}-${count%\t*}\"\n+\t\t\t;;\n+\t\tesac\n+\tfi\n+}\n+\n+\n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n # returns text to add to bash PS1 prompt (includes branch name)\n __git_ps1 ()\n@@ -132,6 +214,7 @@ __git_ps1 ()\n \t\tlocal s\n \t\tlocal u\n \t\tlocal c\n+\t\tlocal p\n \n \t\tif [ \"true\" = \"$(git rev-parse --is-inside-git-dir 2>/dev/null)\" ]; then\n \t\t\tif [ \"true\" = \"$(git rev-parse --is-bare-repository 2>/dev/null)\" ]; then\n@@ -159,10 +242,14 @@ __git_ps1 ()\n \t\t\t      u=\"%\"\n \t\t\t   fi\n \t\t\tfi\n+\n+\t\t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n+\t\t\t\tp=\"$(__git_ps1_divergence_from_upstream)\"\n+\t\t\tfi\n \t\tfi\n \n \t\tlocal f=\"$w$i$s$u\"\n-\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r\"\n+\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r${p:+ u$p}\"\n \tfi\n }\n \n-- \n1.7.1.561.g94582\n"},{"id":"143562","messageId":"cover.1276336602.git.trast@student.ethz.ch","threadId":"24085","inReplyTo":"20100612000002.GA30196@neumann","subject":"[PATCH v2 0/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-12T10:03:38Z","receivedAt":"2010-06-12T10:03:38Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"[Argh.  Or maybe it's an encoding problem?]\n\nSZEDER Gabor wrote:\n> Furthermore, I think it would be good to provide means to disable this\n> feature for some repositories while keeping it enabled for others.  In\n> the current version I could either disable or enable it globally.\n> Perhaps we could disable it when bash.showUpstream is set to an empty\n> value.\n\nWell, I wanted to leave this to Andrew but since I'm already messing\naround with it, here's my take on it.  I might be getting a bit\nfeature creepy, but it should be prepared for all possible uses now.\n\nThe semantics now are that (as with e.g. GIT_PS1_SHOWDIRTYSTATE) you\nhave to set the environment variable to get anything, but after that,\nthe config *always* overrides (so you can disable again).\n\nFurthermore, the SVN code tries remotes/git-svn first (for\nsingle-branch clones), and there are new features to set a certain ref\nor provide a small snippet of hook code.\n\n\nAndrew Sayers (1):\n  bash completion: Support \"divergence from upstream\" warnings in\n    __git_ps1\n\nThomas Rast (1):\n  rev-list: introduce --count option\n\n Documentation/rev-list-options.txt     |    9 +++\n builtin/rev-list.c                     |   16 ++++++\n contrib/completion/git-completion.bash |   89 +++++++++++++++++++++++++++++++-\n revision.c                             |    2 +\n revision.h                             |    5 ++\n t/t6007-rev-list-cherry-pick-file.sh   |   29 ++++++++++\n 6 files changed, 149 insertions(+), 1 deletions(-)\n"},{"id":"143563","messageId":"201006121211.12870.trast@student.ethz.ch","threadId":"24085","inReplyTo":"cover.1276336602.git.trast@student.ethz.ch","subject":"vger doesn't like UTF-8 from send-email","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-12T10:11:12Z","receivedAt":"2010-06-12T10:11:12Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thomas Rast wrote:\n> [Argh.  Or maybe it's an encoding problem?]\n\nFirst, sorry everyone on the Cc list for the triple post.  I first\nblamed it on the fact that I was Cc'ing Gabor, but apparently the\nproblem was in the content.\n\nThe files I handed to git-send-email were UTF-8, and I used my usual\ngit alias to --cc Gabor on the first pass which also results in an\nUTF-8 encoded name.\n\nI got this back from our university mail server:\n\n  git@vger.kernel.org\n  vger.kernel.org #550 5.7.1 Content-Policy reject msg: Wrong MIME labeling on 8-bit character texts. BF:<H 0>; S1753608Ab0FLKCQ ##\n\nAFAICT the original message did not declare an encoding:\n\n  Subject: [PATCH v2 0/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1\n  Date: Sat, 12 Jun 2010 12:02:14 +0200\n  Message-ID: <cover.1276336602.git.trast@student.ethz.ch>\n  X-Mailer: git-send-email 1.7.1.561.g94582\n  In-Reply-To: <20100612000002.GA30196@neumann>\n  References: <20100612000002.GA30196@neumann>\n  MIME-Version: 1.0\n  Content-Type: text/plain\n  Return-Path: trast@student.ethz.ch\n\nIt's hard to be 100% sure though because in the infinite wisdom of MS\nExchange, the bounce came back with everything wrapped in a layer of\nHTML(!) and declared latin-1.\n\nIs this a new vger policy, or am I hitting a send-email bug?\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"143570","messageId":"cebe57bb68b5e8ea445e560bbe6305c915ce8a1c.1276354971.git.trast@student.ethz.ch","threadId":"24085","inReplyTo":"201006121211.12870.trast@student.ethz.ch","subject":"[PATCH] send-email: ask about and declare 8bit mails","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-12T15:06:20Z","receivedAt":"2010-06-12T15:06:20Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"git-send-email passes on an 8bit mail as-is even if it does not\ndeclare a content-type.  Because the user can edit email between\nformat-patch and send-email, such invalid mails are unfortunately not\nvery hard to come by.\n\nMake git-send-email stop and ask about the encoding to use if it\nencounters any such mail.  Also provide a configuration setting to\npermanently configure an encoding.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nThis takes care of what I ran into earlier today.  However, there's\nanother problem: format-patch doesn't even mark the patch 8bit if its\npatch contents (not log message) are non-ASCII.  I'm really not sure\nwhat to do there.\n\nOn the practical hand, there's the problem that the entire\nlog_tree_commit() call chain is geared towards printing on a file, at\nwhich time it's too late.  So we would either have to go in and fix\nall of that to support formatting to a strbuf, or rewrite the patch if\nit turns out to be non-ASCII.\n\nOn the philosophical hand, we don't really care about file encodings\nso far, but this requires declaring one.\n\nEither way, I think if vger doesn't accept format-patch;send-email,\nsomething is really wrong :-)\n\n\n Documentation/git-send-email.txt |    9 ++++\n git-send-email.perl              |   59 +++++++++++++++++++++++++++++\n t/t9001-send-email.sh            |   77 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 145 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt\nindex 12622fc..c283084 100644\n--- a/Documentation/git-send-email.txt\n+++ b/Documentation/git-send-email.txt\n@@ -101,6 +101,15 @@ See the CONFIGURATION section for 'sendemail.multiedit'.\n +\n The --to option must be repeated for each user you want on the to list.\n \n+--8bit-encoding=<encoding>::\n+\tWhen encountering a non-ASCII message or subject that does not\n+\tdeclare its encoding, add headers/quoting to indicate it is\n+\tencoded in <encoding>.  Default is the value of the\n+\t'sendemail.assume8bitEncoding'; if that is unspecified, this\n+\twill be prompted for if any non-ASCII files are encountered.\n++\n+Note that no attempts whatsoever are made to validate the encoding.\n+\n \n Sending\n ~~~~~~~\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 111c981..6b2ac79 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -54,6 +54,7 @@ git send-email [options] <file | directory | rev-list options >\n     --in-reply-to           <str>  * Email \"In-Reply-To:\"\n     --annotate                     * Review each patch that will be sent in an editor.\n     --compose                      * Open an editor for introduction.\n+    --8bit-encoding         <str>  * Encoding to assume 8bit mails if undeclared\n \n   Sending:\n     --envelope-sender       <str>  * Email envelope sender.\n@@ -191,6 +192,7 @@ my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption);\n my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts, $smtp_domain);\n my ($validate, $confirm);\n my (@suppress_cc);\n+my ($auto_8bit_encoding);\n \n my ($debug_net_smtp) = 0;\t\t# Net::SMTP, see send_message()\n \n@@ -222,6 +224,7 @@ my %config_settings = (\n     \"multiedit\" => \\$multiedit,\n     \"confirm\"   => \\$confirm,\n     \"from\" => \\$sender,\n+    \"assume8bitencoding\" => \\$auto_8bit_encoding,\n );\n \n # Help users prepare for 1.7.0\n@@ -297,6 +300,7 @@ my $rc = GetOptions(\"sender|from=s\" => \\$sender,\n \t\t    \"thread!\" => \\$thread,\n \t\t    \"validate!\" => \\$validate,\n \t\t    \"format-patch!\" => \\$format_patch,\n+\t\t    \"8bit-encoding=s\" => \\$auto_8bit_encoding,\n \t );\n \n unless ($rc) {\n@@ -669,6 +673,34 @@ sub ask {\n \treturn undef;\n }\n \n+my %broken_encoding;\n+\n+sub file_declares_8bit_cte($) {\n+\tmy $fn = shift;\n+\topen (my $fh, '<', $fn);\n+\twhile (my $line = <$fh>) {\n+\t\treturn 1 if ($line =~ /^Content-Transfer-Encoding: .*8bit.*$/);\n+\t}\n+\tclose $fh;\n+\treturn 0;\n+}\n+\n+foreach my $f (@files) {\n+\tnext unless (body_or_subject_has_nonascii($f)\n+\t\t     && !file_declares_8bit_cte($f));\n+\t$broken_encoding{$f} = 1;\n+}\n+\n+if (!defined $auto_8bit_encoding && scalar %broken_encoding) {\n+\tprint \"The following files are 8bit, but do not declare \" .\n+\t\t\"a Content-Transfer-Encoding.\\n\";\n+\tforeach my $f (sort keys %broken_encoding) {\n+\t\tprint \"    $f\\n\";\n+\t}\n+\t$auto_8bit_encoding = ask(\"Which 8bit encoding should I declare [UTF-8]? \",\n+\t\t\t\t  default => \"UTF-8\");\n+}\n+\n my $prompting = 0;\n if (!defined $sender) {\n \t$sender = $repoauthor || $repocommitter || '';\n@@ -1221,6 +1253,18 @@ foreach my $t (@files) {\n \t\t\tor die \"(cc-cmd) failed to close pipe to '$cc_cmd'\";\n \t}\n \n+\tif ($broken_encoding{$t} && !$has_content_type) {\n+\t\t$has_content_type = 1;\n+\t\tpush @xh, \"MIME-Version: 1.0\",\n+\t\t\t\"Content-Type: text/plain; charset=$auto_8bit_encoding\",\n+\t\t\t\"Content-Transfer-Encoding: 8bit\";\n+\t\t$body_encoding = $auto_8bit_encoding;\n+\t}\n+\n+\tif ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) {\n+\t\t$subject = quote_rfc2047($subject, $auto_8bit_encoding);\n+\t}\n+\n \tif (defined $author and $author ne $sender) {\n \t\t$message = \"From: $author\\n\\n$message\";\n \t\tif (defined $author_encoding) {\n@@ -1233,6 +1277,7 @@ foreach my $t (@files) {\n \t\t\t\t}\n \t\t\t}\n \t\t\telse {\n+\t\t\t\t$has_content_type = 1;\n \t\t\t\tpush @xh,\n \t\t\t\t  'MIME-Version: 1.0',\n \t\t\t\t  \"Content-Type: text/plain; charset=$author_encoding\",\n@@ -1310,3 +1355,17 @@ sub file_has_nonascii {\n \t}\n \treturn 0;\n }\n+\n+sub body_or_subject_has_nonascii {\n+\tmy $fn = shift;\n+\topen(my $fh, '<', $fn)\n+\t\tor die \"unable to open $fn: $!\\n\";\n+\twhile (my $line = <$fh>) {\n+\t\tlast if $line =~ /^$/;\n+\t\treturn 1 if $line =~ /^Subject.*[^[:ascii:]]/;\n+\t}\n+\twhile (my $line = <$fh>) {\n+\t\treturn 1 if $line =~ /[^[:ascii:]]/;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh\nindex 640b3d2..0b8a591 100755\n--- a/t/t9001-send-email.sh\n+++ b/t/t9001-send-email.sh\n@@ -918,4 +918,81 @@ test_expect_success '--no-bcc overrides sendemail.bcc' '\n \t! grep \"RCPT TO:<other@ex.com>\" stdout\n '\n \n+cat >email-using-8bit <<EOF\n+From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001\n+Message-Id: <bogus-message-id@example.com>\n+From: author@example.com\n+Date: Sat, 12 Jun 2010 15:53:58 +0200\n+Subject: subject goes here\n+\n+Dieser deutsche Text enthält einen Umlaut!\n+EOF\n+\n+cat >content-type-decl <<EOF\n+MIME-Version: 1.0\n+Content-Type: text/plain; charset=UTF-8\n+Content-Transfer-Encoding: 8bit\n+EOF\n+\n+test_expect_success 'asks about and fixes 8bit encodings' '\n+\tclean_fake_sendmail &&\n+\techo |\n+\tgit send-email --from=author@example.com --to=nobody@example.com \\\n+\t\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\t\temail-using-8bit >stdout &&\n+\tgrep \"do not declare a Content-Transfer-Encoding\" stdout &&\n+\tgrep email-using-8bit stdout &&\n+\tgrep \"Which 8bit encoding\" stdout &&\n+\tgrep \"Content\\\\|MIME\" msgtxt1 >actual &&\n+\ttest_cmp actual content-type-decl\n+'\n+\n+test_expect_success 'sendemail.8bitEncoding works' '\n+\tclean_fake_sendmail &&\n+\tgit config sendemail.assume8bitEncoding UTF-8 &&\n+\techo bogus |\n+\tgit send-email --from=author@example.com --to=nobody@example.com \\\n+\t\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\t\temail-using-8bit >stdout &&\n+\tgrep \"Content\\\\|MIME\" msgtxt1 >actual &&\n+\ttest_cmp actual content-type-decl\n+'\n+\n+test_expect_success '--8bit-encoding overrides sendemail.8bitEncoding' '\n+\tclean_fake_sendmail &&\n+\tgit config sendemail.assume8bitEncoding \"bogus too\" &&\n+\techo bogus |\n+\tgit send-email --from=author@example.com --to=nobody@example.com \\\n+\t\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\t\t--8bit-encoding=UTF-8 \\\n+\t\t\temail-using-8bit >stdout &&\n+\tgrep \"Content\\\\|MIME\" msgtxt1 >actual &&\n+\ttest_cmp actual content-type-decl\n+'\n+\n+cat >email-using-8bit <<EOF\n+From fe6ecc66ece37198fe5db91fa2fc41d9f4fe5cc4 Mon Sep 17 00:00:00 2001\n+Message-Id: <bogus-message-id@example.com>\n+From: author@example.com\n+Date: Sat, 12 Jun 2010 15:53:58 +0200\n+Subject: Dieser Betreff enthält auch einen Umlaut!\n+\n+Nothing to see here.\n+EOF\n+\n+cat >expected <<EOF\n+Subject: =?UTF-8?q?Dieser=20Betreff=20enth=C3=A4lt=20auch=20einen=20Umlaut!?=\n+EOF\n+\n+test_expect_success '--8bit-encoding also treats subject' '\n+\tclean_fake_sendmail &&\n+\techo bogus |\n+\tgit send-email --from=author@example.com --to=nobody@example.com \\\n+\t\t\t--smtp-server=\"$(pwd)/fake.sendmail\" \\\n+\t\t\t--8bit-encoding=UTF-8 \\\n+\t\t\temail-using-8bit >stdout &&\n+\tgrep \"Subject\" msgtxt1 >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n1.7.1.557.gd161\n"},{"id":"143575","messageId":"7vljakfc64.fsf@alter.siamese.dyndns.org","threadId":"24085","inReplyTo":"cebe57bb68b5e8ea445e560bbe6305c915ce8a1c.1276354971.git.trast@student.ethz.ch","subject":"Re: [PATCH] send-email: ask about and declare 8bit mails","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-12T16:28:19Z","receivedAt":"2010-06-12T16:28:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> git-send-email passes on an 8bit mail as-is even if it does not\n> declare a content-type.  Because the user can edit email between\n> format-patch and send-email, such invalid mails are unfortunately not\n> very hard to come by.\n>\n> Make git-send-email stop and ask about the encoding to use if it\n> encounters any such mail.  Also provide a configuration setting to\n> permanently configure an encoding.\n>\n> Signed-off-by: Thomas Rast <trast@student.ethz.ch>\n> ---\n>\n> This takes care of what I ran into earlier today.  However, there's\n> another problem: format-patch doesn't even mark the patch 8bit if its\n> patch contents (not log message) are non-ASCII.  I'm really not sure\n> what to do there.\n\nA project won't have uniform file encoding anyway, so even if we were to\ndo something clever about this, it has to be per-patch.  Perhaps\n\n (0) use the attributes mechanism to allow projects to mark paths with\n     encoding.  E.g.\n\n\t# everything in UTF-8 unless otherwise specified...\n        * encoding=UTF-8\n        Documentation/zh_CN/* encoding=big5\n\n (1) for each patch, find the paths involved, and if their encodings are\n     the same, perhaps promote that as the encoding used for the entire\n     message;\n\n (2) otherwise, if there is an 8-bit encoding involved in the paths,\n     perhaps mark the entire message as 8-bit (binary???).\n\nI have this suspicion that (2) is very rare (you cannot transmit such a\npatch as a plain text message reliably afaict, so it is not done in\npractice), and we would probably need to make a separate patchfile for\ngroups of paths in each encoding and attach them as MIME multiparts (ugh).\n\nJust thinkning aloud, before morning caffeine sinks in, so please take\nthis with a grain of salt...\n"},{"id":"143590","messageId":"4C13F32B.7060106@pileofstuff.org","threadId":"24085","inReplyTo":"cover.1276336602.git.trast@student.ethz.ch","subject":"[PATCH] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-12T20:50:51Z","receivedAt":"2010-06-12T20:50:51Z","isPatch":true,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"Add a notification in the command prompt specifying whether (and optionally how\nfar) your branch has diverged from its upstream.  This is especially helpful in\nsmall teams that very frequently (forget to) push to each other.\n\nSupport git-svn upstream detection as a special case, as migrators from\ncentralised version control systems are especially likely to forget to push.\n\nAlso provide ways for the user to specify a custom upstream, or code that\nfigures out the upstream.\n\nSupport for other types of upstream than SVN should be easy to add if anyone is\nso inclined.\n---\n\nThis is based largely on Thomas' patch, but with some significant\ndifferences.  Thanks once again Thomas.\n\nI've made the quieter </> behaviour the default.  A major use case for\nme will be over-the-shoulder checking for the rest of my team - I can\nprobably add a couple of characters to their prompts without raising\nany eyebrows, but \" u+1-2\" is enough UI to provoke people's curiosity.\nIf they're not interested in this feature, it will be harder for me to\njustify 6+ interesting characters than 2 boring ones.  I haven't gone\nwith Steven's ↑/↓ idea because I don't want to field complaints\nabout \"my terminal is Unicode-aware but those characters are\nunreadable in my default font\".  I'd rather people edit the source for\nthat sort of thing.\n\nI've added a message in the \"equal to upstream\" case, to differentiate\nit from the \"no upstream\" case.  Again, this is an over-the-shoulder\nissue - when I see an \"=\" (or \" u=\") in someone's prompt, I don't have\nto patronise them about whether they've e.g. misconfigured their\nbranch.\n\nI've added a legacy mode to make the script work without \"git rev-list\n--count\".  I really like the \"git rev-list --count\" option, but\ngetting my team to run a patched version of git would be quite a bit\nmore trouble than it's worth.  If people strongly object to this\nfeature then I can hide it better or remove it from the public patch.\n\nThe documentation for the \"legacy\" option currently reads \"don't use\nthe '--count' option available in recent versions of git-rev-list\".\nIf/when \"--count\" makes it into master, this could be changed to\n\"compatibility mode for git versions less than <version when --count\nwent in>\".\n\nI've made several efficiency improvements, only one of which is\nparticularly interesting: instead of doing an `echo`, the code now\nsets `p=` directly.  Admittedly this is messier, but $p is dynamically\nscoped and testing suggests that setting it knocks 10% or so off\nrun-time.\n\nThe code should now handle multiple SVN repositories, by getting all\nsvn-remote.*.url config options with a --get-regexp.\n\nI like the \"ref\" option, but I'm not really sure when \"eval\" would be\nuseful.  I've changed it here to \"cmd\" so people are encouraged to put\ntheir work in a script.\n\nI've tried to take Szeder's comments on board, but I'm not really sure\nwhat the problem with unnecessary empty lines is.  If this is a\nconvention I'm not aware of, could you explain in a bit more detail?\n\n\t- Andrew\n\n contrib/completion/git-completion.bash |  144 +++++++++++++++++++++++++++++++-\n 1 files changed, 143 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 57245a8..7e40f65 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -42,6 +42,23 @@\n #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n #       untracked files, then a '%' will be shown next to the branch name.\n #\n+#       If you would like to see the difference between HEAD and its\n+#       upstream, set GIT_PS1_SHOWUPSTREAM to a nonempty value.  A \"<\"\n+#       indicates you are behind, \">\" indicates you are ahead, and\n+#       \"<>\" indicates you have diverged.  You can further control the\n+#       output by setting GIT_PS1_SHOWUPSTREAM to a space-separated\n+#       list of values:\n+#           git           compare HEAD to @{upstream}\n+#           svn           compare HEAD to your SVN upstream\n+#           ref=<ref>     compare HEAD to <ref>\n+#           cmd=<command> compare HEAD to the output of <command>\n+#           verbose       show number of commits ahead/behind (+/-) upstream\n+#           legacy        don't use the '--count' option available in recent\n+#                         versions of git-rev-list\n+#       If none of 'git', 'svn', 'ref' or 'cmd' are specified, your SVN\n+#       upstream will be used if configured, or your git upstream otherwise.\n+#\n+#\n # To submit patches:\n #\n #    *) Read Documentation/SubmittingPatches\n@@ -78,6 +95,126 @@ __gitdir ()\n \tfi\n }\n \n+# stores the divergence from upstream in $p\n+# used by GIT_PS1_SHOWUPSTREAM\n+__git_ps1_show_upstream ()\n+{\n+\tlocal cfg=( $( git config --get-regexp '^bash\\.showUpstream$|^svn-remote\\..*\\.url$' 2>/dev/null ) )\n+\tlocal svn_remote=() svn_url_pattern count n\n+\tlocal upstream=git legacy verbose\n+\n+\t# get some config options from git-config\n+\tfor (( n=0; \"$n\" != \"${#cfg[@]}\"; ++n )); do\n+\t\tcase \"${cfg[$n]}\" in\n+\t\t\tbash.showUpstream)\n+\t\t\t\tGIT_PS1_SHOWUPSTREAM=\"${cfg[$((n+1))]}\"\n+\t\t\t\tif [[ -z \"${GIT_PS1_SHOWUPSTREAM}\" ]]; then\n+\t\t\t\t\tp=\"\"\n+\t\t\t\t\treturn\n+\t\t\t\tfi\n+\t\t\t\t;;\n+\t\t\tsvn-remote.*.url)\n+\t\t\t\tsvn_remote[ $(( ${#svn_remote[@]} + 1 )) ]=\"${cfg[$((n+1))]}\"\n+\t\t\t\tsvn_url_pattern+=\"\\\\|${cfg[$((n+1))]}\"\n+\t\t\t\tupstream=svn # default upstream is SVN if available\n+\t\t\t\t;;\n+\t\tesac\n+\tdone\n+\n+\t# parse configuration values\n+\tfor option in ${GIT_PS1_SHOWUPSTREAM}; do\n+\t\tcase \"$option\" in\n+\t\t\tgit|svn|\"ref=\"*|\"cmd=\"*) upstream=\"$option\" ;;\n+\t\t\tverbose) verbose=1 ;;\n+\t\t\tlegacy)  legacy=1  ;;\n+\t\tesac\n+\tdone\n+\n+\t# Find our upstream\n+\tcase \"$upstream\" in\n+\t\tgit)    upstream=\"@{upstream}\" ;;\n+\t\tref\\=*) upstream=\"${option:4}\" ;;\n+\t\tcmd\\=*) upstream=$( \"${option:4}\" ) ;;\n+\t\tsvn)\n+\t\t\t# get the upstream from the \"git-svn-id: ...\" in a commit message\n+\t\t\t# (git-svn uses essentially the same procedure internally)\n+\t\t\tupstream=( $(git log --first-parent -1 \\\n+\t\t\t\t\t--grep=\"^git-svn-id: \\(${svn_url_pattern:2}\\)\") )\n+\t\t\tif [[ -n \"$upstream\" ]]; then\n+\t\t\t\tupstream=${upstream[ ${#upstream[@]} - 2 ]}\n+\t\t\t\tupstream=${upstream%@*}\n+\t\t\t\tfor (( n=1; \"$n\" <= \"${#svn_remote[@]}\"; ++n )); do\n+\t\t\t\t\tupstream=${upstream#${svn_remote[$n]}}\n+\t\t\t\tdone\n+\n+\t\t\t\tif [[ -z \"$upstream\" ]]; then\n+\t\t\t\t\t# default branch name for checkouts with no layout:\n+\t\t\t\t\tupstream=${GIT_SVN_ID:-git-svn}\n+\t\t\t\telse\n+\t\t\t\t\tupstream=${upstream#/}\n+\t\t\t\tfi\n+\n+\t\t\tfi\n+\t\t\t;;\n+\tesac\n+\n+\t# Find how many commits we are ahead/behind our upstream\n+\tif [[ -z \"$legacy\" ]]; then\n+\t\tcount=\"$(git rev-list --count --left-right \\\n+\t\t\t\t\"$upstream\"...HEAD 2>/dev/null)\"\n+\telse\n+\t\t# produce equivalent output to --count for older versions of git\n+\t\tlocal commits\n+\t\tif commits=\"$( git rev-list --left-right \"$upstream\"...HEAD 2>/dev/null )\"\n+\t\tthen\n+\t\t\tlocal commit behind=0 ahead=0\n+\t\t\tfor commit in $commits\n+\t\t\tdo\n+\t\t\t\tcase \"$commit\" in\n+\t\t\t\t\t\"<\"*) let ++behind\n+\t\t\t\t\t\t;;\n+\t\t\t\t\t*)    let ++ahead\n+\t\t\t\t\t\t;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\t\tcount=\"$behind\t$ahead\"\n+\t\telse\n+\t\t\tcount=\"\"\n+\t\tfi\n+\tfi\n+\n+\t# calculate the result\n+\tif [[ -z \"$verbose\" ]]; then\n+\t\tcase \"$count\" in\n+\t\t\t\"\") # no upstream\n+\t\t\t\tp=\"\" ;;\n+\t\t\t\"0\t0\") # equal to upstream\n+\t\t\t\tp=\"=\" ;;\n+\t\t\t\"0\t\"*) # ahead of upstream\n+\t\t\t\tp=\">\" ;;\n+\t\t\t*\"\t0\") # behind upstream\n+\t\t\t\tp=\"<\" ;;\n+\t\t\t*)\t    # diverged from upstream\n+\t\t\t\tp=\"<>\" ;;\n+\t\tesac\n+\telse\n+\t\tcase \"$count\" in\n+\t\t\t\"\") # no upstream\n+\t\t\t\tp=\"\" ;;\n+\t\t\t\"0\t0\") # equal to upstream\n+\t\t\t\tp=\" u=\" ;;\n+\t\t\t\"0\t\"*) # ahead of upstream\n+\t\t\t\tp=\" u+${count#0\t}\" ;;\n+\t\t\t*\"\t0\") # behind upstream\n+\t\t\t\tp=\" u-${count%\t0}\" ;;\n+\t\t\t*)\t    # diverged from upstream\n+\t\t\t\tp=\" u+${count#*\t}-${count%\t*}\" ;;\n+\t\tesac\n+\tfi\n+\n+}\n+\n+\n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n # returns text to add to bash PS1 prompt (includes branch name)\n __git_ps1 ()\n@@ -132,6 +269,7 @@ __git_ps1 ()\n \t\tlocal s\n \t\tlocal u\n \t\tlocal c\n+\t\tlocal p\n \n \t\tif [ \"true\" = \"$(git rev-parse --is-inside-git-dir 2>/dev/null)\" ]; then\n \t\t\tif [ \"true\" = \"$(git rev-parse --is-bare-repository 2>/dev/null)\" ]; then\n@@ -159,10 +297,14 @@ __git_ps1 ()\n \t\t\t      u=\"%\"\n \t\t\t   fi\n \t\t\tfi\n+\n+\t\t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n+\t\t\t\t__git_ps1_show_upstream\n+\t\t\tfi\n \t\tfi\n \n \t\tlocal f=\"$w$i$s$u\"\n-\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r\"\n+\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r$p\"\n \tfi\n }\n \n-- \n1.7.0.4\n"},{"id":"143597","messageId":"AANLkTim1QajqLOp4y6-oIMAGp8Tkf7z9uTH6bwIIFYkH@mail.gmail.com","threadId":"24085","inReplyTo":"201006121211.12870.trast@student.ethz.ch","subject":"Re: vger doesn't like UTF-8 from send-email","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-06-13T04:15:51Z","receivedAt":"2010-06-13T04:15:51Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Sat, Jun 12, 2010 at 05:11, Thomas Rast <trast@student.ethz.ch> wrote:\n> AFAICT the original message did not declare an encoding:\n>\n> Subject: [PATCH v2 0/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1\n> Date: Sat, 12 Jun 2010 12:02:14 +0200\n> Message-ID: <cover.1276336602.git.trast@student.ethz.ch>\n> X-Mailer: git-send-email 1.7.1.561.g94582\n> In-Reply-To: <20100612000002.GA30196@neumann>\n> References: <20100612000002.GA30196@neumann>\n> MIME-Version: 1.0\n> Content-Type: text/plain\n> Return-Path: trast@student.ethz.ch\n> ...\n> Is this a new vger policy, or am I hitting a send-email bug?\n\nLet's assume the headers themselves are already properly encoded.\n\nAccording to:\n\n    http://www.faqs.org/rfcs/rfc2045.html\n\nwe have:\n\n    The proper Content-Transfer-Encoding\n    label must always be used.\n\nand:\n\n    An encoding type of 7BIT requires that\n    the body is already in a 7bit mail-ready\n    representation.  This is the default value\n    -- that is, \"Content-Transfer-Encoding: 7BIT\"\n    is assumed if the Content-Transfer-Encoding\n    header field is not present.\n\nMoreover, according to:\n\n    http://www.faqs.org/rfcs/rfc2046.html\n\nwe have:\n\n    4.1.2    Charset Parameter\n    ...\n    The default character set, which must be\n    assumed in the absence of a charset parameter,\n    is US-ASCII.\n\nSo, your email is indeed incorrect in 2 ways if the body contains\nUTF-8 encoded data.\n\n>From what I've skimmed, the mail user agent (MUA)---such as\nsend-email---could send your unmodified message body by producing\nthese headers:\n\n    MIME-Version: 1.0\n    Content-type: text/plain; charset=utf-8\n    Content-transfer-encoding: 8bit\n\nbut only 7bit transfer encodings are guaranteed to make it intact to\nthe destination; consequently, it would probably be a good idea for\nthe MUA to transform your message into some 7bit encoding, preferably\na human-readable one such as the 'quoted-printable' encoding; after\nsuch a transformation, the headers could be:\n\n    MIME-Version: 1.0\n    Content-type: text/plain; charset=utf-8\n    Content-transfer-encoding: quoted-printable\n\nSincerely,\nMichael Witten\n"},{"id":"143611","messageId":"201006131709.55335.trast@student.ethz.ch","threadId":"24085","inReplyTo":"7vljakfc64.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] send-email: ask about and declare 8bit mails","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-13T15:09:55Z","receivedAt":"2010-06-13T15:09:55Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n>  (2) otherwise, if there is an 8-bit encoding involved in the paths,\n>      perhaps mark the entire message as 8-bit (binary???).\n> \n> I have this suspicion that (2) is very rare (you cannot transmit such a\n> patch as a plain text message reliably afaict, so it is not done in\n> practice), and we would probably need to make a separate patchfile for\n> groups of paths in each encoding and attach them as MIME multiparts (ugh).\n\nSo IIUC this would be the main/first obstacle?  Seeing as we seem to\ndo fine here but you both say 8bit is not reliable.  (According to\nWikipedia[*] all the big names support it though...)\n\nPerhaps Quoted-Printable would work with minimal effort?  We could\nleave it to send-email to do all the quoting, mailsplit or am all the\nunquoting and we retain (mostly) the readability of the original\npatches.\n\nThat still doesn't solve the problem that we might send (invalid utf8)\nbinary data declared as utf8.  I suppose to work around that, a more\nelaborate approach like\n\n>  (0) use the attributes mechanism to allow projects to mark paths with\n>      encoding.  E.g.\n> \n> \t# everything in UTF-8 unless otherwise specified...\n>         * encoding=UTF-8\n>         Documentation/zh_CN/* encoding=big5\n> \n>  (1) for each patch, find the paths involved, and if their encodings are\n>      the same, perhaps promote that as the encoding used for the entire\n>      message;\n\nis needed.\n\n\n[*] http://en.wikipedia.org/wiki/8BITMIME#8BITMIME\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"143624","messageId":"7v7hm2e27z.fsf@alter.siamese.dyndns.org","threadId":"24085","inReplyTo":"93842467ca22405712cab23a9b3920c106df0f17.1276336602.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 2/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-14T03:13:04Z","receivedAt":"2010-06-14T03:13:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> +#       If you would like to see the difference between HEAD and its upstream,\n> +#       set GIT_PS1_SHOWUPSTREAM to one of the following:\n> +#           git          use @{upstream}\n> +#           svn          attempt to DWIM svn upstream for normal and --stdlayout\n> +#           ref <ref>    unconditionally use <ref>\n> +#           eval <code>  evaluate <code> which should print the commit to use\n\nThis looks somewhat overengineered, although \"git\" and \"svn\" are probably\nuseful in real life.  I especially wonder if a fixed <ref> is useful at\nall.  Wouldn't the choice of \"other\" branch always depend on the current\nbranch?\n"},{"id":"143641","messageId":"201006140942.43099.trast@student.ethz.ch","threadId":"24085","inReplyTo":"4C13F32B.7060106@pileofstuff.org","subject":"Re: [PATCH] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-14T07:42:42Z","receivedAt":"2010-06-14T07:42:42Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Andrew Sayers wrote:\n> I've added a message in the \"equal to upstream\" case, to differentiate\n> it from the \"no upstream\" case.  Again, this is an over-the-shoulder\n> issue - when I see an \"=\" (or \" u=\") in someone's prompt, I don't have\n> to patronise them about whether they've e.g. misconfigured their\n> branch.\n\nI omitted it because I thought it would be too cluttery, but then my\nbranches seem to rarely agree with their upstream.\n\n> +       local cfg=( $( git config --get-regexp '^bash\\.showUpstream$|^svn-remote\\..*\\.url$' 2>/dev/null ) )\n\nDoesn't this break if the config value contains spaces?  I don't know\nenough about bash arrays but in my simple tests, the array elements\nare split between words.\n\nAnd with the new design, you practically *expect* the config key to\ncontain spaces.\n\nAlong the same lines, I think\n> +                               GIT_PS1_SHOWUPSTREAM=\"${cfg[$((n+1))]}\"\n> +                               if [[ -z \"${GIT_PS1_SHOWUPSTREAM}\" ]]; then\ncan never trigger because bash will never see the empty config string.\n\nSlightly more robust would be to use\n\n  git config --get-regexp '^bash\\.showUpstream$|^svn-remote\\..*\\.url$' \\\n    2>/dev/null |\n  while read key value, do\n    # stuff\n  done\n\nThat still breaks in the case of values containing newlines, though.\n\n> I like the \"ref\" option, but I'm not really sure when \"eval\" would be\n> useful.  I've changed it here to \"cmd\" so people are encouraged to put\n> their work in a script.\n[...]\n> +#           cmd=<command> compare HEAD to the output of <command>\n[...]\n> +\t\tcmd\\=*) upstream=$( \"${option:4}\" ) ;;\n\n\"Encourage\" is a mild understatement; AFAICS the code doesn't work\nwith more than single-word command any more.\n\nThe original intent was that the user could put a (very small) shell\nscript directly in the configuration if the normal DWIMming doesn't\nfit his neds, perhaps most likely in the case of git-svn (do other\nremote helpers have the same problem?).\n\nHaving to wrap it in a script defeats that point, as it becomes almost\nas easy to edit the completion script.  So I think if it can't eval,\nyou might as well remove it.\n\nBTW, please spell $(command) substitution without the spaces.  Your\ncurrent style does not match what is already in the file.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"143642","messageId":"201006140944.20737.trast@student.ethz.ch","threadId":"24085","inReplyTo":"7v7hm2e27z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 2/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-14T07:44:20Z","receivedAt":"2010-06-14T07:44:20Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> Thomas Rast <trast@student.ethz.ch> writes:\n> \n> > +#       If you would like to see the difference between HEAD and its upstream,\n> > +#       set GIT_PS1_SHOWUPSTREAM to one of the following:\n> > +#           git          use @{upstream}\n> > +#           svn          attempt to DWIM svn upstream for normal and --stdlayout\n> > +#           ref <ref>    unconditionally use <ref>\n> > +#           eval <code>  evaluate <code> which should print the commit to use\n> \n> This looks somewhat overengineered, although \"git\" and \"svn\" are probably\n> useful in real life.  I especially wonder if a fixed <ref> is useful at\n> all.  Wouldn't the choice of \"other\" branch always depend on the current\n> branch?\n\nYou're probably right.  I had 'ref' early on to test around, and then\nmade 'eval' to allow for arcane git-svn setups, but now that it seems\nAndrew has a nice way of matching those, we can also just drop it.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"143650","messageId":"AANLkTinH7p6_WV1FK7UTZLg-8OGINZFnYMA1kENb6PkW@mail.gmail.com","threadId":"24085","inReplyTo":"AANLkTim1QajqLOp4y6-oIMAGp8Tkf7z9uTH6bwIIFYkH@mail.gmail.com","subject":"Re: vger doesn't like UTF-8 from send-email","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@googlemail.com","sentAt":"2010-06-14T11:57:21Z","receivedAt":"2010-06-14T11:57:21Z","isPatch":false,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Sun, Jun 13, 2010 at 6:15 AM, Michael Witten <mfwitten@gmail.com> wrote:\n> On Sat, Jun 12, 2010 at 05:11, Thomas Rast <trast@student.ethz.ch> wrote:\n>> AFAICT the original message did not declare an encoding:\n>>\n>> Subject: [PATCH v2 0/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1\n>> Date: Sat, 12 Jun 2010 12:02:14 +0200\n>> Message-ID: <cover.1276336602.git.trast@student.ethz.ch>\n>> X-Mailer: git-send-email 1.7.1.561.g94582\n>> In-Reply-To: <20100612000002.GA30196@neumann>\n>> References: <20100612000002.GA30196@neumann>\n>> MIME-Version: 1.0\n>> Content-Type: text/plain\n>> Return-Path: trast@student.ethz.ch\n>> ...\n>> Is this a new vger policy, or am I hitting a send-email bug?\n>\n> Let's assume the headers themselves are already properly encoded.\n>\n> According to:\n>\n>    http://www.faqs.org/rfcs/rfc2045.html\n>\n> we have:\n>\n>    The proper Content-Transfer-Encoding\n>    label must always be used.\n>\n> and:\n>\n>    An encoding type of 7BIT requires that\n>    the body is already in a 7bit mail-ready\n>    representation.  This is the default value\n>    -- that is, \"Content-Transfer-Encoding: 7BIT\"\n>    is assumed if the Content-Transfer-Encoding\n>    header field is not present.\n>\n> Moreover, according to:\n>\n>    http://www.faqs.org/rfcs/rfc2046.html\n>\n> we have:\n>\n>    4.1.2    Charset Parameter\n>    ...\n>    The default character set, which must be\n>    assumed in the absence of a charset parameter,\n>    is US-ASCII.\n>\n> So, your email is indeed incorrect in 2 ways if the body contains\n> UTF-8 encoded data.\n>\n> From what I've skimmed, the mail user agent (MUA)---such as\n> send-email---could send your unmodified message body by producing\n> these headers:\n>\n>    MIME-Version: 1.0\n>    Content-type: text/plain; charset=utf-8\n>    Content-transfer-encoding: 8bit\n>\n> but only 7bit transfer encodings are guaranteed to make it intact to\n> the destination; consequently, it would probably be a good idea for\n> the MUA to transform your message into some 7bit encoding, preferably\n> a human-readable one such as the 'quoted-printable' encoding; after\n> such a transformation, the headers could be:\n>\n>    MIME-Version: 1.0\n>    Content-type: text/plain; charset=utf-8\n>    Content-transfer-encoding: quoted-printable\n>\n\nQP-encoding is sometimes destructive, and as such not recommended for\npatches - in fact, Documentation/SubmittingPatches forbid it. For the\ncover-letter the destruction might not be an issue (IIRC it's some\nline-feeds that might be added because QP can a line longer than the\nmaximum line-length), but special casing the encoding for\ncover-letters doesn't strike me as The Right Thing To Do(tm).\n\nI think the only real alternative to 8-bit encoding is Base64, and it\nsacrifices human-readability. Dunno how bad that is, though.\n\n-- \nErik \"kusma\" Faye-Lund\n"},{"id":"143651","messageId":"20100614123633.GN4640@neumann","threadId":"24085","inReplyTo":"93842467ca22405712cab23a9b3920c106df0f17.1276336602.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 2/2] bash completion: Support \"divergence from upstream\" warnings in __git_ps1","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2010-06-14T12:36:33Z","receivedAt":"2010-06-14T12:36:33Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nOn Sat, Jun 12, 2010 at 11:59:11AM +0200, Thomas Rast wrote:\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 57245a8..a6cb435 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -42,6 +42,17 @@\n>  #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n>  #       untracked files, then a '%' will be shown next to the branch name.\n>  #\n> +#       If you would like to see the difference between HEAD and its upstream,\n> +#       set GIT_PS1_SHOWUPSTREAM to one of the following:\n> +#           git          use @{upstream}\n> +#           svn          attempt to DWIM svn upstream for normal and --stdlayout\n> +#           ref <ref>    unconditionally use <ref>\n> +#           eval <code>  evaluate <code> which should print the commit to use\n> +#       Any other value DWIMs either svn or git, preferring svn if configured.\n\nSomething like this should go in there somewhere:\n\n  The bash.showUpstream config variable can be used to override the \n  value of GIT_PS1_SHOWUPSTREAM on a per-repository basis.\n\n> +#\n> +#       The difference will be shown as, e.g., \"u+7-5\" meaning that you are 7\n> +#       commits ahead of and 5 commits behind the upstream.\n> +#\n>  # To submit patches:\n>  #\n>  #    *) Read Documentation/SubmittingPatches\n"},{"id":"143789","messageId":"4C17F5B3.4070907@pileofstuff.org","threadId":"24085","inReplyTo":"201006140942.43099.trast@student.ethz.ch","subject":"[PATCHv4] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-15T21:50:43Z","receivedAt":"2010-06-15T21:50:43Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"Add a notification in the command prompt specifying whether (and optionally how\nfar) your branch has diverged from its upstream.  This is especially helpful in\nsmall teams that very frequently (forget to) push to each other.\n\nSupport git-svn upstream detection as a special case, as migrators from\ncentralised version control systems are especially likely to forget to push.\n\nSupport for other types of upstream than SVN should be easy to add if anyone is\nso inclined.\n---\n\nThis version removes ref= and cmd=/eval entirely, adds documentation\nand reaches once again into the forbidden bash bag to fix Thomas'\nissues.\n\nI've used process substitution <(git config) instead of a simple pipe\nbecause it's the only way I know to maintain the value of a local\nvariable.  To demonstrate, this prints a blank line:\n\nfoo() {\n\tlocal FOO\n\techo foo | while read ; do FOO=$REPLY ; done\n\techo $FOO\n}\nfoo\n\nWhereas this prints 'foo':\n\nfoo() {\n\tlocal FOO\n\twhile read ; do FOO=$REPLY ; done < <( echo foo )\n\techo $FOO\n}\nfoo\n\nWhile working on this patch, I found the following bug in 1.7.0.4:\n\n$ git config --get-regexp '^(bash\\.showUpstream)$'\nbash.showupstream legacy verbose\n$ git config --get-regexp '^(bash\\.showUpstream|x)$'\nbash.showupstream legacy verbose\n$ git config --get-regexp '^(bash\\.showupstream|\\.)$'\nbash.showupstream legacy verbose\n$ git config --get-regexp '^(bash\\.showUpstream|\\.)$'\n\nThe last line should print the same value as all the others.  This\nseems to be some weird issue with handling uppercase characters, but\nI've not yet had time to create a minimal test case or check it on\nmaster - I'll try to make some time tomorrow if it isn't a known\nissue.\n\n contrib/completion/git-completion.bash |  142 +++++++++++++++++++++++++++++++-\n 1 files changed, 141 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 57245a8..dabcdaa 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -42,6 +42,23 @@\n #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n #       untracked files, then a '%' will be shown next to the branch name.\n #\n+#       If you would like to see the difference between HEAD and its\n+#       upstream, set GIT_PS1_SHOWUPSTREAM to a nonempty value.  A \"<\"\n+#       indicates you are behind, \">\" indicates you are ahead, and\n+#       \"<>\" indicates you have diverged.  You can further control\n+#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated\n+#       list of values:\n+#           git           compare HEAD to @{upstream}\n+#           svn           compare HEAD to your SVN upstream\n+#           verbose       show number of commits ahead/behind (+/-) upstream\n+#           legacy        don't use the '--count' option available in recent\n+#                         versions of git-rev-list\n+#       By default, __git_ps1 will compare HEAD to your SVN upstream\n+#       if it can find one, or @{upstream} otherwise.  You can\n+#       override the value of GIT_PS1_SHOWUPSTREAM on a per-repository\n+#       basis by setting the bash.showUpstream config variable.\n+#\n+#\n # To submit patches:\n #\n #    *) Read Documentation/SubmittingPatches\n@@ -78,6 +95,124 @@ __gitdir ()\n \tfi\n }\n \n+# stores the divergence from upstream in $p\n+# used by GIT_PS1_SHOWUPSTREAM\n+__git_ps1_show_upstream ()\n+{\n+\tlocal key value\n+\tlocal svn_remote=() svn_url_pattern count n\n+\tlocal upstream=git legacy verbose\n+\n+\t# get some config options from git-config\n+\twhile read key value; do\n+\t\tcase \"$key\" in\n+\t\t\tbash.showupstream)\n+\t\t\t\tGIT_PS1_SHOWUPSTREAM=\"$value\"\n+\t\t\t\tif [[ -z \"${GIT_PS1_SHOWUPSTREAM}\" ]]; then\n+\t\t\t\t\tp=\"\"\n+\t\t\t\t\treturn\n+\t\t\t\tfi\n+\t\t\t\t;;\n+\t\t\tsvn-remote.*.url)\n+\t\t\t\tsvn_remote[ $((${#svn_remote[@]} + 1)) ]=\"$value\"\n+\t\t\t\tsvn_url_pattern+=\"\\\\|$value\"\n+\t\t\t\tupstream=svn # default upstream is SVN if available\n+\t\t\t\t;;\n+\t\tesac\n+\tdone < <(git config -z --get-regexp '^(svn-remote\\..*\\.url|bash\\.showupstream)$' 2>/dev/null | tr '\\0\\n' '\\n ')\n+\n+\t# parse configuration values\n+\tfor option in ${GIT_PS1_SHOWUPSTREAM}; do\n+\t\tcase \"$option\" in\n+\t\t\tgit|svn) upstream=\"$option\" ;;\n+\t\t\tverbose) verbose=1 ;;\n+\t\t\tlegacy)  legacy=1  ;;\n+\t\tesac\n+\tdone\n+\n+\t# Find our upstream\n+\tcase \"$upstream\" in\n+\t\tgit)    upstream=\"@{upstream}\" ;;\n+\t\tsvn)\n+\t\t\t# get the upstream from the \"git-svn-id: ...\" in a commit message\n+\t\t\t# (git-svn uses essentially the same procedure internally)\n+\t\t\tupstream=($(git log --first-parent -1 \\\n+\t\t\t\t\t--grep=\"^git-svn-id: \\(${svn_url_pattern:2}\\)\"))\n+\t\t\tif [[ -n \"$upstream\" ]]; then\n+\t\t\t\tupstream=${upstream[ ${#upstream[@]} - 2 ]}\n+\t\t\t\tupstream=${upstream%@*}\n+\t\t\t\tfor ((n=1; \"$n\" <= \"${#svn_remote[@]}\"; ++n)); do\n+\t\t\t\t\tupstream=${upstream#${svn_remote[$n]}}\n+\t\t\t\tdone\n+\n+\t\t\t\tif [[ -z \"$upstream\" ]]; then\n+\t\t\t\t\t# default branch name for checkouts with no layout:\n+\t\t\t\t\tupstream=${GIT_SVN_ID:-git-svn}\n+\t\t\t\telse\n+\t\t\t\t\tupstream=${upstream#/}\n+\t\t\t\tfi\n+\n+\t\t\tfi\n+\t\t\t;;\n+\tesac\n+\n+\t# Find how many commits we are ahead/behind our upstream\n+\tif [[ -z \"$legacy\" ]]; then\n+\t\tcount=\"$(git rev-list --count --left-right \\\n+\t\t\t\t\"$upstream\"...HEAD 2>/dev/null)\"\n+\telse\n+\t\t# produce equivalent output to --count for older versions of git\n+\t\tlocal commits\n+\t\tif commits=\"$(git rev-list --left-right \"$upstream\"...HEAD 2>/dev/null)\"\n+\t\tthen\n+\t\t\tlocal commit behind=0 ahead=0\n+\t\t\tfor commit in $commits\n+\t\t\tdo\n+\t\t\t\tcase \"$commit\" in\n+\t\t\t\t\t\"<\"*) let ++behind\n+\t\t\t\t\t\t;;\n+\t\t\t\t\t*)    let ++ahead\n+\t\t\t\t\t\t;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\t\tcount=\"$behind\t$ahead\"\n+\t\telse\n+\t\t\tcount=\"\"\n+\t\tfi\n+\tfi\n+\n+\t# calculate the result\n+\tif [[ -z \"$verbose\" ]]; then\n+\t\tcase \"$count\" in\n+\t\t\t\"\") # no upstream\n+\t\t\t\tp=\"\" ;;\n+\t\t\t\"0\t0\") # equal to upstream\n+\t\t\t\tp=\"=\" ;;\n+\t\t\t\"0\t\"*) # ahead of upstream\n+\t\t\t\tp=\">\" ;;\n+\t\t\t*\"\t0\") # behind upstream\n+\t\t\t\tp=\"<\" ;;\n+\t\t\t*)\t    # diverged from upstream\n+\t\t\t\tp=\"<>\" ;;\n+\t\tesac\n+\telse\n+\t\tcase \"$count\" in\n+\t\t\t\"\") # no upstream\n+\t\t\t\tp=\"\" ;;\n+\t\t\t\"0\t0\") # equal to upstream\n+\t\t\t\tp=\" u=\" ;;\n+\t\t\t\"0\t\"*) # ahead of upstream\n+\t\t\t\tp=\" u+${count#0\t}\" ;;\n+\t\t\t*\"\t0\") # behind upstream\n+\t\t\t\tp=\" u-${count%\t0}\" ;;\n+\t\t\t*)\t    # diverged from upstream\n+\t\t\t\tp=\" u+${count#*\t}-${count%\t*}\" ;;\n+\t\tesac\n+\tfi\n+\n+}\n+\n+\n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n # returns text to add to bash PS1 prompt (includes branch name)\n __git_ps1 ()\n@@ -132,6 +267,7 @@ __git_ps1 ()\n \t\tlocal s\n \t\tlocal u\n \t\tlocal c\n+\t\tlocal p\n \n \t\tif [ \"true\" = \"$(git rev-parse --is-inside-git-dir 2>/dev/null)\" ]; then\n \t\t\tif [ \"true\" = \"$(git rev-parse --is-bare-repository 2>/dev/null)\" ]; then\n@@ -159,10 +295,14 @@ __git_ps1 ()\n \t\t\t      u=\"%\"\n \t\t\t   fi\n \t\t\tfi\n+\n+\t\t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n+\t\t\t\t__git_ps1_show_upstream\n+\t\t\tfi\n \t\tfi\n \n \t\tlocal f=\"$w$i$s$u\"\n-\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r\"\n+\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r$p\"\n \tfi\n }\n \n-- \n1.7.0.4\n"},{"id":"143828","messageId":"7v7hlyg5nh.fsf@alter.siamese.dyndns.org","threadId":"24085","inReplyTo":"4C17F5B3.4070907@pileofstuff.org","subject":"Re: [PATCHv4] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-16T19:05:06Z","receivedAt":"2010-06-16T19:05:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andrew Sayers <andrew-git@pileofstuff.org> writes:\n\n> Add a notification in the command prompt specifying whether (and optionally how\n> far) your branch has diverged from its upstream.  This is especially helpful in\n> small teams that very frequently (forget to) push to each other.\n>\n> Support git-svn upstream detection as a special case, as migrators from\n> centralised version control systems are especially likely to forget to push.\n>\n> Support for other types of upstream than SVN should be easy to add if anyone is\n> so inclined.\n> ---\n\nSign-off?\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 57245a8..dabcdaa 100755\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -42,6 +42,23 @@\n>  #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n>  #       untracked files, then a '%' will be shown next to the branch name.\n>  #\n> +#       If you would like to see the difference between HEAD and its\n> +#       upstream, set GIT_PS1_SHOWUPSTREAM to a nonempty value.  A \"<\"\n> +#       indicates you are behind, \">\" indicates you are ahead, and\n> +#       \"<>\" indicates you have diverged.  You can further control\n> +#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated\n> +#       list of values:\n> +#           git           compare HEAD to @{upstream}\n> +#           svn           compare HEAD to your SVN upstream\n> +#           verbose       show number of commits ahead/behind (+/-) upstream\n> +#           legacy        don't use the '--count' option available in recent\n> +#                         versions of git-rev-list\n> +#       By default, __git_ps1 will compare HEAD to your SVN upstream\n> +#       if it can find one, or @{upstream} otherwise.\n\nThis feels somewhat weird.\n\nI can sort-of read from the above that I can set the variable to a random\nstring, e.g. \"garbage\", if I only want a simple show-upstream feature\nwithout frills (i.e. I don't want it to be verbose, I don't want it to\nrestrict the comparison only to \"git\" upstream nor \"svn\" upstream, and I\ndon't think I would ever use ancient git that lack \"rev-list --count\").\nBut the description does not assure me that the random string I happened\nto choose (in this case \"garbage\") is a safe one.  Perhaps list (and\nimplement) \"default\" as a safe, otherwise-no-op value?\n\nHow much overhead are we shaving if you specify \"git\" (without \"svn\") or\n\"svn\" (without \"git\") to the variable?  I suspect that the bulk of the\ntime is spent by reading from \"git config\" to look for svn-remote.*.url,\nwhich you seem to unconditionally do even when \"git\" was asked for\nanyway.\n\n> +#       You can\n> +#       override the value of GIT_PS1_SHOWUPSTREAM on a per-repository\n> +#       basis by setting the bash.showUpstream config variable.\n\nThat's totally backwards from it should be, isn't it?\n\nUsually configuration variables are used to give you the default, and\nyou use environment variables to override them.\n\n> +# stores the divergence from upstream in $p\n> +# used by GIT_PS1_SHOWUPSTREAM\n> +__git_ps1_show_upstream ()\n> +{\n> +\tlocal key value\n> +\tlocal svn_remote=() svn_url_pattern count n\n> +\tlocal upstream=git legacy verbose\n> +\n> +\t# get some config options from git-config\n> +\twhile read key value; do\n> +\t\tcase \"$key\" in\n> +\t\t\tbash.showupstream)\n> +\t\t\t\tGIT_PS1_SHOWUPSTREAM=\"$value\"\n> +\t\t\t\tif [[ -z \"${GIT_PS1_SHOWUPSTREAM}\" ]]; then\n> +\t\t\t\t\tp=\"\"\n> +\t\t\t\t\treturn\n> +\t\t\t\tfi\n\nThis is the \"backwards\" part.\n\n> +\t\t\t\t;;\n> +\t\t\tsvn-remote.*.url)\n> +\t\t\t\tsvn_remote[ $((${#svn_remote[@]} + 1)) ]=\"$value\"\n> +\t\t\t\tsvn_url_pattern+=\"\\\\|$value\"\n> +\t\t\t\tupstream=svn # default upstream is SVN if available\n> +\t\t\t\t;;\n\nI expected that (1) when on a branch that is a fork of a svn upstream, you\nwould use the svn magic; (2) otherwise when on a branch that is a fork of\na git upstream, you would use \"@{upstream}\".  That way, the users do not\neven have to say \"git\" or \"svn\" in GIT_PS1_SHOWUPSTREAM at all, no?\n\nBut that does not seem to be what is happening here.  Your loop seems to\nforce \"upstream=svn\" if I have one branch that is a fork from svn\nupstream, even if my current branch does not have anything to do with that\nbranch nor svn upstream.  Is that what was intended?\n\nOh, also, all of your case arms are one-indent too deep.  Please write\nthem like this:\n\n\tcase foo in\n        arm1)\n        \tstmt1\n                ;;\n\tesac\n\n> +\t\tesac\n> +\tdone < <(git config -z --get-regexp '^(svn-remote\\..*\\.url|bash\\.showupstream)$' 2>/dev/null | tr '\\0\\n' '\\n ')\n\nIf you \"tr\" to trash \"\\0\" anyway, do you need to run \"config -z\"?\n\n> +\t# parse configuration values\n> +\tfor option in ${GIT_PS1_SHOWUPSTREAM}; do\n\nIs this safe under \"set -u\"?  See 25a31f8 (bash-completion: Support\nrunning when set -u is enabled, 2009-01-15).\n"},{"id":"143830","messageId":"201006162111.09557.trast@student.ethz.ch","threadId":"24085","inReplyTo":"7v7hlyg5nh.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv4] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2010-06-16T19:11:09Z","receivedAt":"2010-06-16T19:11:09Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano wrote:\n> Andrew Sayers <andrew-git@pileofstuff.org> writes:\n> > +#       You can\n> > +#       override the value of GIT_PS1_SHOWUPSTREAM on a per-repository\n> > +#       basis by setting the bash.showUpstream config variable.\n> \n> That's totally backwards from it should be, isn't it?\n> \n> Usually configuration variables are used to give you the default, and\n> you use environment variables to override them.\n\nNot in the bash completion.  The test for the environment variable is\ncheap, so you use that to enable the feature and can then use configs\nto tweak them at a per-repo level.  There is precedent with\nGIT_PS1_SHOWDIRTYSTATE and bash.showDirtyState.\n\nThe comment above should state that this override only works if the\nenvironment variable is also enabled, though.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"143887","messageId":"4C1A9442.7080304@pileofstuff.org","threadId":"24085","inReplyTo":"7v7hlyg5nh.fsf@alter.siamese.dyndns.org","subject":"[PATCHv5 0/2] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-17T21:31:46Z","receivedAt":"2010-06-17T21:31:46Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"I agree with all the points I haven't specifically replied to.  The\nfirst patch makes the appropriate changes.  The second patch fixes\nlargely unrelated \"set -u\" issues I stumbled over while running tests.\n\nOn 16/06/10 20:05, Junio C Hamano wrote:\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index 57245a8..dabcdaa 100755\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -42,6 +42,23 @@\n>>  #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n>>  #       untracked files, then a '%' will be shown next to the branch name.\n>>  #\n>> +#       If you would like to see the difference between HEAD and its\n>> +#       upstream, set GIT_PS1_SHOWUPSTREAM to a nonempty value.  A \"<\"\n>> +#       indicates you are behind, \">\" indicates you are ahead, and\n>> +#       \"<>\" indicates you have diverged.  You can further control\n>> +#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated\n>> +#       list of values:\n>> +#           git           compare HEAD to @{upstream}\n>> +#           svn           compare HEAD to your SVN upstream\n>> +#           verbose       show number of commits ahead/behind (+/-) upstream\n>> +#           legacy        don't use the '--count' option available in recent\n>> +#                         versions of git-rev-list\n>> +#       By default, __git_ps1 will compare HEAD to your SVN upstream\n>> +#       if it can find one, or @{upstream} otherwise.\n> \n> This feels somewhat weird.\n> \n> I can sort-of read from the above that I can set the variable to a random\n> string, e.g. \"garbage\", if I only want a simple show-upstream feature\n> without frills (i.e. I don't want it to be verbose, I don't want it to\n> restrict the comparison only to \"git\" upstream nor \"svn\" upstream, and I\n> don't think I would ever use ancient git that lack \"rev-list --count\").\n> But the description does not assure me that the random string I happened\n> to choose (in this case \"garbage\") is a safe one.  Perhaps list (and\n> implement) \"default\" as a safe, otherwise-no-op value?\n\nI agree this would improve the documentation, but I've used \"auto\"\ninstead of \"default\", to give a hint that that the code is being a bit\nautomagical.  I don't see how adding code would help though -\n\"GIT_PS1_SHOWUPSTREAM=auto\" is already covered in the default case of an\nunrecognised string, and adding code to make \"GIT_PS1_SHOWUPSTREAM=1\" do\nnothing or print a warning would just confuse people that skip-read the\ndocumentation and set the value to see what happened.\n\n> How much overhead are we shaving if you specify \"git\" (without \"svn\") or\n> \"svn\" (without \"git\") to the variable?  I suspect that the bulk of the\n> time is spent by reading from \"git config\" to look for svn-remote.*.url,\n> which you seem to unconditionally do even when \"git\" was asked for\n> anyway.\n\nIn my tests, a single invocation of git-config took an average of\nroughly 0.005s with a 30-line .git/config, and roughly 0.030s with a\n.git/config that contained about 17,600 extra nonsense lines (aaa = aaa,\naab = aab, etc.).  In both cases, the extra test for svn-remote.*.url\nmade no significant difference to the time taken, whereas a second\ninvocation of `git config` (obviously) doubled the time taken.\n\nChecking the SVN upstream with `git log --first-parent -1\n--grep=\"^git-svn-id: \\(${svn_url_pattern:2}\\)\"` is actually quite a\nserious time issue, especially if you have made many commits since your\nupstream.  A test with 100 empty commits since the SVN upstream took\nroughly 0.012 seconds on average.  A test on git itself (>22,000\ncommits) took roughly 0.29 seconds to determine there was no SVN upstream.\n\nSpeed (and user confidence in speed) isn't the main reason to allow the\nuser to force \"git\" or \"svn\".  If someone had e.g. imported their old\nSVN history into a git project, or did clever git tricks on a branch\nthey regularly merged into SVN, they would want to override the default\nbehaviour.  This is probably quite rare now I think about it, and I've\nrejigged the documentation a bit to reflect that.\n\n> \n>> +#       You can\n>> +#       override the value of GIT_PS1_SHOWUPSTREAM on a per-repository\n>> +#       basis by setting the bash.showUpstream config variable.\n> \n> That's totally backwards from it should be, isn't it?\n> \n> Usually configuration variables are used to give you the default, and\n> you use environment variables to override them.\n> \n\nI basically agree with Thomas here.  Going down that route without\nparsing all the options in one big `--get-regexp` mess would take O(n)\ntime, where n consists mostly of config options I don't care about.\n\n>> +\t\t\t\t;;\n>> +\t\t\tsvn-remote.*.url)\n>> +\t\t\t\tsvn_remote[ $((${#svn_remote[@]} + 1)) ]=\"$value\"\n>> +\t\t\t\tsvn_url_pattern+=\"\\\\|$value\"\n>> +\t\t\t\tupstream=svn # default upstream is SVN if available\n>> +\t\t\t\t;;\n> \n> I expected that (1) when on a branch that is a fork of a svn upstream, you\n> would use the svn magic; (2) otherwise when on a branch that is a fork of\n> a git upstream, you would use \"@{upstream}\".  That way, the users do not\n> even have to say \"git\" or \"svn\" in GIT_PS1_SHOWUPSTREAM at all, no?\n> \n> But that does not seem to be what is happening here.  Your loop seems to\n> force \"upstream=svn\" if I have one branch that is a fork from svn\n> upstream, even if my current branch does not have anything to do with that\n> branch nor svn upstream.  Is that what was intended?\n\nI'm not sure I understand how you would detect if something is a fork of\nan SVN/git upstream.  It's certainly deliberate not to do a `git log` if\nit's avoidable, for the efficiency reasons I mentioned above.  But it\nseems like a good idea to use @{upstream} in the \"auto\" case if no SVN\nupstream was found, so I've changed the patch to do that.  Please let me\nknow if there's some applicable magic I'm not aware of :)\n\n>> +\t\tesac\n>> +\tdone < <(git config -z --get-regexp '^(svn-remote\\..*\\.url|bash\\.showupstream)$' 2>/dev/null | tr '\\0\\n' '\\n ')\n> \n> If you \"tr\" to trash \"\\0\" anyway, do you need to run \"config -z\"?\n\nThe `tr` is there to work around issues like this:\n\n\tgit config bash.showUpstream $'svn\\nlegacy'\n\tgit config bash.showUpstream | tr '\\0\\n' '\\n '\n\nThe end result is a format that can be easily parsed with `read`.\nWithout the -z, I'd have no way to tell the difference between the end\nof a config item and a literal newline.\n\nHaving said that, I have no strong opinion about which is the more\nappropriate thing to do here - slow down everyone's prompt to deal with\nan edge case, or break otherwise-valid behaviour because the solution is\nugly.  The latest patch still has it in - let me know if you'd prefer it\nout.\n\n> \n>> +\t# parse configuration values\n>> +\tfor option in ${GIT_PS1_SHOWUPSTREAM}; do\n> \n> Is this safe under \"set -u\"?  See 25a31f8 (bash-completion: Support\n> running when set -u is enabled, 2009-01-15).\n\nThis is safe under \"set -u\", as this function is only called if\n$GIT_PS1_SHOWUPSTREAM is defined.  But testing showed several issues\nthat make me suspect __git_ps1 never worked under \"set -u\".  My second\npatch fixes those issues.\n\n\t- Andrew\n"},{"id":"143888","messageId":"4C1A9452.1090900@pileofstuff.org","threadId":"24085","inReplyTo":"7v7hlyg5nh.fsf@alter.siamese.dyndns.org","subject":"[PATCHv5 1/2] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-17T21:32:02Z","receivedAt":"2010-06-17T21:32:02Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"Add a notification in the command prompt specifying whether (and optionally how\nfar) your branch has diverged from its upstream.  This is especially helpful in\nsmall teams that very frequently (forget to) push to each other.\n\nSupport git-svn upstream detection as a special case, as migrators from\ncentralised version control systems are especially likely to forget to push.\n\nSupport for other types of upstream than SVN should be easy to add if anyone is\nso inclined.\n\nSigned-off-by: Andrew Sayers <andrew-git@pileofstuff.org>\n---\n contrib/completion/git-completion.bash |  144 +++++++++++++++++++++++++++++++-\n 1 files changed, 143 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 57245a8..6e6f458 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -42,6 +42,24 @@\n #       set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're\n #       untracked files, then a '%' will be shown next to the branch name.\n #\n+#       If you would like to see the difference between HEAD and its\n+#       upstream, set GIT_PS1_SHOWUPSTREAM=\"auto\".  A \"<\" indicates\n+#       you are behind, \">\" indicates you are ahead, and \"<>\"\n+#       indicates you have diverged.  You can further control\n+#       behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated\n+#       list of values:\n+#           verbose       show number of commits ahead/behind (+/-) upstream\n+#           legacy        don't use the '--count' option available in recent\n+#                         versions of git-rev-list\n+#           git           always compare HEAD to @{upstream}\n+#           svn           always compare HEAD to your SVN upstream\n+#       By default, __git_ps1 will compare HEAD to your SVN upstream\n+#       if it can find one, or @{upstream} otherwise.  Once you have\n+#       set GIT_PS1_SHOWUPSTREAM, you can override it on a\n+#       per-repository basis by setting the bash.showUpstream config\n+#       variable.\n+#\n+#\n # To submit patches:\n #\n #    *) Read Documentation/SubmittingPatches\n@@ -78,6 +96,125 @@ __gitdir ()\n \tfi\n }\n \n+# stores the divergence from upstream in $p\n+# used by GIT_PS1_SHOWUPSTREAM\n+__git_ps1_show_upstream ()\n+{\n+\tlocal key value\n+\tlocal svn_remote=() svn_url_pattern count n\n+\tlocal upstream=git legacy=\"\" verbose=\"\"\n+\n+\t# get some config options from git-config\n+\twhile read key value; do\n+\t\tcase \"$key\" in\n+\t\tbash.showupstream)\n+\t\t\tGIT_PS1_SHOWUPSTREAM=\"$value\"\n+\t\t\tif [[ -z \"${GIT_PS1_SHOWUPSTREAM}\" ]]; then\n+\t\t\t\tp=\"\"\n+\t\t\t\treturn\n+\t\t\tfi\n+\t\t\t;;\n+\t\tsvn-remote.*.url)\n+\t\t\tsvn_remote[ $((${#svn_remote[@]} + 1)) ]=\"$value\"\n+\t\t\tsvn_url_pattern+=\"\\\\|$value\"\n+\t\t\tupstream=svn+git # default upstream is SVN if available, else git\n+\t\t\t;;\n+\t\tesac\n+\tdone < <(git config -z --get-regexp '^(svn-remote\\..*\\.url|bash\\.showupstream)$' 2>/dev/null | tr '\\0\\n' '\\n ')\n+\n+\t# parse configuration values\n+\tfor option in ${GIT_PS1_SHOWUPSTREAM}; do\n+\t\tcase \"$option\" in\n+\t\tgit|svn) upstream=\"$option\" ;;\n+\t\tverbose) verbose=1 ;;\n+\t\tlegacy)  legacy=1  ;;\n+\t\tesac\n+\tdone\n+\n+\t# Find our upstream\n+\tcase \"$upstream\" in\n+\tgit)    upstream=\"@{upstream}\" ;;\n+\tsvn*)\n+\t\t# get the upstream from the \"git-svn-id: ...\" in a commit message\n+\t\t# (git-svn uses essentially the same procedure internally)\n+\t\tlocal svn_upstream=($(git log --first-parent -1 \\\n+\t\t\t\t\t--grep=\"^git-svn-id: \\(${svn_url_pattern:2}\\)\" 2>/dev/null))\n+\t\tif [[ 0 -ne ${#svn_upstream[@]} ]]; then\n+\t\t\tsvn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}\n+\t\t\tsvn_upstream=${svn_upstream%@*}\n+\t\t\tfor ((n=1; \"$n\" <= \"${#svn_remote[@]}\"; ++n)); do\n+\t\t\t\tsvn_upstream=${svn_upstream#${svn_remote[$n]}}\n+\t\t\tdone\n+\n+\t\t\tif [[ -z \"$svn_upstream\" ]]; then\n+\t\t\t\t# default branch name for checkouts with no layout:\n+\t\t\t\tupstream=${GIT_SVN_ID:-git-svn}\n+\t\t\telse\n+\t\t\t\tupstream=${svn_upstream#/}\n+\t\t\tfi\n+\t\telif [[ \"svn+git\" = \"$upstream\" ]]; then\n+\t\t\tupstream=\"@{upstream}\"\n+\t\tfi\n+\t\t;;\n+\tesac\n+\n+\t# Find how many commits we are ahead/behind our upstream\n+\tif [[ -z \"$legacy\" ]]; then\n+\t\tcount=\"$(git rev-list --count --left-right \\\n+\t\t\t\t\"$upstream\"...HEAD 2>/dev/null)\"\n+\telse\n+\t\t# produce equivalent output to --count for older versions of git\n+\t\tlocal commits\n+\t\tif commits=\"$(git rev-list --left-right \"$upstream\"...HEAD 2>/dev/null)\"\n+\t\tthen\n+\t\t\tlocal commit behind=0 ahead=0\n+\t\t\tfor commit in $commits\n+\t\t\tdo\n+\t\t\t\tcase \"$commit\" in\n+\t\t\t\t\"<\"*) let ++behind\n+\t\t\t\t\t;;\n+\t\t\t\t*)    let ++ahead\n+\t\t\t\t\t;;\n+\t\t\t\tesac\n+\t\t\tdone\n+\t\t\tcount=\"$behind\t$ahead\"\n+\t\telse\n+\t\t\tcount=\"\"\n+\t\tfi\n+\tfi\n+\n+\t# calculate the result\n+\tif [[ -z \"$verbose\" ]]; then\n+\t\tcase \"$count\" in\n+\t\t\"\") # no upstream\n+\t\t\tp=\"\" ;;\n+\t\t\"0\t0\") # equal to upstream\n+\t\t\tp=\"=\" ;;\n+\t\t\"0\t\"*) # ahead of upstream\n+\t\t\tp=\">\" ;;\n+\t\t*\"\t0\") # behind upstream\n+\t\t\tp=\"<\" ;;\n+\t\t*)\t    # diverged from upstream\n+\t\t\tp=\"<>\" ;;\n+\t\tesac\n+\telse\n+\t\tcase \"$count\" in\n+\t\t\"\") # no upstream\n+\t\t\tp=\"\" ;;\n+\t\t\"0\t0\") # equal to upstream\n+\t\t\tp=\" u=\" ;;\n+\t\t\"0\t\"*) # ahead of upstream\n+\t\t\tp=\" u+${count#0\t}\" ;;\n+\t\t*\"\t0\") # behind upstream\n+\t\t\tp=\" u-${count%\t0}\" ;;\n+\t\t*)\t    # diverged from upstream\n+\t\t\tp=\" u+${count#*\t}-${count%\t*}\" ;;\n+\t\tesac\n+\tfi\n+\n+}\n+\n+\n # __git_ps1 accepts 0 or 1 arguments (i.e., format string)\n # returns text to add to bash PS1 prompt (includes branch name)\n __git_ps1 ()\n@@ -132,6 +269,7 @@ __git_ps1 ()\n \t\tlocal s\n \t\tlocal u\n \t\tlocal c\n+\t\tlocal p\n \n \t\tif [ \"true\" = \"$(git rev-parse --is-inside-git-dir 2>/dev/null)\" ]; then\n \t\t\tif [ \"true\" = \"$(git rev-parse --is-bare-repository 2>/dev/null)\" ]; then\n@@ -159,10 +297,14 @@ __git_ps1 ()\n \t\t\t      u=\"%\"\n \t\t\t   fi\n \t\t\tfi\n+\n+\t\t\tif [ -n \"${GIT_PS1_SHOWUPSTREAM-}\" ]; then\n+\t\t\t\t__git_ps1_show_upstream\n+\t\t\tfi\n \t\tfi\n \n \t\tlocal f=\"$w$i$s$u\"\n-\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r\"\n+\t\tprintf \"${1:- (%s)}\" \"$c${b##refs/heads/}${f:+ $f}$r$p\"\n \tfi\n }\n \n-- \n1.7.0.4\n"},{"id":"143889","messageId":"4C1A9460.6080905@pileofstuff.org","threadId":"24085","inReplyTo":"7v7hlyg5nh.fsf@alter.siamese.dyndns.org","subject":"[PATCHv5 2/2] bash-completion: Fix __git_ps1 to work with \"set -u\"","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-17T21:32:16Z","receivedAt":"2010-06-17T21:32:16Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"Define several variables in __git_ps1 to avoid errors under \"set -u\" semantics.\n\n__git_ps1 seems to have been missed when the rest of the file was fixed in\n25a31f8.\n\nSigned-off-by: Andrew Sayers <andrew-git@pileofstuff.org>\n---\n contrib/completion/git-completion.bash |   16 ++++++++--------\n 1 files changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 6e6f458..337e4c9 100755\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -221,8 +221,8 @@ __git_ps1 ()\n {\n \tlocal g=\"$(__gitdir)\"\n \tif [ -n \"$g\" ]; then\n-\t\tlocal r\n-\t\tlocal b\n+\t\tlocal r=\"\"\n+\t\tlocal b=\"\"\n \t\tif [ -f \"$g/rebase-merge/interactive\" ]; then\n \t\t\tr=\"|REBASE-i\"\n \t\t\tb=\"$(cat \"$g/rebase-merge/head-name\")\"\n@@ -264,12 +264,12 @@ __git_ps1 ()\n \t\t\t}\n \t\tfi\n \n-\t\tlocal w\n-\t\tlocal i\n-\t\tlocal s\n-\t\tlocal u\n-\t\tlocal c\n-\t\tlocal p\n+\t\tlocal w=\"\"\n+\t\tlocal i=\"\"\n+\t\tlocal s=\"\"\n+\t\tlocal u=\"\"\n+\t\tlocal c=\"\"\n+\t\tlocal p=\"\"\n \n \t\tif [ \"true\" = \"$(git rev-parse --is-inside-git-dir 2>/dev/null)\" ]; then\n \t\t\tif [ \"true\" = \"$(git rev-parse --is-bare-repository 2>/dev/null)\" ]; then\n-- \n1.7.0.4\n"},{"id":"143909","messageId":"7vljacxqwc.fsf@alter.siamese.dyndns.org","threadId":"24085","inReplyTo":"4C1A9442.7080304@pileofstuff.org","subject":"Re: [PATCHv5 0/2] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-18T16:10:59Z","receivedAt":"2010-06-18T16:10:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andrew Sayers <andrew-git@pileofstuff.org> writes:\n\n>>> +#       You can\n>>> +#       override the value of GIT_PS1_SHOWUPSTREAM on a per-repository\n>>> +#       basis by setting the bash.showUpstream config variable.\n>> \n>> That's totally backwards from it should be, isn't it?\n>> \n>> Usually configuration variables are used to give you the default, and\n>> you use environment variables to override them.\n>\n> I basically agree with Thomas here.\n\nOk.\n\n> ...  If someone had e.g. imported their old\n> SVN history into a git project, or did clever git tricks on a branch\n> they regularly merged into SVN, they would want to override the default\n> behaviour.  This is probably quite rare now I think about it, and I've\n> rejigged the documentation a bit to reflect that.\n\nYeah, I see.\n\nBut doesn't all of the above suggest the decision should be per branch?\nIt is not too implausible to have a branch that is actively interacting\nwith SVN upstream and another branch whose upstream has migrated from SVN\nand now managed by git.  Say you and your pal are working with a project\nthat is managed by SVN, and you use one of your branches to interact\ndirectly with SVN upstream.  Your pal has a branch forked from the same\nSVN upstream, and one of your other branches is building on top of her\nwork.  When you are on the former branch, you would want to know how your\nwork diverged from the SVN upstream; when you are on the latter branch,\nyou would want to know how your work diverged from your pal's git branch\nthat you are using as its upstream.  No?\n\nWhich led me to this expectation:\n\n>>> +\t\t\tsvn-remote.*.url)\n>>> +\t\t\t\tsvn_remote[ $((${#svn_remote[@]} + 1)) ]=\"$value\"\n>>> +\t\t\t\tsvn_url_pattern+=\"\\\\|$value\"\n>>> +\t\t\t\tupstream=svn # default upstream is SVN if available\n>>> +\t\t\t\t;;\n>> \n>> I expected that (1) when on a branch that is a fork of a svn upstream, you\n>> would use the svn magic; (2) otherwise when on a branch that is a fork of\n>> a git upstream, you would use \"@{upstream}\".  That way, the users do not\n>> even have to say \"git\" or \"svn\" in GIT_PS1_SHOWUPSTREAM at all, no?\n\nI wonder if looking for \"git-svn-id:\" in the past log is the best you can\ndo to see if a branch is forked from a remote that is managed by git-svn;\nfor one thing, that would not work for \"noMetadata\" setting.\n\n>> If you \"tr\" to trash \"\\0\" anyway, do you need to run \"config -z\"?\n>\n> The `tr` is there to work around issues like this:\n>\n> \tgit config bash.showUpstream $'svn\\nlegacy'\n> \tgit config bash.showUpstream | tr '\\0\\n' '\\n '\n\nIs that even an issue?  Why should there be a LF in the value?  I thought\nyou defined it as a string with space separated magic tokens...  Perhaps I\nam missing something?\n"},{"id":"143924","messageId":"4C1BDED3.2090002@pileofstuff.org","threadId":"24085","inReplyTo":"7vljacxqwc.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCHv5 0/2] bash completion: Support \"divergence from upstream\" messages in __git_ps1","fromName":"Andrew Sayers","fromEmail":"andrew-git@pileofstuff.org","sentAt":"2010-06-18T21:02:11Z","receivedAt":"2010-06-18T21:02:11Z","isPatch":false,"sender":{"key":"andrew-git@pileofstuff.org","avatar":null},"body":"On 18/06/10 17:10, Junio C Hamano wrote:\n> \n> But doesn't all of the above suggest the decision should be per branch?\n> It is not too implausible to have a branch that is actively interacting\n> with SVN upstream and another branch whose upstream has migrated from SVN\n> and now managed by git.  Say you and your pal are working with a project\n> that is managed by SVN, and you use one of your branches to interact\n> directly with SVN upstream.  Your pal has a branch forked from the same\n> SVN upstream, and one of your other branches is building on top of her\n> work.  When you are on the former branch, you would want to know how your\n> work diverged from the SVN upstream; when you are on the latter branch,\n> you would want to know how your work diverged from your pal's git branch\n> that you are using as its upstream.  No?\n> \n\nIt sounds like you're asking for git-svn to set\ngit.<branch>.{remote|upstream}, and for this script to ditch the\nSVN-specific workarounds.  I have no problem with such a solution, but I\nalso have no idea where to begin with it.  Is there some reason we don't\ndo this already?\n\nA simpler 90% solution would be to switch the defaults around, so you\nalways use @{upstream} if defined, or otherwise search for the SVN\nupstream.  This enables every use case except noMetadata, and I suspect\nany solution to that one would be at least as complex as setting\ngit.<branch>.{remote|upstream}.\n\n>>> If you \"tr\" to trash \"\\0\" anyway, do you need to run \"config -z\"?\n>>\n>> The `tr` is there to work around issues like this:\n>>\n>> \tgit config bash.showUpstream $'svn\\nlegacy'\n>> \tgit config bash.showUpstream | tr '\\0\\n' '\\n '\n> \n> Is that even an issue?  Why should there be a LF in the value?  I thought\n> you defined it as a string with space separated magic tokens...  Perhaps I\n> am missing something?\n\nMy concern was more with the robustness principle than anything - LFs\naren't part of the format defined in the docs, and I can't think of a\nreason why people would need them, but there's no mechanical way to stop\npeople putting them in there.  If you're saying that git users can be\ntrusted not to do anything so stupid (and/or that it's their problem if\nthey do), then I'm happy to get rid of this.\n\n\t- Andrew\n"}]}