{"thread":{"id":"10536","subject":"[PATCH 1/1] Add --first-parent support to interactive rebase.","startedAt":"2007-10-31T02:21:49Z","lastAt":"2007-11-01T04:14:08Z","messageCount":18,"participants":["Björn Steinbrink","Johannes Schindelin","Junio C Hamano","Wincent Colaiuta","Dmitry Potapov","Karl Hasselström","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"57646","messageId":"1193797309-1161-1-git-send-email-B.Steinbrink@gmx.de","threadId":"10536","inReplyTo":null,"subject":"[PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2007-10-31T02:21:49Z","receivedAt":"2007-10-31T02:21:49Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"By default, rebase will take all commits from the branch that is to be\nrebased which are missing in upstream. The new --first-parent option\nallows to just follow the first parent and thus completely ignore\nmerges.\n\nAdditionally, when used together with --preserve-merges (which is the\nmore useful use-case) it will no longer rebase the commits from the\nmerged-in branches, but instead redo the merge with the original\nparents.\n\nThat means that:\n     ---H------I topicB\n    /    \\      \\\n    | D---E---F--G topicA\n    |/\n    A---B---C master\n\ndoes no longer become:\n                -H'--------I'\n               /  \\         \\\n              D'---E'---F'---G' topicA\n             /\n    A---B---C master\n     \\\n      H---I topicB\n\nbut instead:\n    A---B---C master\n     \\       \\\n      \\       D'---E'---F'---G' topicA\n       \\          /         /\n        ---------H---------I topicB\n\nSigned-off-by: BjÃ¶rn Steinbrink <B.Steinbrink@gmx.de>\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex e4326d3..0b5f4b6 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git-rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]\n \t[-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]\n-\t[--onto <newbase>] <upstream> [<branch>]\n+\t[--first-parent] [--onto <newbase>] <upstream> [<branch>]\n 'git-rebase' --continue | --skip | --abort\n \n DESCRIPTION\n@@ -166,6 +166,52 @@ This is useful if F and G were flawed in some way, or should not be\n part of topicA.  Note that the argument to --onto and the <upstream>\n parameter can be any valid commit-ish.\n \n+If you have a branch that contains merges which you want to preserve, you\n+can use the --preserve-merges option. By default, this will duplicate all\n+merged commits on top of <upstream> (or <newbase>) and try to redo the\n+merges using the new commits. Given this situation:\n+\n+------------\n+     ---H------I topicB\n+    /    \\      \\\n+    | D---E---F--G topicA\n+    |/\n+    A---B---C master\n+------------\n+\n+then the command\n+\n+    git rebase -i --preserve-merges master topicA\n+\n+would result in\n+\n+------------\n+                -H'--------I'\n+               /  \\         \\\n+              D'---E'---F'---G' topicA\n+             /\n+    A---B---C master\n+     \\\n+      H---I topicB\n+------------\n+\n+If you pass --first-parent in addition to --preserve-merges, the commits\n+from the merged-in branches won't be duplicated.\n+\n+So the command\n+\n+    git rebase -i --preserve-merges --first-parent master topicA\n+\n+would instead result in\n+\n+------------\n+    A---B---C master\n+     \\       \\\n+      \\       D'---E'---F'---G' topicA\n+       \\          /         /\n+        ---------H---------I topicB\n+------------\n+\n In case of conflict, git-rebase will stop at the first problematic commit\n and leave conflict markers in the tree.  You can use git diff to locate\n the markers (<<<<<<) and make edits to resolve the conflict.  For each\n@@ -246,6 +292,13 @@ OPTIONS\n \tInstead of ignoring merges, try to recreate them.  This option\n \tonly works in interactive mode.\n \n+\\--first-parent::\n+\tOnly follow the first parent commits in merge commits when looking\n+\tfor the commits that are to be rebased. This is most useful with -p\n+\tas it will cause rebase to recreate the merges against the original\n+\tbranches instead of rebasing those branches as well. This option\n+\tonly works in interactive mode.\n+\n include::merge-strategies.txt[]\n \n NOTES\ndiff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh\nindex e63e1c9..38b070e 100755\n--- a/git-rebase--interactive.sh\n+++ b/git-rebase--interactive.sh\n@@ -22,6 +22,7 @@ DONE=\"$DOTEST\"/done\n MSG=\"$DOTEST\"/message\n SQUASH_MSG=\"$DOTEST\"/message-squash\n REWRITTEN=\"$DOTEST\"/rewritten\n+FIRST_PARENT=\n PRESERVE_MERGES=\n STRATEGY=\n VERBOSE=\n@@ -143,14 +144,20 @@ pick_one_preserving_merges () {\n \t\t\tpreserve=f\n \t\t\tnew_p=$(cat \"$REWRITTEN\"/$p)\n \t\t\ttest $p != $new_p && fast_forward=f\n-\t\t\tcase \"$new_parents\" in\n-\t\t\t*$new_p*)\n-\t\t\t\t;; # do nothing; that parent is already there\n-\t\t\t*)\n-\t\t\t\tnew_parents=\"$new_parents $new_p\"\n-\t\t\t\t;;\n-\t\t\tesac\n+\t\telif test t = \"$FIRST_PARENT\"\n+\t\tthen\n+\t\t\tnew_p=$p\n+\t\telse\n+\t\t\tcontinue\n \t\tfi\n+\n+\t\tcase \"$new_parents\" in\n+\t\t*$new_p*)\n+\t\t\t;; # do nothing; that parent is already there\n+\t\t*)\n+\t\t\tnew_parents=\"$new_parents $new_p\"\n+\t\t\t;;\n+\t\tesac\n \tdone\n \tcase $fast_forward in\n \tt)\n@@ -412,6 +419,9 @@ do\n \t-p|--preserve-merges)\n \t\tPRESERVE_MERGES=t\n \t\t;;\n+\t--first-parent)\n+\t\tFIRST_PARENT=t\n+\t\t;;\n \t-i|--interactive)\n \t\t# yeah, we know\n \t\t;;\n@@ -481,6 +491,10 @@ do\n \t\telse\n \t\t\tMERGES_OPTION=--no-merges\n \t\tfi\n+\t\tif test t = \"$FIRST_PARENT\"\n+\t\tthen\n+\t\t\tMERGES_OPTION=\"--first-parent $MERGES_OPTION\"\n+\t\tfi\n \n \t\tSHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)\n \t\tSHORTHEAD=$(git rev-parse --short $HEAD)\n-- \n1.5.3.4.456.g072a\n"},{"id":"57652","messageId":"Pine.LNX.4.64.0710310329520.4362@racer.site","threadId":"10536","inReplyTo":"1193797309-1161-1-git-send-email-B.Steinbrink@gmx.de","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-31T03:34:47Z","receivedAt":"2007-10-31T03:34:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 31 Oct 2007, Björn Steinbrink wrote:\n\n> @@ -246,6 +292,13 @@ OPTIONS\n>  \tInstead of ignoring merges, try to recreate them.  This option\n>  \tonly works in interactive mode.\n>  \n> +\\--first-parent::\n> +\tOnly follow the first parent commits in merge commits when looking\n> +\tfor the commits that are to be rebased. This is most useful with -p\n> +\tas it will cause rebase to recreate the merges against the original\n> +\tbranches instead of rebasing those branches as well. This option\n> +\tonly works in interactive mode.\n> +\n\nHmm.  I had to read this several times to understand it.  Maybe something \nlike this instead?\n\n\\--first-parent::\n\tWhen you want to preserve merges, this option allows you to rebase \n\tonly the commits which were not merged in, i.e. which are in the\n\tfirst parent ancestry of the current HEAD.\n+\nThis option only makes sense together with --preserve-merges.\n\nAlso, could you please add a test case to make sure that your patch works \nas advertised (and that this functionality will not be broken in future \ncommits)?\n\nThanks,\nDscho\n"},{"id":"57653","messageId":"20071031041751.GA3326@atjola.homenet","threadId":"10536","inReplyTo":"Pine.LNX.4.64.0710310329520.4362@racer.site","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2007-10-31T04:17:51Z","receivedAt":"2007-10-31T04:17:51Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2007.10.31 03:34:47 +0000, Johannes Schindelin wrote:\n> Hi,\n> \n> On Wed, 31 Oct 2007, Björn Steinbrink wrote:\n> \n> > @@ -246,6 +292,13 @@ OPTIONS\n> >  \tInstead of ignoring merges, try to recreate them.  This option\n> >  \tonly works in interactive mode.\n> >  \n> > +\\--first-parent::\n> > +\tOnly follow the first parent commits in merge commits when looking\n> > +\tfor the commits that are to be rebased. This is most useful with -p\n> > +\tas it will cause rebase to recreate the merges against the original\n> > +\tbranches instead of rebasing those branches as well. This option\n> > +\tonly works in interactive mode.\n> > +\n> \n> Hmm.  I had to read this several times to understand it.  Maybe something \n> like this instead?\n> \n> \\--first-parent::\n> \tWhen you want to preserve merges, this option allows you to rebase \n> \tonly the commits which were not merged in, i.e. which are in the\n> \tfirst parent ancestry of the current HEAD.\n> +\n> This option only makes sense together with --preserve-merges.\n\nHm, I think that it might make might sense without -p. Say that your\ntopic branch is following two other branches like this:\n\n---o---o---o--------o topicB\n            \\        \\\n--o---A---o---o---o---o---B topicA\n         /       /\no---o---o---o---o master\n\ntopicB branched off from master earlier than topicA and you currently\nrequire stuff from master..topicB _and_ topicB..master, so AFAICT, you\nneed sth. like the above.\n\nLet's say that topicB simplifies some internal API and you desperately\nwanted to use that, while master introduced some new stuff that you also\nuse. Now your stuff is finished, but it becomes obvious that topicB is\nstill too broken to go into master any time soon. Then you could do:\n\ngit rebase -i --first-parent master topicA\n\nto get:\n\n--o---o---o topicB (branched from master somewhere to the left)\n\n             o---o---o---A---B topicA\n            /\n---o---o---o master\n\nDepending on how much topicA really depends on topicB, you might need to\nfix a bunch of stuff, but it might be worth it.\n\nHow about:\n\\--first-parent::\n\tWhen this option is given and --preserve-merges is not, then\n\tmerge commits are completely ignored and only commits from the\n\tfirst parent ancestry are rebased. This allows to pretend that\n\tmerges never happened.\n\n\tIf --preserve-merges is also given, the merge commits are\n\tpreserved, but only their first parent is rebased as opposed to\n\tthe default behaviour which would rebase all parents.\n\n> Also, could you please add a test case to make sure that your patch works \n> as advertised (and that this functionality will not be broken in future \n> commits)?\n\nOk, might take some time, as I currently have no clue how the test stuff\nfor git works :-/ Well, I'm sure #git will be helpful :-)\n\nThanks,\nBjörn\n"},{"id":"57656","messageId":"Pine.LNX.4.64.0710310441530.4362@racer.site","threadId":"10536","inReplyTo":"20071031041751.GA3326@atjola.homenet","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-10-31T04:50:33Z","receivedAt":"2007-10-31T04:50:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 31 Oct 2007, Bj?rn Steinbrink wrote:\n\n> On 2007.10.31 03:34:47 +0000, Johannes Schindelin wrote:\n> \n> > On Wed, 31 Oct 2007, Bj?rn Steinbrink wrote:\n> > \n> > > @@ -246,6 +292,13 @@ OPTIONS\n> > >  \tInstead of ignoring merges, try to recreate them.  This option\n> > >  \tonly works in interactive mode.\n> > >  \n> > > +\\--first-parent::\n> > > +\tOnly follow the first parent commits in merge commits when looking\n> > > +\tfor the commits that are to be rebased. This is most useful with -p\n> > > +\tas it will cause rebase to recreate the merges against the original\n> > > +\tbranches instead of rebasing those branches as well. This option\n> > > +\tonly works in interactive mode.\n> > > +\n> > \n> > Hmm.  I had to read this several times to understand it.  Maybe \n> > something like this instead?\n> > \n> > \\--first-parent::\n> > \tWhen you want to preserve merges, this option allows you to rebase \n> > \tonly the commits which were not merged in, i.e. which are in the\n> > \tfirst parent ancestry of the current HEAD.\n> > +\n> > This option only makes sense together with --preserve-merges.\n> \n> Hm, I think that it might make might sense without -p. Say that your \n> topic branch is following two other branches like this:\n> \n> ---o---o---o--------o topicB\n>             \\        \\\n> --o---A---o---o---o---o---B topicA\n>          /       /\n> o---o---o---o---o master\n> \n> topicB branched off from master earlier than topicA and you currently\n> require stuff from master..topicB _and_ topicB..master, so AFAICT, you\n> need sth. like the above.\n> \n> Let's say that topicB simplifies some internal API and you desperately\n> wanted to use that, while master introduced some new stuff that you also\n> use. Now your stuff is finished, but it becomes obvious that topicB is\n> still too broken to go into master any time soon. Then you could do:\n> \n> git rebase -i --first-parent master topicA\n> \n> to get:\n> \n> --o---o---o topicB (branched from master somewhere to the left)\n> \n>              o---o---o---A---B topicA\n>             /\n> ---o---o---o master\n> \n> Depending on how much topicA really depends on topicB, you might need to\n> fix a bunch of stuff, but it might be worth it.\n\nOkay, I see now.\n\n> How about:\n> \\--first-parent::\n> \tWhen this option is given and --preserve-merges is not, then\n> \tmerge commits are completely ignored and only commits from the\n> \tfirst parent ancestry are rebased. This allows to pretend that\n> \tmerges never happened.\n> \n> \tIf --preserve-merges is also given, the merge commits are\n> \tpreserved, but only their first parent is rebased as opposed to\n> \tthe default behaviour which would rebase all parents.\n\nOkay.\n\n> > Also, could you please add a test case to make sure that your patch \n> > works as advertised (and that this functionality will not be broken in \n> > future commits)?\n> \n> Ok, might take some time, as I currently have no clue how the test stuff \n> for git works :-/ Well, I'm sure #git will be helpful :-)\n\nJust have a look at t/t3404-rebase-interactive.sh.  The easiest way to \nproceed would be to read it from the end.  You'll see that every test case \nstarts with \"test_expect_success\", followed by a message and a piece of \nshell code.\n\nI usually enhance some existing test script instead of inventing a new \none.\n\nIn your case, I would run t3404 by\n\n\tcd t\n\tsh t3404*\n\nThe working directory of these tests is in the subdirectory trash/ of t/.  \nAfter one run of t3404, I would go there and look at what is there with \ngitk.\n\nIn your case, you want to have at least a few merges.  Build them up in \nthe test case, using echo, git add, git commit and git checkout.  Then run \nan appropriate git rebase -i --first-commit [-p], and test that the \noutcome makes sense.\n\nYou need not test _everything_.  Just the differences with regards to \nnormal rebase.  For example, that a side branch is _not_ rebased, but \n\"git rev-parse HEAD~2^2\" is the same as before the rebase.\n\nAnd remember to connect all commands with && so that a failure in one \ncommand leads to the failure of the whole test case.\n\nHth,\nDscho\n"},{"id":"57657","messageId":"7vodefj2lk.fsf@gitster.siamese.dyndns.org","threadId":"10536","inReplyTo":"1193797309-1161-1-git-send-email-B.Steinbrink@gmx.de","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-31T05:05:27Z","receivedAt":"2007-10-31T05:05:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Your MUA seems to mark the UTF-8 message you are sending out as\n8859-1, which means your name in the message gets corrupt.\n\nBjörn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> By default, rebase will take all commits from the branch that is to be\n> rebased which are missing in upstream. The new --first-parent option\n> allows to just follow the first parent and thus completely ignore\n> merges.\n>\n> Additionally, when used together with --preserve-merges (which is the\n> more useful use-case) it will no longer rebase the commits from the\n> merged-in branches, but instead redo the merge with the original\n> parents.\n>\n> That means that:\n>      ---H------I topicB\n\nPlease add a blank line after \"means that:\" for readability.\n\n>     /    \\      \\\n> ...\n> does no longer become:\n>                 -H'--------I'\n\nLikewise; also, \"no longer becomes:\".\n\n>                /  \\         \\\n>               D'---E'---F'---G' topicA\n>              /\n>     A---B---C master\n>      \\\n>       H---I topicB\n>\n> but instead:\n>     A---B---C master\n\nLikewise.\n\n> ...\n>         ---------H---------I topicB\n\nAnd crucially, you forgot to say \"... when you do X\".\n\nI am assuming that you meant:\n\n    This (picture) becomes this (picture) instead of this (picture)\n    when you run \"git rebase -p -m master topicA\".\n\nbut without it, the nice ASCII drawings loses their value.\n\nIt is somewhat disturbing that this treats the first parent too\nspecial.\n"},{"id":"57658","messageId":"20071031055303.GB3326@atjola.homenet","threadId":"10536","inReplyTo":"7vodefj2lk.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2007-10-31T05:53:03Z","receivedAt":"2007-10-31T05:53:03Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2007.10.30 22:05:27 -0700, Junio C Hamano wrote:\n> Your MUA seems to mark the UTF-8 message you are sending out as\n> 8859-1, which means your name in the message gets corrupt.\n\nHm, that would be git-send-email then, anything I need to configure?\n(Actually I don't see it marking the message as anything)\n\n> Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> \n> > By default, rebase will take all commits from the branch that is to be\n> > rebased which are missing in upstream. The new --first-parent option\n> > allows to just follow the first parent and thus completely ignore\n> > merges.\n> >\n> > Additionally, when used together with --preserve-merges (which is the\n> > more useful use-case) it will no longer rebase the commits from the\n> > merged-in branches, but instead redo the merge with the original\n> > parents.\n> >\n> > That means that:\n\nGiven this situation:\n\n> >      ---H------I topicB\n> >     /    \\      \\\n> > ...\n> > does no longer become:\n\nWhich results in:\n\n> >                 -H'--------I'\n> >                /  \\         \\\n> >               D'---E'---F'---G' topicA\n> >              /\n> >     A---B---C master\n> >      \\\n> >       H---I topicB\n\nWhen you do \"git-rebase -p -i master topicA\"\n\nYou can now also get:\n\n> >     A---B---C master\n> > ...\n> >         ---------H---------I topicB\n\nWhen you do \"git-rebase -p -i --first-parent master topicA\"\n\n\nThat's better, right?\n\n> And crucially, you forgot to say \"... when you do X\".\n> \n> I am assuming that you meant:\n> \n>     This (picture) becomes this (picture) instead of this (picture)\n>     when you run \"git rebase -p -m master topicA\".\n> \n> but without it, the nice ASCII drawings loses their value.\n\n:-/\n\n> It is somewhat disturbing that this treats the first parent too\n> special.\n\nThe original use-case for the \"-p -i --first-parent\" case was a question\non #git, where someone had sth. like this:\n\n   o---o---o---o---o remote/branch\n        \\           \\\n     o---o---o---o---o topicA\n    /\n   o---o---o master trunk\n\nNow that guy was using git-svn to dcommit into svn from master. To\ndcommit the changes from topicA he had to have that based on master, and\nhe wanted to preserve the merges from remote/branch to have them\nsquashed when dcommitted to svn. So what he wanted was:\n\n\n     ...---o---o---o---o---o remote/branch\n                \\           \\\n             o---o---o---o---o topicA\n            /\n   o---o---o master trunk\n\nThe default behaviour of rebase would totally flat out the history and\ninstead of two sqaush merges (which he wanted), svn would've seen a huge\namount of commits comning from remote/branch. And the plain -p behaviour\nwould have duplicated all those branches from remote/branch for no good\nreason, so I came up with that --first-parent thing.\n\nBetter ideas are welcome, I just don't know git well enough to come up\nwith anything better...\n\nThanks,\nBjörn\n"},{"id":"57668","messageId":"B168AF44-265B-4339-BD00-10CD1ECB9394@wincent.com","threadId":"10536","inReplyTo":"20071031041751.GA3326@atjola.homenet","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2007-10-31T08:24:36Z","receivedAt":"2007-10-31T08:24:36Z","isPatch":true,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"El 31/10/2007, a las 5:17, Björn Steinbrink escribió:\n\n> How about:\n> \\--first-parent::\n> \tWhen this option is given and --preserve-merges is not, then\n> \tmerge commits are completely ignored and only commits from the\n> \tfirst parent ancestry are rebased. This allows to pretend that\n> \tmerges never happened.\n>\n> \tIf --preserve-merges is also given, the merge commits are\n> \tpreserved, but only their first parent is rebased as opposed to\n> \tthe default behaviour which would rebase all parents.\n\n\nMinor nitpick:\n\n-\tfirst parent ancestry are rebased. This allows to pretend that\n+\tfirst parent ancestry are rebased. This allows you to pretend that\n\nCheers,\nWincent\n"},{"id":"57693","messageId":"20071031134358.GD15182@dpotapov.dyndns.org","threadId":"10536","inReplyTo":"20071031055303.GB3326@atjola.homenet","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2007-10-31T13:43:58Z","receivedAt":"2007-10-31T13:43:58Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Wed, Oct 31, 2007 at 06:53:03AM +0100, Björn Steinbrink wrote:\n> On 2007.10.30 22:05:27 -0700, Junio C Hamano wrote:\n> > Your MUA seems to mark the UTF-8 message you are sending out as\n> > 8859-1, which means your name in the message gets corrupt.\n> \n> Hm, that would be git-send-email then, anything I need to configure?\n> (Actually I don't see it marking the message as anything)\n\nI believe that the issue is with Junio's mail client. Indeed, the\ncontext encoding for the mail *body* was specified as 8859-1, but\nthat should have none effect on fields in the mail header, because\nany field is the header should be either printable ASCII or encoded\nto contain only ASCII characters as specified in RFC 1522:\n\nencoded-word = \"=?\" charset \"?\" encoding \"?\" encoded-text \"?=\"\n\nHere is the From field from the mail:\n\nFrom:\t=?utf-8?q?Bj=C3=B6rn=20Steinbrink?= <B.Steinbrink@gmx.de>\n\nSo, as far as I can tell, it is encoded properly using utf-8.\n\nDmitry\n"},{"id":"57697","messageId":"20071031140028.GA30207@diana.vm.bytemark.co.uk","threadId":"10536","inReplyTo":"20071031134358.GD15182@dpotapov.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-10-31T14:00:28Z","receivedAt":"2007-10-31T14:00:28Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-10-31 16:43:58 +0300, Dmitry Potapov wrote:\n\n> I believe that the issue is with Junio's mail client. Indeed, the\n> context encoding for the mail *body* was specified as 8859-1, but\n> that should have none effect on fields in the mail header, because\n> any field is the header should be either printable ASCII or encoded\n> to contain only ASCII characters as specified in RFC 1522:\n\nYes. But it's the body that's been mangled -- specifically, the\nSign-off line.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"57703","messageId":"20071031143641.GF15182@dpotapov.dyndns.org","threadId":"10536","inReplyTo":"20071031140028.GA30207@diana.vm.bytemark.co.uk","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2007-10-31T14:36:41Z","receivedAt":"2007-10-31T14:36:41Z","isPatch":true,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Wed, Oct 31, 2007 at 03:00:28PM +0100, Karl Hasselström wrote:\n> On 2007-10-31 16:43:58 +0300, Dmitry Potapov wrote:\n> \n> > I believe that the issue is with Junio's mail client. Indeed, the\n> > context encoding for the mail *body* was specified as 8859-1, but\n> > that should have none effect on fields in the mail header, because\n> > any field is the header should be either printable ASCII or encoded\n> > to contain only ASCII characters as specified in RFC 1522:\n> \n> Yes. But it's the body that's been mangled -- specifically, the\n> Sign-off line.\n\nHmm... I looked at the mail again and I cannot see where 8859-1 is\nspecified. It seems that context encoding is not specified at all.\nOf course, it is incorrect to use non ASCII characters in a mail\nwithout specifying encoding. Apparently, because I use utf-8 in the\nterminal, the Sign-off line displays correctly for me, so I did not\nnotice the problem. Sorry for the noise...\n\nDmitry\n"},{"id":"57716","messageId":"20071031180557.GA12211@coredump.intra.peff.net","threadId":"10536","inReplyTo":"20071031143641.GF15182@dpotapov.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-31T18:05:57Z","receivedAt":"2007-10-31T18:05:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 31, 2007 at 05:36:41PM +0300, Dmitry Potapov wrote:\n\n> Hmm... I looked at the mail again and I cannot see where 8859-1 is\n> specified. It seems that context encoding is not specified at all.\n> Of course, it is incorrect to use non ASCII characters in a mail\n> without specifying encoding. Apparently, because I use utf-8 in the\n> terminal, the Sign-off line displays correctly for me, so I did not\n> notice the problem. Sorry for the noise...\n\nIt is our old friend vger adding the iso-8859-1 header, I think, since\nno encoding was specified.\n\nI think the problem is that git-format-patch only decides whether to\nappend a MIME header based on the commit message contents; it does not\ntake the Signed-Off-By into account. This may also be the cause of the\nrecent complaints from Matti Aarnio.\n\n-Peff\n"},{"id":"57721","messageId":"20071031195016.GA24332@atjola.homenet","threadId":"10536","inReplyTo":"20071031180557.GA12211@coredump.intra.peff.net","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2007-10-31T19:50:16Z","receivedAt":"2007-10-31T19:50:16Z","isPatch":true,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2007.10.31 14:05:57 -0400, Jeff King wrote:\n> On Wed, Oct 31, 2007 at 05:36:41PM +0300, Dmitry Potapov wrote:\n> \n> > Hmm... I looked at the mail again and I cannot see where 8859-1 is\n> > specified. It seems that context encoding is not specified at all.\n> > Of course, it is incorrect to use non ASCII characters in a mail\n> > without specifying encoding. Apparently, because I use utf-8 in the\n> > terminal, the Sign-off line displays correctly for me, so I did not\n> > notice the problem. Sorry for the noise...\n> \n> It is our old friend vger adding the iso-8859-1 header, I think, since\n> no encoding was specified.\n> \n> I think the problem is that git-format-patch only decides whether to\n> append a MIME header based on the commit message contents; it does not\n> take the Signed-Off-By into account. This may also be the cause of the\n> recent complaints from Matti Aarnio.\n\nYep, that's it. If the Signed-Off-By was added by commit -s, it works,\nwhile format-patch -s causes the header to be missing, although the\nSigned-Off-By is utf-8 encoded. Will try to remember that.\n\nThanks,\nBjörn\n"},{"id":"57749","messageId":"7v8x5jgdck.fsf@gitster.siamese.dyndns.org","threadId":"10536","inReplyTo":"20071031180557.GA12211@coredump.intra.peff.net","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-31T21:53:47Z","receivedAt":"2007-10-31T21:53:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> It is our old friend vger adding the iso-8859-1 header, I think, since\n> no encoding was specified.\n>\n> I think the problem is that git-format-patch only decides whether to\n> append a MIME header based on the commit message contents; it does not\n> take the Signed-Off-By into account. This may also be the cause of the\n> recent complaints from Matti Aarnio.\n\nI agree.  \"Signed-off-by\" as part of the existing commit message\nshould be fine, but with \"format-patch -s\" the code needs to be\ncareful.\n\nThe following is on top of 'master'.  I haven't tested it.  If it\nworks, great.  If it doesn't, at least it should illustrate what\nneeds to be touched.\n\nIdeally a fix to 'maint' is needed --- the pretty-print\ninfrastructure on the 'master' side has strbuf changes and the\npatch may have conflicts at the textual level, but it should be\nstraightforward to adjust to it by anybody so inclined (hint,\nhint).\n\n---\n\n builtin-branch.c      |    2 +-\n builtin-log.c         |    2 +-\n builtin-rev-list.c    |    3 ++-\n builtin-show-branch.c |    2 +-\n commit.c              |    5 ++---\n commit.h              |    4 +++-\n log-tree.c            |   15 ++++++++++++++-\n 7 files changed, 24 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin-branch.c b/builtin-branch.c\nindex 3da8b55..3e020cc 100644\n--- a/builtin-branch.c\n+++ b/builtin-branch.c\n@@ -276,7 +276,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,\n \t\tcommit = lookup_commit(item->sha1);\n \t\tif (commit && !parse_commit(commit)) {\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t\t    &subject, 0, NULL, NULL, 0);\n+\t\t\t\t\t    &subject, 0, NULL, NULL, 0, 0);\n \t\t\tsub = subject.buf;\n \t\t}\n \t\tprintf(\"%c %s%-*s%s %s %s\\n\", c, branch_get_color(color),\ndiff --git a/builtin-log.c b/builtin-log.c\nindex e8b982d..8b2bf63 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -787,7 +787,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)\n \t\t\tstruct strbuf buf;\n \t\t\tstrbuf_init(&buf, 0);\n \t\t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t                    &buf, 0, NULL, NULL, 0);\n+\t\t\t                    &buf, 0, NULL, NULL, 0, 0);\n \t\t\tprintf(\"%c %s %s\\n\", sign,\n \t\t\t       sha1_to_hex(commit->object.sha1), buf.buf);\n \t\t\tstrbuf_release(&buf);\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 4439332..6970467 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -86,7 +86,8 @@ static void show_commit(struct commit *commit)\n \t\tstruct strbuf buf;\n \t\tstrbuf_init(&buf, 0);\n \t\tpretty_print_commit(revs.commit_format, commit,\n-\t\t\t\t\t&buf, revs.abbrev, NULL, NULL, revs.date_mode);\n+\t\t\t\t    &buf, revs.abbrev, NULL, NULL,\n+\t\t\t\t    revs.date_mode, 0);\n \t\tif (buf.len)\n \t\t\tprintf(\"%s%c\", buf.buf, hdr_termination);\n \t\tstrbuf_release(&buf);\ndiff --git a/builtin-show-branch.c b/builtin-show-branch.c\nindex 07a0c23..6dc835d 100644\n--- a/builtin-show-branch.c\n+++ b/builtin-show-branch.c\n@@ -266,7 +266,7 @@ static void show_one_commit(struct commit *commit, int no_name)\n \tstrbuf_init(&pretty, 0);\n \tif (commit->object.parsed) {\n \t\tpretty_print_commit(CMIT_FMT_ONELINE, commit,\n-\t\t\t\t\t&pretty, 0, NULL, NULL, 0);\n+\t\t\t\t    &pretty, 0, NULL, NULL, 0, 0);\n \t\tpretty_str = pretty.buf;\n \t}\n \tif (!prefixcmp(pretty_str, \"[PATCH] \"))\ndiff --git a/commit.c b/commit.c\nindex ac24266..8262f6a 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -479,7 +479,7 @@ static int get_one_line(const char *msg)\n }\n \n /* High bit set, or ISO-2022-INT */\n-static int non_ascii(int ch)\n+int non_ascii(int ch)\n {\n \tch = (ch & 0xff);\n \treturn ((ch & 0x80) || (ch == 0x1b));\n@@ -1046,12 +1046,11 @@ static void pp_remainder(enum cmit_fmt fmt,\n void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,\n \t\t\t\t  struct strbuf *sb, int abbrev,\n \t\t\t\t  const char *subject, const char *after_subject,\n-\t\t\t\t  enum date_mode dmode)\n+\t\t\t\t  enum date_mode dmode, int plain_non_ascii)\n {\n \tunsigned long beginning_of_body;\n \tint indent = 4;\n \tconst char *msg = commit->buffer;\n-\tint plain_non_ascii = 0;\n \tchar *reencoded;\n \tconst char *encoding;\n \ndiff --git a/commit.h b/commit.h\nindex b779de8..678c62b 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -61,13 +61,15 @@ enum cmit_fmt {\n \tCMIT_FMT_UNSPECIFIED,\n };\n \n+extern int non_ascii(int);\n extern enum cmit_fmt get_commit_format(const char *arg);\n extern void format_commit_message(const struct commit *commit,\n                                   const void *format, struct strbuf *sb);\n extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,\n                                 struct strbuf *,\n                                 int abbrev, const char *subject,\n-                                const char *after_subject, enum date_mode);\n+                                const char *after_subject, enum date_mode,\n+\t\t\t\tint non_ascii_present);\n \n /** Removes the first commit from a list sorted by date, and adds all\n  * of its parents.\ndiff --git a/log-tree.c b/log-tree.c\nindex 3763ce9..a34beb0 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -125,6 +125,18 @@ static unsigned int digits_in_number(unsigned int number)\n \treturn result;\n }\n \n+static int has_non_ascii(const char *s)\n+{\n+\tint ch;\n+\tif (!s)\n+\t\treturn 0;\n+\twhile ((ch = *s++) != '\\0') {\n+\t\tif (non_ascii(ch))\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n void show_log(struct rev_info *opt, const char *sep)\n {\n \tstruct strbuf msgbuf;\n@@ -273,7 +285,8 @@ void show_log(struct rev_info *opt, const char *sep)\n \t */\n \tstrbuf_init(&msgbuf, 0);\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf,\n-\t\t\t\t  abbrev, subject, extra_headers, opt->date_mode);\n+\t\t\t    abbrev, subject, extra_headers, opt->date_mode,\n+\t\t\t    has_non_ascii(opt->add_signoff));\n \n \tif (opt->add_signoff)\n \t\tappend_signoff(&msgbuf, opt->add_signoff);\n"},{"id":"57750","messageId":"20071031215625.GC14211@coredump.intra.peff.net","threadId":"10536","inReplyTo":"7v8x5jgdck.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-10-31T21:56:26Z","receivedAt":"2007-10-31T21:56:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 31, 2007 at 02:53:47PM -0700, Junio C Hamano wrote:\n\n> The following is on top of 'master'.  I haven't tested it.  If it\n> works, great.  If it doesn't, at least it should illustrate what\n> needs to be touched.\n\nYou beat me to it, as I was busy flaming Linus. :)\n\nThe patch I started is very similar to this, but I had one concern that\nI was tracking down: is the author name encoding necessarily the same as\nthe commit text encoding?\n\n-Peff\n"},{"id":"57755","messageId":"7vzlxygblz.fsf@gitster.siamese.dyndns.org","threadId":"10536","inReplyTo":"20071031215625.GC14211@coredump.intra.peff.net","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-31T22:31:20Z","receivedAt":"2007-10-31T22:31:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> ... I had one concern that\n> I was tracking down: is the author name encoding necessarily the same as\n> the commit text encoding?\n\nThe user is screwing himself already if that is the case and\nuses -s to format-patch, isn't he?\n"},{"id":"57773","messageId":"20071101032303.GA14495@coredump.intra.peff.net","threadId":"10536","inReplyTo":"7vzlxygblz.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-01T03:23:03Z","receivedAt":"2007-11-01T03:23:03Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 31, 2007 at 03:31:20PM -0700, Junio C Hamano wrote:\n\n> > ... I had one concern that\n> > I was tracking down: is the author name encoding necessarily the same as\n> > the commit text encoding?\n> \n> The user is screwing himself already if that is the case and\n> uses -s to format-patch, isn't he?\n\nHrm, they probably _should_ be the same in the output. It's not clear to\nme what encoding we assume the name comes in (utf-8, I guess). Looks\nlike we don't touch it at all when putting it in the signoff. I think we\nshould just be able to reencode when appending the signoff; patch is\nbelow.\n\nI'm sure there are other weird interactions lurking. For example, do we\ncorrectly detect an existing signoff if we are storing in a non-utf8\nencoding? I must admit to being a little ignorant to some of the\nencoding magic of git, having a us-ascii name myself.\n\n---\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 3763ce9..906942d 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -3,6 +3,7 @@\n #include \"commit.h\"\n #include \"log-tree.h\"\n #include \"reflog-walk.h\"\n+#include \"utf8.h\"\n \n struct decoration name_decoration = { \"object names\" };\n \n@@ -111,7 +112,14 @@ static void append_signoff(struct strbuf *sb, const char *signoff)\n \t\tstrbuf_addch(sb, '\\n');\n \n \tstrbuf_addstr(sb, signed_off_by);\n-\tstrbuf_add(sb, signoff, signoff_len);\n+\tif (git_log_output_encoding) {\n+\t\tchar *encoded_name = reencode_string(signoff,\n+\t\t\t\tgit_log_output_encoding, \"utf-8\");\n+\t\tstrbuf_addstr(sb, encoded_name);\n+\t\tfree(encoded_name);\n+\t}\n+\telse\n+\t\tstrbuf_add(sb, signoff, signoff_len);\n \tstrbuf_addch(sb, '\\n');\n }\n \n"},{"id":"57775","messageId":"7vabpyfvwp.fsf@gitster.siamese.dyndns.org","threadId":"10536","inReplyTo":"20071101032303.GA14495@coredump.intra.peff.net","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-11-01T04:10:30Z","receivedAt":"2007-11-01T04:10:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Oct 31, 2007 at 03:31:20PM -0700, Junio C Hamano wrote:\n>\n>> > ... I had one concern that\n>> > I was tracking down: is the author name encoding necessarily the same as\n>> > the commit text encoding?\n>> \n>> The user is screwing himself already if that is the case and\n>> uses -s to format-patch, isn't he?\n>\n> Hrm, they probably _should_ be the same in the output. It's not clear to\n> me what encoding we assume the name comes in (utf-8, I guess). Looks\n> like we don't touch it at all when putting it in the signoff. I think we\n> should just be able to reencode when appending the signoff; patch is\n> below.\n\nI think assuming utf-8 and reencoding is actively wrong.\nExisting setups of people with names that cannot be expressed in\nASCII would already have the commit encoding specified in the\nconfiguration and user.name stored in that encoding, so passing\nthings through as we have always done is the right thing to do.\n"},{"id":"57777","messageId":"20071101041408.GA18646@coredump.intra.peff.net","threadId":"10536","inReplyTo":"7vabpyfvwp.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/1] Add --first-parent support to interactive rebase.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-11-01T04:14:08Z","receivedAt":"2007-11-01T04:14:08Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Oct 31, 2007 at 09:10:30PM -0700, Junio C Hamano wrote:\n\n> I think assuming utf-8 and reencoding is actively wrong.\n> Existing setups of people with names that cannot be expressed in\n> ASCII would already have the commit encoding specified in the\n> configuration and user.name stored in that encoding, so passing\n> things through as we have always done is the right thing to do.\n\nThat will break any time somebody uses -s with a --encoding= that is\ndifferent from their usual encoding. My patch assumes the source is\nutf-8, but should perhaps assume some other default encoding from the\nconfig.\n\nBut if this is not a problem for people, I'm not going to push it. I\ndon't actually use any of these features; it was just something I\nnoticed while looking at the actual bug.\n\n-Peff\n"}]}