{"thread":{"id":"2167","subject":"git-filehistory (first cut at detecting renames)","startedAt":"2005-10-20T19:51:58Z","lastAt":"2005-10-20T20:19:15Z","messageCount":2,"participants":["David Ho"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"10367","messageId":"4dd15d180510201251p57bea756s18b2e77d4be4ec35@mail.gmail.com","threadId":"2167","inReplyTo":null,"subject":"git-filehistory (first cut at detecting renames)","fromName":"David Ho","fromEmail":"davidkwho@gmail.com","sentAt":"2005-10-20T19:51:58Z","receivedAt":"2005-10-20T19:51:58Z","isPatch":false,"sender":{"key":"davidkwho@gmail.com","avatar":"https://gravatar.com/avatar/1596ca9708bdd00a5c237f15af1011d65b6ef49a3bd9e9152e0bf09e7577fb5a?d=mp&s=160"},"body":"Hi all,\n\nThis is my stupid perl script to detect renames all the way to it's\norigin.  This is my first attempt at writing a perl script so it looks\na bit awful.  It's not perfect, if a file is renamed, the entire\ncommit is dumped out.  Maybe if git-diff-tree -M <pathname> does post\nprocessing to output changes relevant to <pathname> then it will work\nquite well.\n\nDavid\n\n[davidho@penguin git-tutorial]$ cat git-filehistory.perl\n#!/usr/bin/perl\n\nuse warnings;\nuse strict;\n\nsub usage($);\n\n# Sanity checks:\nmy $GIT_DIR = $ENV{'GIT_DIR'} || \".git\";\n\nunless ( -d $GIT_DIR && -d $GIT_DIR . \"/objects\" &&\n        -d $GIT_DIR . \"/objects/\" && -d $GIT_DIR . \"/refs\") {\n        usage(\"Git repository not found.\");\n}\n\nusage(\"\") if scalar @ARGV != 1;\n\nmy ($file) = @ARGV;\n\nunless (-f $file) {\n        usage(\"git filehistory: '$file' does not exist\");\n}\n\nopen(F,\"-|\",\"git-rev-parse\",,\"--default\",\"HEAD\",\"--revs-only\",$file);\nmy $git_rev_args = <F>;\nchomp ($git_rev_args);\nclose (F);\n\nopen(F,\"-|\",\"git-rev-list\", $git_rev_args);\nmy @commits = <F>;\nclose (F);\n\nmy $nextname = $file;\nfor (my $i=0; $i < scalar @commits; $i++)\n{\n        my $commit = $commits[$i];\n        chomp ($commit);\n\n        open(F,\"-|\",\"git-diff-tree\",\"-r\",\"-M\", $commit)\n                or die \"Failed to open pipe from git-diff-tree: \" . $!;\n        my @lines = grep /R\\d{3}.+$nextname/, <F>;\n        close(F);\n        if (scalar @lines >=1) {\n                #The file is renamed!\n                my $rc = system\n(\"git-diff-tree\",\"-r\",\"-M\",\"-p\",\"--pretty=medium\",$commit);\n                die \"git-diff-tree failed\" if $rc;\n                print \"\\n\";\n                if ($lines[0] =~ /R\\d{3}\\t(.+)\\t(.+)/) {\n                        $nextname = $1;\n                }\n        }\n        else {\n                #Not renamed\n                my $rc = system\n(\"git-diff-tree\",\"-r\",\"-m\",\"-p\",\"--pretty=medium\",$commit, $nextname);\n                die \"git-diff-tree failed\" if $rc;\n                print \"\\n\";\n        }\n}\n\nsub usage($) {\n        my $s = shift;\n        print $s, \"\\n\" if (length $s != 0);\n        print <<EOT;\n$0 <file>\nThis script traces renames to find the origin of the file\nEOT\n        exit(1);\n}\n"},{"id":"10369","messageId":"4dd15d180510201319k6beeb1f3j89eae34322d12c90@mail.gmail.com","threadId":"2167","inReplyTo":"4dd15d180510201251p57bea756s18b2e77d4be4ec35@mail.gmail.com","subject":"Re: git-filehistory (first cut at detecting renames)","fromName":"David Ho","fromEmail":"davidkwho@gmail.com","sentAt":"2005-10-20T20:19:15Z","receivedAt":"2005-10-20T20:19:15Z","isPatch":false,"sender":{"key":"davidkwho@gmail.com","avatar":"https://gravatar.com/avatar/1596ca9708bdd00a5c237f15af1011d65b6ef49a3bd9e9152e0bf09e7577fb5a?d=mp&s=160"},"body":"Actually, just tried it on the git repository.  It is very slow. \nMaybe because I'm doing a complete diff-tree on each commit.  Mmm...\nmaybe there is a better way to detect renames  when walking up the\nfile history.\n\nDavid\n\nOn 10/20/05, David Ho <davidkwho@gmail.com> wrote:\n> Hi all,\n>\n> This is my stupid perl script to detect renames all the way to it's\n> origin.  This is my first attempt at writing a perl script so it looks\n> a bit awful.  It's not perfect, if a file is renamed, the entire\n> commit is dumped out.  Maybe if git-diff-tree -M <pathname> does post\n> processing to output changes relevant to <pathname> then it will work\n> quite well.\n>\n> David\n>\n> [davidho@penguin git-tutorial]$ cat git-filehistory.perl\n> #!/usr/bin/perl\n>\n> use warnings;\n> use strict;\n>\n> sub usage($);\n>\n> # Sanity checks:\n> my $GIT_DIR = $ENV{'GIT_DIR'} || \".git\";\n>\n> unless ( -d $GIT_DIR && -d $GIT_DIR . \"/objects\" &&\n>         -d $GIT_DIR . \"/objects/\" && -d $GIT_DIR . \"/refs\") {\n>         usage(\"Git repository not found.\");\n> }\n>\n> usage(\"\") if scalar @ARGV != 1;\n>\n> my ($file) = @ARGV;\n>\n> unless (-f $file) {\n>         usage(\"git filehistory: '$file' does not exist\");\n> }\n>\n> open(F,\"-|\",\"git-rev-parse\",,\"--default\",\"HEAD\",\"--revs-only\",$file);\n> my $git_rev_args = <F>;\n> chomp ($git_rev_args);\n> close (F);\n>\n> open(F,\"-|\",\"git-rev-list\", $git_rev_args);\n> my @commits = <F>;\n> close (F);\n>\n> my $nextname = $file;\n> for (my $i=0; $i < scalar @commits; $i++)\n> {\n>         my $commit = $commits[$i];\n>         chomp ($commit);\n>\n>         open(F,\"-|\",\"git-diff-tree\",\"-r\",\"-M\", $commit)\n>                 or die \"Failed to open pipe from git-diff-tree: \" . $!;\n>         my @lines = grep /R\\d{3}.+$nextname/, <F>;\n>         close(F);\n>         if (scalar @lines >=1) {\n>                 #The file is renamed!\n>                 my $rc = system\n> (\"git-diff-tree\",\"-r\",\"-M\",\"-p\",\"--pretty=medium\",$commit);\n>                 die \"git-diff-tree failed\" if $rc;\n>                 print \"\\n\";\n>                 if ($lines[0] =~ /R\\d{3}\\t(.+)\\t(.+)/) {\n>                         $nextname = $1;\n>                 }\n>         }\n>         else {\n>                 #Not renamed\n>                 my $rc = system\n> (\"git-diff-tree\",\"-r\",\"-m\",\"-p\",\"--pretty=medium\",$commit, $nextname);\n>                 die \"git-diff-tree failed\" if $rc;\n>                 print \"\\n\";\n>         }\n> }\n>\n> sub usage($) {\n>         my $s = shift;\n>         print $s, \"\\n\" if (length $s != 0);\n>         print <<EOT;\n> $0 <file>\n> This script traces renames to find the origin of the file\n> EOT\n>         exit(1);\n> }\n>\n"}]}