Felipe Contreras <felipe.contreras@xxxxxxxxx> writes: >> If the change in HEAD^ in the above example were to copy the whole A >> and C from a different file, then your !found_guilty logic would >> kick in and say all lines of A where copied from elsewhere in HEAD^, >> but again we would not learn the same information for C. > > We would, when it's the turn for C, which is not guilty at this point. In _this_ round of the while(1) loop, pass_blame_to_parent() gets the scoreboard and two origins (HEAD^ that we are looking at and HEAD^^ that is its parent); it does not even know what blame entry this request came from. It runs a single diff using diff_hunks(), and asks blame_chunk() to split all the blame entries in the scoreboard that suspect it is looking at may be guilty for. Blame entry for A and C are both processed exactly the same way when HEAD^ is given to pass_blame() for the first time, which is when assign_blame() decided to call it with HEAD^ because it happened to have seen A before seeing C. At that point, both A and C are processed, and the post-processing loop "Take responsibility for the remaining" will clean up remnants from both A and C. After this round ends, the suspect for A and C are both set to HEAD^^. In the next round of the while(1) loop, C already forgot that its line movement happened in HEAD^. Its suspect is now HEAD^^. When "it's the turn for C" [*1*], you can say "These lines originate in that different path in HEAD^^", but it is too late to say "But the first time they appeared in the original file was HEAD^" (which is when they were moved from the different path in HEAD^^), isn't it? [Footnote] *1* It does not make much sense to say "turn for C", by the way. pass_blame() work per suspect (not per blame entry), so what you are talking about really is "when it is turn for HEAD^^", at which point we will discover that these lines in C originate in that different path in the commit. And in the scenario we are discussing, we will decide to check HEAD^^ because the blame ent for A is also the same origin as C's suspect in HEAD^^, so technically it is still "turn for A" ;-). The sample would be like (cat A; cat C) >file0; git commit file0 ; HEAD^^ (cat A; cat C) >file1; git commit file1 ; HEAD^ (cat A; cat B; cat C) >file1; git commit file1 ; HEAD git blame -C -C -C file1 HEAD -- 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