{"thread":{"id":"1060","subject":"how about this as a basis for git-annotate?","startedAt":"2005-06-30T13:55:32Z","lastAt":"2005-06-30T20:20:05Z","messageCount":2,"participants":["lode leroy","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"5451","messageId":"BAY22-F40C3079B41F242AEB407E1FFE30@phx.gbl","threadId":"1060","inReplyTo":null,"subject":"how about this as a basis for git-annotate?","fromName":"lode leroy","fromEmail":"lode_leroy@hotmail.com","sentAt":"2005-06-30T13:55:32Z","receivedAt":"2005-06-30T13:55:32Z","isPatch":false,"sender":{"key":"lode_leroy@hotmail.com","avatar":null},"body":"#!/bin/bash\n\nfile=\"$1\"\nanno=\"$file.anno\"\nprev=\"\"\nexport GIT_DIFF_OPTS=-u0\n\nrm $anno\ntouch $anno\n\nrevs=`git-rev-list HEAD | tac`\n\nfor rev in $revs; do\n\tif [ ! -z \"$prev\" ]; then\n\t\tgit-diff-tree -p $prev $rev $file \\\n\t\t| sed \t-e \"/^--- /p\" \\\n\t\t\t-e \"/^+++ /p\" \\\n\t\t\t-e \"/^--- /d\" \\\n\t\t\t-e \"/^+++ /d\" \\\n\t\t\t-e \"s/^-/-$prev /g\" \\\n\t\t\t-e \"s/^+/+$rev /g\" | patch $anno\n\tfi\n\tprev=$rev\ndone\n\n\n\n* gives a warning when the diff is empty\n* has a problem with \"\\ No newline at end of file\"\n\nWhat I tried to do is to reconstruct the file from the diffs,\nand prefixing each line with the sha1 of the revision.\n\nAfter further testing, I see that the implementation I provided does not \nwork,\nbecause the context is not necessarily from the previous version, but from \n/a/ previous version.\nStill the idea should work.\nSo patch needs to ignore the sha1 of the revision.\nMaybe git-apply can be modified to do this...?\n"},{"id":"5481","messageId":"7vd5q338cq.fsf@assigned-by-dhcp.cox.net","threadId":"1060","inReplyTo":"BAY22-F40C3079B41F242AEB407E1FFE30@phx.gbl","subject":"Re: how about this as a basis for git-annotate?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-06-30T20:20:05Z","receivedAt":"2005-06-30T20:20:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"ll\" == lode leroy <lode_leroy@hotmail.com> writes:\n\nll> Still the idea should work.\n\nMultiple parents?  Renames?  Total rewrites?\n\nTo save some time for you to think, here is an excerpt from my\nsloooooow one describing how it works.  The final line-by-line\nblame assignment is done exactly the same way as what you did in\nyour outline, reading from \"diff -u0\"; but there are other\nthings you need to worry about.\n\nYou will find at http://members.cox.net/junkio/blame.perl the\nfull implementation.  This is what I have been using to generate\nthe http://members.cox.net/junkio/Summary.txt file.\n\nI do not need \"how about this as a basis\" at this point.  Basis\nis already there and I have verified that it produces correct\nresults.  What I would like to see is for somebody to come up\nwith an implementation that produces the identical results in\n1/20th of the time ;-).  That solution might probably involve\nnot calling diff-tree but instead doing things inside diff-tree.\nI donno.\n\n------------\nHow does this work, and what do we do about merges?\n\nThe algorithm considers that the first parent is our main line of\ndevelopment and treats it somewhat special than other parents.  So we\npass on the blame to the first parent if a line has not changed from\nit.  For lines that have changed from the first parent, we must have\neither inherited that change from some other parent, or it could have\nbeen merge conflict resolution edit we did on our own.\n\nThe following picture illustrates how we pass on and assign blames.\n\nIn the sample, the original O was forked into A and B and then merged\ninto M.  Line 1, 2, and 4 did not change.  Line 3 and 5 are changed in\nA, and Line 5 and 6 are changed in B.  M made its own decision to\nresolve merge conflicts at Line 5 to something different from A and B:\n\n                A: 1 2 T 4 T 6\n               /               \\ \nO: 1 2 3 4 5 6                  M: 1 2 T 4 M S\n               \\               / \n                B: 1 2 3 4 S S\n\nIn the following picture, each line is annotated with a blame letter.\nA lowercase blame (e.g. \"a\" for \"1\") means that commit or its ancestor\nis the guilty party but we do not know which particular ancestor is\nresponsible for the change yet.  An uppercase blame means that we know\nthat commit is the guilty party.\n\nFirst we look at M (the HEAD) and initialize Git::Blame->{LINE} like\nthis:\n\n             M: 1 2 T 4 M S\n                m m m m m m\n\nThat is, we know all lines are results of modification made by some\nancestor of M, so we assign lowercase 'm' to all of them.\n\nThen we examine our first parent A.  Throughout the algorithm, we are\nalways only interested in the lines we are the suspect, but this being\nthe initial round, we are the suspect for all of them.  We notice that\n1 2 T 4 are the same as the parent A, so we pass the blame for these\nfour lines to A.  M and S are different from A, so we leave them as\nthey are (note that we do not immediately take the blame for them):\n\n             M: 1 2 T 4 M S\n                a a a a m m\n\nNext we go on to examine parent B.  Again, we are only interested in\nthe lines we are still the suspect (i.e. M and S).  We notice S is\nsomething we inherited from B, so we pass the blame on to it, like\nthis:\n\n             M: 1 2 T 4 M S\n                a a a a m b\n\nOnce we exhausted the parents, we look at the results and take\nresponsibility for the remaining ones that we are still the suspect:\n\n             M: 1 2 T 4 M S\n                a a a a M b\n\nWe are done with M.  And we know commits A and B need to be examined\nfurther, so we do them recursively.  When we look at A, we again only\nlook at the lines that A is the suspect:\n\n             A: 1 2 T 4 T 6\n                a a a a M b\n\nAmong 1 2 T 4, comparing against its parent O, we notice 1 2 4 are\nthe same so pass the blame for those lines to O:\n\n             A: 1 2 T 4 T 6\n                o o a o M b\n\nA is a non-merge commit; we have already exhausted the parents and\ntake responsibility for the remaining ones that A is the suspect:\n\n             A: 1 2 T 4 T 6\n                o o A o M b\n\nWe go on like this and the final result would become:\n\n             O: 1 2 3 4 5 6\n                O O A O M B\n"}]}