{"thread":{"id":"26741","subject":"git blame --follow","startedAt":"2011-03-15T15:44:44Z","lastAt":"2011-03-17T16:47:31Z","messageCount":6,"participants":["Wolfgang Rohdewald","Junio C Hamano","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"163394","messageId":"201103151644.44360.wolfgang@rohdewald.de","threadId":"26741","inReplyTo":null,"subject":"git blame --follow","fromName":"Wolfgang Rohdewald","fromEmail":"wolfgang@rohdewald.de","sentAt":"2011-03-15T15:44:44Z","receivedAt":"2011-03-15T15:44:44Z","isPatch":false,"sender":{"key":"wolfgang@rohdewald.de","avatar":null},"body":"git log --follow filename\n\nshows the full history, while\n\ngit blame --follow filename\n\nblames everything to the latest commit (which was\na file rename)\n\nit would be nice if --follow were also supported by\ngit blame. Actually git blame accepts --follow without\nan error message, it just ignores it. git help blame\ndoes not mention --follow\n\nusing latest git from master\ngit version 1.7.4.1.234.ga3513\n\n-- \nWolfgang\n"},{"id":"163400","messageId":"7vy64g9tqs.fsf@alter.siamese.dyndns.org","threadId":"26741","inReplyTo":"201103151644.44360.wolfgang@rohdewald.de","subject":"Re: git blame --follow","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-03-15T17:30:19Z","receivedAt":"2011-03-15T17:30:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Wolfgang Rohdewald <wolfgang@rohdewald.de> writes:\n\n> git log --follow filename\n>\n> shows the full history, while\n>\n> git blame --follow filename\n>\n> blames everything to the latest commit (which was\n> a file rename)\n\nHuh?\n\n    $ git checkout master^0\n    $ git mv COPYING RENAMING\n    $ git commit -m renamed\n    $ git blame --follow RENAMING\n\ngives everything blamed to 075b845a COPYING (but that is probably by\naccident, see below).  FYI,\n\n    $ git blame RENAMING\n\nshould also blame everything to the same commit and the same COPYING\nfile. If you get a different behaviour out of the above command sequence,\nthere is something else going on.\n\nI didn't know \"blame\" even accepted \"--follow\".  It is entirely out of the\nscope of its design to take \"--follow\" option, as the \"blame\" command\nitself has its own and real \"follow\" logic that is enabled by default\n(i.e. it follows a whole file rename without any option), instead of the\ncheckbox \"--follow\" hack that is in \"git log\" family of commands.  You\ncannot even turn it off.\n\nPerhaps the behaviour you saw comes from the internal revision traversal\nmachinery blame uses getting confused by the use of --follow, but I am too\nlazy to check (and I don't think it is worth to check, as the command\nshould follow by default).\n\nWe should just teach \"blame\" to ignore --follow option from the command\nline, without even complaining.\n"},{"id":"163403","messageId":"201103151926.58449.wolfgang@rohdewald.de","threadId":"26741","inReplyTo":"7vy64g9tqs.fsf@alter.siamese.dyndns.org","subject":"Re: git blame --follow","fromName":"Wolfgang Rohdewald","fromEmail":"wolfgang@rohdewald.de","sentAt":"2011-03-15T18:26:58Z","receivedAt":"2011-03-15T18:26:58Z","isPatch":false,"sender":{"key":"wolfgang@rohdewald.de","avatar":null},"body":"On Dienstag 15 März 2011, Junio C Hamano wrote:\n> Wolfgang Rohdewald <wolfgang@rohdewald.de> writes:\n> > git log --follow filename\n> > \n> > shows the full history, while\n> > \n> > git blame --follow filename\n> > \n> > blames everything to the latest commit (which was\n> > a file rename)\n> \n> Huh?\n> \n>     $ git checkout master^0\n>     $ git mv COPYING RENAMING\n>     $ git commit -m renamed\n>     $ git blame --follow RENAMING\n> \n> gives everything blamed to 075b845a COPYING (but that is\n> probably by accident, see below).  FYI,\n> \n>     $ git blame RENAMING\n> \n> should also blame everything to the same commit and the same\n> COPYING file. If you get a different behaviour out of the\n> above command sequence, there is something else going on.\n\nI get the same - except that only most is attributed to 075b845a,\nsome is attributed to 703601d6. But git blame and git\nblame --follow return the same output with your example\n\n> I didn't know \"blame\" even accepted \"--follow\".  It is\n> entirely out of the scope of its design to take \"--follow\"\n> option, as the \"blame\" command itself has its own and real\n> \"follow\" logic that is enabled by default (i.e. it follows a\n> whole file rename without any option)\n\nso if I rename a parent directory of myfile and do git blame \nmyfile, blaming should ignore the renaming. This works\nwith the git repo\n\ngit mv xdiff xxx\ngit ci -m'mv xdiff xxx'\ncd xxx\ngit blame xemit.c\n\nBut with my repository (which I cannot share),\nthis does not happen. git blame attributes everything to \nthe renaming commit. If I checkout the commit before, git\nblame shows everything correctly.\n\nSo there must be something special with my repo. How could\nI debug that? BTW the renaming happened in svn, it is the\nlast svn commit for this file before I imported this svn\nrepo into git (like described in the Pro Git book)\n\nAnd - for directories below the renamed one git log --follow \ncannot cross this barrier either but if the \"follow\" logic\nis different I suppose this is not related\n\n-- \nWolfgang\n"},{"id":"163545","messageId":"m3tyf25arl.fsf@localhost.localdomain","threadId":"26741","inReplyTo":"201103151926.58449.wolfgang@rohdewald.de","subject":"Re: git blame --follow","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-17T09:59:22Z","receivedAt":"2011-03-17T09:59:22Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Wolfgang Rohdewald <wolfgang@rohdewald.de> writes:\n\n> But with my repository (which I cannot share),\n> this does not happen. git blame attributes everything to \n> the renaming commit. If I checkout the commit before, git\n> blame shows everything correctly.\n\n\"git blame\" manpage says:\n\n       -M|<num>|\n              Detect  moved  or copied lines within a file. [...]\n              [...]\n              <num> is optional [...]\n\n       -C|<num>|\n              In  addition  to  -M,  detect lines moved or copied from other files\n              that were modified in the same commit.\n\nSidenote: I wonder why we use '-M|<num>|' and not '-M[<num>]' here.\n\nSo you probably want to run \"git blame -C -C <file>\", not \"git blame <file>\".\nNote that it is the same option name to turn on rename detection as is\nused for for \"git diff\".\n\nNote that \"git gui blame\" shows _two_ commits for each line: one is\nresult of \"git blame\" (and it would show commit that did code\nmovement, or renamed file), the other is result of \"git blame -C -C -w\",\nwhich would show commit that changed line, disregarding whitespace-only\nchange (like e.g. reindent caused by extracting code into separate\nfunction).\n\nI wonder if it would be possible to generate result of \"git blame\"\nand of \"git blame -C -C -w\" in a single run (with --porcelain or\n--incremental)...\n\n[...]\n> And - for directories below the renamed one git log --follow \n> cannot cross this barrier either but if the \"follow\" logic\n> is different I suppose this is not related\n\nThe implementation of \"git log --follow <file>\" is a bolted-on hack,\nand it doesn't work in all cases; for example it doesn't cross\nboundaries of subtree merge, IIRC.  Try \"git log --follow gitweb/gitweb.perl\"\nin git repository itself...\n\nHTH\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"163547","messageId":"201103171116.39411.wolfgang@rohdewald.de","threadId":"26741","inReplyTo":"m3tyf25arl.fsf@localhost.localdomain","subject":"Re: git blame --follow","fromName":"Wolfgang Rohdewald","fromEmail":"wolfgang@rohdewald.de","sentAt":"2011-03-17T10:16:39Z","receivedAt":"2011-03-17T10:16:39Z","isPatch":false,"sender":{"key":"wolfgang@rohdewald.de","avatar":null},"body":"On Donnerstag 17 März 2011, Jakub Narebski wrote:\n> So you probably want to run \"git blame -C -C <file>\", not \"git\n> blame <file>\".\n\nthat does the trick - I only tried \"git blame -C\"\n\n-- \nWolfgang\n"},{"id":"163566","messageId":"201103171747.34452.jnareb@gmail.com","threadId":"26741","inReplyTo":"201103171116.39411.wolfgang@rohdewald.de","subject":"Re: git blame --follow","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2011-03-17T16:47:31Z","receivedAt":"2011-03-17T16:47:31Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Dnia czwartek 17. marca 2011 11:16, Wolfgang Rohdewald napisał:\n> On Donnerstag 17 März 2011, Jakub Narebski wrote:\n\n> > So you probably want to run \"git blame -C -C <file>\", not \"git\n> > blame <file>\".\n> \n> that does the trick - I only tried \"git blame -C\"\n\nHmmm... it is described in git-blame(1) manpage, but you have to read\nit carefully.\n\n\n\"git blame\" synopsis states:\n\n 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L n,m]\n             [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]\n             [<rev> | --contents <file> | --reverse <rev>] [--] <file>\n\nThe important thing is to notice '[-C] [-C] [-C]' here.\n\n\nIn the description of '-C' option we have:\n\n  -C|<num>|::\n        In addition to `-M`, detect lines moved or copied from other\n        files that were modified in the same commit.  This is\n        useful when you reorganize your program and move code\n        around across files.  When this option is given twice,\n                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        the command additionally looks for copies from other\n        files in the commit that creates the file. When this\n        option is given three times, the command additionally\n        looks for copies from other files in any commit.\n\nI have underlined important part.\n-- \nJakub Narebski\nPoland\n"}]}