* Junio C Hamano <gitster@xxxxxxxxx> [140102 21:29]: > > This optimization, while being faster in the usual case, means that in > > the case of cherry-picks the blamed commit depends on which other commits > > touched a file. > > > > If for example one commit A modified both files b and c. And there are > > commits B and C, B only modifies file b and C only modifies file c > > (so that no conflicts happen), and assume A is cherry-picked as A' > > and the two branches then merged: > > > > --o-----B---A > > \ \ > > ---C---A'--M--- > > So the contents of b at M is as the same as in A, so following 'b' > will see A and B changed that path, which is correct. > > The contents of c at M is? It is different from A because at A c > lacks the change made to it at C. The merged result at M would > match C in A', no? So following 'c' will see A' and C changed that > path, no? > > So what is wrong about it? It's not wrong (that's why I do not suggest to change the default behaviour), but it's inconsistent and can be a bit confusing to have either the one or the other commit blamed depending on whether some file was touched or not. The history I'm a bit more concerned is something like (with ... being unrelated commits not touching B or C): --o-----...---A--...---B---...-- \ \ ---...---A'--...---C---...---M--- Here having B or C touching b or c determines which of A or A' is blamed for which part of the patch. It's even enough to have: --...---A'--...---B---...-- / \ ---o---...---A--................---M--- To have the A/A' changes of c to be attributed to A while the b changes are attributed to A'. I.e. you have a master branch that has commit A, which is also cherry-picked to some previously forked side-branch. Once that side-branch is merged back, parts of the change are attributed to A' if they are in a file that is not touched otherwise in the main branch. > Also, when handling a merge, we have to handle parents sequencially, > checking the difference between M with its first parent first, and > then passing blame for the remaining common lines to the remaining > parents. If you flip the order of parents of M when you merge A and > A' in your original history, and with your patch, what would you > see when you blame c? Wouldn't it notice that M:c is identical to c > in its first parent (now A') and pass the whole blame to A' anyway > with or without your change? When giving git-blame the new option introduced with my patch, only the order of parents determines which commit is blamed. Without the option (i.e. the currently only possible behaviour) which commit is blamed depends what else touches other parts of the file. If both branches make modifications to the file (or if there is any merge conflict resolution in the merge) then the bahaviour with or without the option are the same. But in the example with one commit B touching also b and one commit C touching also c, there is (without the new option) always one part of the cherry-picked commit is blamed on the original and one on the cherry-picked, no matter how you order the parents. (While by having your mainline always the most leftward parent, with the the new option you always get those commit blamed that is the "first one this was introduced to mainline".) Bernhard R. Link -- F8AC 04D5 0B9B 064B 3383 C3DA AFFC 96D1 151D FFDC -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html