* [PATCH 1/2] gitweb: blame: Print just a single new line char per table row @ 2006-10-05 0:59 Luben Tuikov 2006-10-05 2:35 ` Junio C Hamano 0 siblings, 1 reply; 14+ messages in thread From: Luben Tuikov @ 2006-10-05 0:59 UTC (permalink / raw) To: git [-- Attachment #1: Type: text/plain, Size: 237 bytes --] This makes cut-and-paste from blame legible, else after pasting it is broken into too many lines. Signed-off-by: Luben Tuikov <ltuikov@yahoo.com> --- gitweb/gitweb.perl | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) [-- Attachment #2: 1207600725-p1.txt --] [-- Type: text/plain, Size: 996 bytes --] diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index cba0840..451bf5d 100644 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2509,7 +2509,7 @@ HTML $current_color = ++$current_color % $num_colors; $print_c8 = 1; } - print "<tr class=\"$rev_color[$current_color]\">\n"; + print "<tr class=\"$rev_color[$current_color]\">"; print "<td class=\"sha1\""; if ($print_c8 == 1) { print " title=\"$author, $date\""; @@ -2519,10 +2519,10 @@ HTML print $cgi->a({-href => href(action=>"commit", hash=>$full_rev, file_name=>$file_name)}, esc_html($rev)); } - print "</td>\n"; + print "</td>"; print "<td class=\"linenr\"><a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" . - esc_html($lineno) . "</a></td>\n"; - print "<td class=\"pre\">" . esc_html($data) . "</td>\n"; + esc_html($lineno) . "</a></td>"; + print "<td class=\"pre\">" . esc_html($data) . "</td>"; print "</tr>\n"; } print "</table>\n"; -- 1.4.2.3.g7d77 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] gitweb: blame: Print just a single new line char per table row 2006-10-05 0:59 [PATCH 1/2] gitweb: blame: Print just a single new line char per table row Luben Tuikov @ 2006-10-05 2:35 ` Junio C Hamano 2006-10-05 6:48 ` Luben Tuikov 0 siblings, 1 reply; 14+ messages in thread From: Junio C Hamano @ 2006-10-05 2:35 UTC (permalink / raw) To: Luben Tuikov; +Cc: git Luben Tuikov <ltuikov@yahoo.com> writes: > This makes cut-and-paste from blame legible, else after > pasting it is broken into too many lines. > > Signed-off-by: Luben Tuikov <ltuikov@yahoo.com> I have to say the browser is seriously broken if whitespaces between <tr> and <td>, </td> and next <td>, </td> and </tr> makes a difference to its behaviour. Aren't there a way to tell the browser to cut "visually"? E.g. "The area I want to cut is from this data column, and lines from here to there. I do not want the leftmost two columns (commit-8 and lineno)". I do not mind applying this, but that is only because it does not make its source any less readable. It does make things harder to debug if somebody is debugging its output by reading the generated raw HTML, so it is not like there is no downside. You might want to run links (or lynx) in screen ;-). Screen supports left- (or right-, or both-sides) bounded cut which I find extremely useful. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] gitweb: blame: Print just a single new line char per table row 2006-10-05 2:35 ` Junio C Hamano @ 2006-10-05 6:48 ` Luben Tuikov 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano 0 siblings, 1 reply; 14+ messages in thread From: Luben Tuikov @ 2006-10-05 6:48 UTC (permalink / raw) To: Junio C Hamano; +Cc: git --- Junio C Hamano <junkio@cox.net> wrote: > I have to say the browser is seriously broken if whitespaces > between <tr> and <td>, </td> and next <td>, </td> and </tr> > makes a difference to its behaviour. Aren't there a way to tell > the browser to cut "visually"? E.g. "The area I want to cut is I'm not sure, I'm using latest Firefox. > from this data column, and lines from here to there. I do not > want the leftmost two columns (commit-8 and lineno)". > > I do not mind applying this, but that is only because it does > not make its source any less readable. It does make things > harder to debug if somebody is debugging its output by reading > the generated raw HTML, so it is not like there is no downside. If you think that this could be a problem or affects negatively, please don't apply. cut-paste-edit is a small price to pay as opposed to messing up the code and output. > You might want to run links (or lynx) in screen ;-). Screen > supports left- (or right-, or both-sides) bounded cut which I > find extremely useful. Ok, I'll try that. Luben ^ permalink raw reply [flat|nested] 14+ messages in thread
* perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-05 6:48 ` Luben Tuikov @ 2006-10-05 8:13 ` Junio C Hamano 2006-10-06 13:07 ` Johannes Schindelin ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: Junio C Hamano @ 2006-10-05 8:13 UTC (permalink / raw) To: git Cc: Luben Tuikov, Petr Baudis, Jakub Narebski, Ryan Anderson, Johannes Schindelin, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds It's been a while since we lost git_blame from %actions list. I am wondering maybe it's time to remove it, after 1.4.3 happens. While I was looking at it, I noticed that it would make git-cvsserver the last in-tree user of git-annotate. As I understand it, "git-blame -c" should produce compatible output to the command, so it might also be a good time to consider removal of git-annotate as well while updating git-cvsserver to use git-blame instead of it. Do people have reason to favor annotate over blame? To keep existing people's scripts working I think we should add a small amount of code to blame.c to default to compatibility mode when the command is called as git-annotate at least for a while, but other than that I do not see much issue against scheduling for annotate's removal. I am not going to do anything about this right now (the "master" branch is in freeze-and-stabilize phase), but if people have issues I overlooked, raise hands now please? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano @ 2006-10-06 13:07 ` Johannes Schindelin 2006-10-06 17:52 ` Luben Tuikov 2006-10-06 16:16 ` Petr Baudis ` (2 subsequent siblings) 3 siblings, 1 reply; 14+ messages in thread From: Johannes Schindelin @ 2006-10-06 13:07 UTC (permalink / raw) To: Junio C Hamano Cc: git, Luben Tuikov, Petr Baudis, Jakub Narebski, Ryan Anderson, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds Hi, On Thu, 5 Oct 2006, Junio C Hamano wrote: > Do people have reason to favor annotate over blame? To keep > existing people's scripts working I think we should add a small > amount of code to blame.c to default to compatibility mode when > the command is called as git-annotate at least for a while, but > other than that I do not see much issue against scheduling for > annotate's removal. +1. Although I would leave git-annotate in git, if only to meet expectations of new git users. Ciao, Dscho ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-06 13:07 ` Johannes Schindelin @ 2006-10-06 17:52 ` Luben Tuikov 2006-10-07 5:37 ` Martin Langhoff (CatalystIT) 0 siblings, 1 reply; 14+ messages in thread From: Luben Tuikov @ 2006-10-06 17:52 UTC (permalink / raw) To: Johannes Schindelin, Junio C Hamano Cc: git, Luben Tuikov, Petr Baudis, Jakub Narebski, Ryan Anderson, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds --- Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > Hi, > > On Thu, 5 Oct 2006, Junio C Hamano wrote: > > > Do people have reason to favor annotate over blame? To keep > > existing people's scripts working I think we should add a small > > amount of code to blame.c to default to compatibility mode when > > the command is called as git-annotate at least for a while, but > > other than that I do not see much issue against scheduling for > > annotate's removal. > > +1. Although I would leave git-annotate in git, if only to meet > expectations of new git users. I agree with Junio's assessment of the situation. Luben ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-06 17:52 ` Luben Tuikov @ 2006-10-07 5:37 ` Martin Langhoff (CatalystIT) 0 siblings, 0 replies; 14+ messages in thread From: Martin Langhoff (CatalystIT) @ 2006-10-07 5:37 UTC (permalink / raw) To: ltuikov Cc: Johannes Schindelin, Junio C Hamano, git, Petr Baudis, Jakub Narebski, Ryan Anderson, Martyn Smith, Fredrik Kuivinen, Linus Torvalds Luben Tuikov wrote: >>>Do people have reason to favor annotate over blame? To keep >>>existing people's scripts working I think we should add a small >>>amount of code to blame.c to default to compatibility mode when >>>the command is called as git-annotate at least for a while, but >>>other than that I do not see much issue against scheduling for >>>annotate's removal. >> >>+1. Although I would leave git-annotate in git, if only to meet >>expectations of new git users. > > > I agree with Junio's assessment of the situation. +1 -- I need to test that the switch to git-blame for git-cvsserver works well for Eclipse end users. Will try and fit that next week somehow ;-) martin -- ----------------------------------------------------------------------- Martin @ Catalyst .Net .NZ Ltd, PO Box 11-053, Manners St, Wellington WEB: http://catalyst.net.nz/ PHYS: Level 2, 150-154 Willis St OFFICE: +64(4)916-7224 MOB: +64(21)364-017 Make things as simple as possible, but no simpler - Einstein ----------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano 2006-10-06 13:07 ` Johannes Schindelin @ 2006-10-06 16:16 ` Petr Baudis 2006-10-06 18:55 ` Luben Tuikov 2006-10-09 10:32 ` [PATCH 1/1] Remove git-annotate.perl and create a builtin-alias for git-blame Ryan Anderson 2006-10-09 10:37 ` perhaps time to remove git_blame from gitweb, and git-annotate? Ryan Anderson 3 siblings, 1 reply; 14+ messages in thread From: Petr Baudis @ 2006-10-06 16:16 UTC (permalink / raw) To: Junio C Hamano Cc: git, Luben Tuikov, Jakub Narebski, Ryan Anderson, Johannes Schindelin, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds Dear diary, on Thu, Oct 05, 2006 at 10:13:15AM CEST, I got a letter where Junio C Hamano <junkio@cox.net> said that... > It's been a while since we lost git_blame from %actions list. I > am wondering maybe it's time to remove it, after 1.4.3 happens. I will not mourn git-annotate disappearance (perhaps it could stay an alias to git-blame -c; I don't like this UI-wise but we already do this kind of thing with git-log / git-whatchanged). I still like gitweb blame better than blame2 but I'll just patch blame to look like blame2 (or better) and be happy with that. -- Petr "Pasky" Baudis Stuff: http://pasky.or.cz/ #!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1 lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-06 16:16 ` Petr Baudis @ 2006-10-06 18:55 ` Luben Tuikov 2006-10-06 19:08 ` Petr Baudis 0 siblings, 1 reply; 14+ messages in thread From: Luben Tuikov @ 2006-10-06 18:55 UTC (permalink / raw) To: Petr Baudis, Junio C Hamano Cc: git, Luben Tuikov, Jakub Narebski, Ryan Anderson, Johannes Schindelin, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds --- Petr Baudis <pasky@suse.cz> wrote: > Dear diary, on Thu, Oct 05, 2006 at 10:13:15AM CEST, I got a letter > where Junio C Hamano <junkio@cox.net> said that... > > It's been a while since we lost git_blame from %actions list. I > > am wondering maybe it's time to remove it, after 1.4.3 happens. > > I will not mourn git-annotate disappearance (perhaps it could stay an > alias to git-blame -c; I don't like this UI-wise but we already do this > kind of thing with git-log / git-whatchanged). I still like gitweb blame > better than blame2 but I'll just patch blame to look like blame2 (or > better) and be happy with that. That's exactly what I don't want to happen. blame2 is much less bloated than blame both in code and in visual appearance and in using git. And this was the whole point: quick, short, fast and straight to the point. I'd like to keep the blame interface as simple as possible, more window estate given to the code lines, and as little as possible to the commit id: a clickable commit-8 and now we also have clickable line_no to show us the state of the file, is more than enough. So far, blame2 has been by far the better "annotate" (as it is called in the other SCMs) interface I've seen in four other SCMs (some proprietary). Let's keep it like this. When data-mining code, what I'm interested in is: where did this line of code come from (commit-8), is it a part of a larger chunk (zebra coloring) and how it relates to the surrounding code. Blame2 is more than efficient at this. Luben > > -- > Petr "Pasky" Baudis > Stuff: http://pasky.or.cz/ > #!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj > $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1 > lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/) > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-06 18:55 ` Luben Tuikov @ 2006-10-06 19:08 ` Petr Baudis 2006-10-06 20:21 ` Luben Tuikov 0 siblings, 1 reply; 14+ messages in thread From: Petr Baudis @ 2006-10-06 19:08 UTC (permalink / raw) To: Luben Tuikov; +Cc: Junio C Hamano, git, Jakub Narebski (Trimmed cc list to people caring about gitweb.) Dear diary, on Fri, Oct 06, 2006 at 08:55:29PM CEST, I got a letter where Luben Tuikov <ltuikov@yahoo.com> said that... > --- Petr Baudis <pasky@suse.cz> wrote: > > I will not mourn git-annotate disappearance (perhaps it could stay an > > alias to git-blame -c; I don't like this UI-wise but we already do this > > kind of thing with git-log / git-whatchanged). I still like gitweb blame > > better than blame2 but I'll just patch blame to look like blame2 (or > > better) and be happy with that. > > That's exactly what I don't want to happen. blame2 is much less > bloated than blame both in code and in visual appearance and in using > git. And this was the whole point: quick, short, fast and straight > to the point. > > I'd like to keep the blame interface as simple as possible, more > window estate given to the code lines, and as little as possible to > the commit id: a clickable commit-8 and now we also have clickable > line_no to show us the state of the file, is more than enough. > > So far, blame2 has been by far the better "annotate" (as it is called > in the other SCMs) interface I've seen in four other SCMs (some proprietary). > Let's keep it like this. > > When data-mining code, what I'm interested in is: where did this line > of code come from (commit-8), is it a part of a larger chunk (zebra > coloring) and how it relates to the surrounding code. Blame2 is more > than efficient at this. And _I_ like to have some general idea about who and when touched given line of code, without having to click on a bunch of commit ids or spend a minute hovering over them patiently. ;-) If you really feel strongly about it, we should be able to make the individual columns hideable at view time, e.g. by a tiny bit of javascript just changing the display CSS property, which would be really comfortable. My idea about the output would be cg-log -s format, which is still reasonably tense. OTOH, there's still some space to burn in the Line column. There should be no additional load caused by this since we already extract this information anyway - we show it as a tooltip. -- Petr "Pasky" Baudis Stuff: http://pasky.or.cz/ #!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1 lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-06 19:08 ` Petr Baudis @ 2006-10-06 20:21 ` Luben Tuikov 0 siblings, 0 replies; 14+ messages in thread From: Luben Tuikov @ 2006-10-06 20:21 UTC (permalink / raw) To: Petr Baudis; +Cc: Junio C Hamano, git, Jakub Narebski --- Petr Baudis <pasky@suse.cz> wrote: > (Trimmed cc list to people caring about gitweb.) > > Dear diary, on Fri, Oct 06, 2006 at 08:55:29PM CEST, I got a letter > where Luben Tuikov <ltuikov@yahoo.com> said that... > > --- Petr Baudis <pasky@suse.cz> wrote: > > > I will not mourn git-annotate disappearance (perhaps it could stay an > > > alias to git-blame -c; I don't like this UI-wise but we already do this > > > kind of thing with git-log / git-whatchanged). I still like gitweb blame > > > better than blame2 but I'll just patch blame to look like blame2 (or > > > better) and be happy with that. > > > > That's exactly what I don't want to happen. blame2 is much less > > bloated than blame both in code and in visual appearance and in using > > git. And this was the whole point: quick, short, fast and straight > > to the point. > > > > I'd like to keep the blame interface as simple as possible, more > > window estate given to the code lines, and as little as possible to > > the commit id: a clickable commit-8 and now we also have clickable > > line_no to show us the state of the file, is more than enough. > > > > So far, blame2 has been by far the better "annotate" (as it is called > > in the other SCMs) interface I've seen in four other SCMs (some proprietary). > > Let's keep it like this. > > > > When data-mining code, what I'm interested in is: where did this line > > of code come from (commit-8), is it a part of a larger chunk (zebra > > coloring) and how it relates to the surrounding code. Blame2 is more > > than efficient at this. > > And _I_ like to have some general idea about who and when touched given > line of code, without having to click on a bunch of commit ids or spend > a minute hovering over them patiently. ;-) Well understood. Although, when I'm chasing after a problem, I care much about tracing back through the commit history as opposed to who did what and when, not until I've nailed the regressive commit (is when I care who/what/when/how). > If you really feel strongly about it, we should be able to make the > individual columns hideable at view time, e.g. by a tiny bit of > javascript just changing the display CSS property, which would be really > comfortable. My idea about the output would be cg-log -s format, which > is still reasonably tense. OTOH, there's still some space to burn in the > Line column. Point taken. Now since I don't want to turn blame2 into a circus, and since the whole point of blame2 (over blame) was to stay away from it being a circus, and to be fast and to the point, can we just keep git_blame() around which gives you this extra information right in the main screen? Luben P.S. The alternative is to create a next git_blame{N+1}() each time git_blameN() becomes git_blame{N-1}(). ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/1] Remove git-annotate.perl and create a builtin-alias for git-blame 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano 2006-10-06 13:07 ` Johannes Schindelin 2006-10-06 16:16 ` Petr Baudis @ 2006-10-09 10:32 ` Ryan Anderson 2006-10-09 10:37 ` perhaps time to remove git_blame from gitweb, and git-annotate? Ryan Anderson 3 siblings, 0 replies; 14+ messages in thread From: Ryan Anderson @ 2006-10-09 10:32 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, Ryan Anderson Signed-off-by: Ryan Anderson <ryan@michonline.com> --- I've clearly been too busy to actually fix this, and blame works, so, let's create an internal alias and delete annotate. (The tests still pass, for whatever that's worth.) --- Makefile | 3 +- builtin-annotate.c | 25 ++ builtin.h | 1 + git-annotate.perl | 708 ---------------------------------------------------- git.c | 1 + 5 files changed, 29 insertions(+), 709 deletions(-) diff --git a/Makefile b/Makefile index 2c7c338..7e62e76 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,7 @@ SCRIPT_SH = \ SCRIPT_PERL = \ git-archimport.perl git-cvsimport.perl git-relink.perl \ git-shortlog.perl git-rerere.perl \ - git-annotate.perl git-cvsserver.perl \ + git-cvsserver.perl \ git-svnimport.perl git-cvsexportcommit.perl \ git-send-email.perl git-svn.perl @@ -265,6 +265,7 @@ LIB_OBJS = \ BUILTIN_OBJS = \ builtin-add.o \ + builtin-annotate.o \ builtin-apply.o \ builtin-archive.o \ builtin-cat-file.o \ diff --git a/builtin-annotate.c b/builtin-annotate.c new file mode 100644 index 0000000..2655e60 --- /dev/null +++ b/builtin-annotate.c @@ -0,0 +1,25 @@ +/* + * "git annotate" builtin alias + * + * Copyright (C) 2006 Ryan Anderson + */ +#include "git-compat-util.h" +#include "exec_cmd.h" + +int cmd_annotate(int argc, const char **argv, const char *prefix) +{ + const char **nargv; + int i; + nargv = xmalloc(sizeof(char *) * (argc + 2)); + + nargv[0] = "blame"; + nargv[1] = "-c"; + + for (i = 1; i < argc; i++) { + nargv[i+1] = argv[i]; + } + nargv[argc + 1] = NULL; + + return execv_git_cmd(nargv); +} + diff --git a/builtin.h b/builtin.h index f9fa9ff..2c5d900 100644 --- a/builtin.h +++ b/builtin.h @@ -13,6 +13,7 @@ extern void stripspace(FILE *in, FILE *o extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); extern int cmd_add(int argc, const char **argv, const char *prefix); +extern int cmd_annotate(int argc, const char **argv, const char *prefix); extern int cmd_apply(int argc, const char **argv, const char *prefix); extern int cmd_archive(int argc, const char **argv, const char *prefix); extern int cmd_cat_file(int argc, const char **argv, const char *prefix); diff --git a/git-annotate.perl b/git-annotate.perl deleted file mode 100755 index 215ed26..0000000 --- a/git-annotate.perl +++ /dev/null @@ -1,708 +0,0 @@ -#!/usr/bin/perl -# Copyright 2006, Ryan Anderson <ryan@michonline.com> -# -# GPL v2 (See COPYING) -# -# This file is licensed under the GPL v2, or a later version -# at the discretion of Linus Torvalds. - -use warnings; -use strict; -use Getopt::Long; -use POSIX qw(strftime gmtime); -use File::Basename qw(basename dirname); - -sub usage() { - print STDERR "Usage: ${\basename $0} [-s] [-S revs-file] file [ revision ] - -l, --long - Show long rev (Defaults off) - -t, --time - Show raw timestamp (Defaults off) - -r, --rename - Follow renames (Defaults on). - -S, --rev-file revs-file - Use revs from revs-file instead of calling git-rev-list - -h, --help - This message. -"; - - exit(1); -} - -our ($help, $longrev, $rename, $rawtime, $starting_rev, $rev_file) = (0, 0, 1); - -my $rc = GetOptions( "long|l" => \$longrev, - "time|t" => \$rawtime, - "help|h" => \$help, - "rename|r" => \$rename, - "rev-file|S=s" => \$rev_file); -if (!$rc or $help or !@ARGV) { - usage(); -} - -my $filename = shift @ARGV; -if (@ARGV) { - $starting_rev = shift @ARGV; -} - -my @stack = ( - { - 'rev' => defined $starting_rev ? $starting_rev : "HEAD", - 'filename' => $filename, - }, -); - -our @filelines = (); - -if (defined $starting_rev) { - @filelines = git_cat_file($starting_rev, $filename); -} else { - open(F,"<",$filename) - or die "Failed to open filename: $!"; - - while(<F>) { - chomp; - push @filelines, $_; - } - close(F); - -} - -our %revs; -our @revqueue; -our $head; - -my $revsprocessed = 0; -while (my $bound = pop @stack) { - my @revisions = git_rev_list($bound->{'rev'}, $bound->{'filename'}); - foreach my $revinst (@revisions) { - my ($rev, @parents) = @$revinst; - $head ||= $rev; - - if (!defined($rev)) { - $rev = ""; - } - $revs{$rev}{'filename'} = $bound->{'filename'}; - if (scalar @parents > 0) { - $revs{$rev}{'parents'} = \@parents; - next; - } - - if (!$rename) { - next; - } - - my $newbound = find_parent_renames($rev, $bound->{'filename'}); - if ( exists $newbound->{'filename'} && $newbound->{'filename'} ne $bound->{'filename'}) { - push @stack, $newbound; - $revs{$rev}{'parents'} = [$newbound->{'rev'}]; - } - } -} -push @revqueue, $head; -init_claim( defined $starting_rev ? $head : 'dirty'); -unless (defined $starting_rev) { - my $diff = open_pipe("git","diff","HEAD", "--",$filename) - or die "Failed to call git diff to check for dirty state: $!"; - - _git_diff_parse($diff, [$head], "dirty", ( - 'author' => gitvar_name("GIT_AUTHOR_IDENT"), - 'author_date' => sprintf("%s +0000",time()), - ) - ); - close($diff); -} -handle_rev(); - - -my $i = 0; -foreach my $l (@filelines) { - my ($output, $rev, $committer, $date); - if (ref $l eq 'ARRAY') { - ($output, $rev, $committer, $date) = @$l; - if (!$longrev && length($rev) > 8) { - $rev = substr($rev,0,8); - } - } else { - $output = $l; - ($rev, $committer, $date) = ('unknown', 'unknown', 'unknown'); - } - - printf("%s\t(%10s\t%10s\t%d)%s\n", $rev, $committer, - format_date($date), ++$i, $output); -} - -sub init_claim { - my ($rev) = @_; - for (my $i = 0; $i < @filelines; $i++) { - $filelines[$i] = [ $filelines[$i], '', '', '', 1]; - # line, - # rev, - # author, - # date, - # 1 <-- belongs to the original file. - } - $revs{$rev}{'lines'} = \@filelines; -} - - -sub handle_rev { - my $revseen = 0; - my %seen; - while (my $rev = shift @revqueue) { - next if $seen{$rev}++; - - my %revinfo = git_commit_info($rev); - - if (exists $revs{$rev}{parents} && - scalar @{$revs{$rev}{parents}} != 0) { - - git_diff_parse($revs{$rev}{'parents'}, $rev, %revinfo); - push @revqueue, @{$revs{$rev}{'parents'}}; - - } else { - # We must be at the initial rev here, so claim everything that is left. - for (my $i = 0; $i < @{$revs{$rev}{lines}}; $i++) { - if (ref ${$revs{$rev}{lines}}[$i] eq '' || ${$revs{$rev}{lines}}[$i][1] eq '') { - claim_line($i, $rev, $revs{$rev}{lines}, %revinfo); - } - } - } - } -} - - -sub git_rev_list { - my ($rev, $file) = @_; - - my $revlist; - if ($rev_file) { - open($revlist, '<' . $rev_file) - or die "Failed to open $rev_file : $!"; - } else { - $revlist = open_pipe("git-rev-list","--parents","--remove-empty",$rev,"--",$file) - or die "Failed to exec git-rev-list: $!"; - } - - my @revs; - while(my $line = <$revlist>) { - chomp $line; - my ($rev, @parents) = split /\s+/, $line; - push @revs, [ $rev, @parents ]; - } - close($revlist); - - printf("0 revs found for rev %s (%s)\n", $rev, $file) if (@revs == 0); - return @revs; -} - -sub find_parent_renames { - my ($rev, $file) = @_; - - my $patch = open_pipe("git-diff-tree", "-M50", "-r","--name-status", "-z","$rev") - or die "Failed to exec git-diff: $!"; - - local $/ = "\0"; - my %bound; - my $junk = <$patch>; - while (my $change = <$patch>) { - chomp $change; - my $filename = <$patch>; - if (!defined $filename) { - next; - } - chomp $filename; - - if ($change =~ m/^[AMD]$/ ) { - next; - } elsif ($change =~ m/^R/ ) { - my $oldfilename = $filename; - $filename = <$patch>; - chomp $filename; - if ( $file eq $filename ) { - my $parent = git_find_parent($rev, $oldfilename); - @bound{'rev','filename'} = ($parent, $oldfilename); - last; - } - } - } - close($patch); - - return \%bound; -} - - -sub git_find_parent { - my ($rev, $filename) = @_; - - my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev","--",$filename) - or die "Failed to open git-rev-list to find a single parent: $!"; - - my $parentline = <$revparent>; - chomp $parentline; - my ($revfound,$parent) = split m/\s+/, $parentline; - - close($revparent); - - return $parent; -} - -sub git_find_all_parents { - my ($rev) = @_; - - my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev") - or die "Failed to open git-rev-list to find a single parent: $!"; - - my $parentline = <$revparent>; - chomp $parentline; - my ($origrev, @parents) = split m/\s+/, $parentline; - - close($revparent); - - return @parents; -} - -sub git_merge_base { - my ($rev1, $rev2) = @_; - - my $mb = open_pipe("git-merge-base", $rev1, $rev2) - or die "Failed to open git-merge-base: $!"; - - my $base = <$mb>; - chomp $base; - - close($mb); - - return $base; -} - -# Construct a set of pseudo parents that are in the same order, -# and the same quantity as the real parents, -# but whose SHA1s are as similar to the logical parents -# as possible. -sub get_pseudo_parents { - my ($all, $fake) = @_; - - my @all = @$all; - my @fake = @$fake; - - my @pseudo; - - my %fake = map {$_ => 1} @fake; - my %seenfake; - - my $fakeidx = 0; - foreach my $p (@all) { - if (exists $fake{$p}) { - if ($fake[$fakeidx] ne $p) { - die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n", - $fake[$fakeidx], $p, - join(", ", @all), - join(", ", @fake), - ); - } - - push @pseudo, $p; - $fakeidx++; - $seenfake{$p}++; - - } else { - my $base = git_merge_base($fake[$fakeidx], $p); - if ($base ne $fake[$fakeidx]) { - die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n", - $fake[$fakeidx], $p, $base); - } - - # The details of how we parse the diffs - # mean that we cannot have a duplicate - # revision in the list, so if we've already - # seen the revision we would normally add, just use - # the actual revision. - if ($seenfake{$base}) { - push @pseudo, $p; - } else { - push @pseudo, $base; - $seenfake{$base}++; - } - } - } - - return @pseudo; -} - - -# Get a diff between the current revision and a parent. -# Record the commit information that results. -sub git_diff_parse { - my ($parents, $rev, %revinfo) = @_; - - my @pseudo_parents; - my @command = ("git-diff-tree"); - my $revision_spec; - - if (scalar @$parents == 1) { - - $revision_spec = join("..", $parents->[0], $rev); - @pseudo_parents = @$parents; - } else { - my @all_parents = git_find_all_parents($rev); - - if (@all_parents != @$parents) { - @pseudo_parents = get_pseudo_parents(\@all_parents, $parents); - } else { - @pseudo_parents = @$parents; - } - - $revision_spec = $rev; - push @command, "-c"; - } - - my @filenames = ( $revs{$rev}{'filename'} ); - - foreach my $parent (@$parents) { - push @filenames, $revs{$parent}{'filename'}; - } - - push @command, "-p", "-M", $revision_spec, "--", @filenames; - - - my $diff = open_pipe( @command ) - or die "Failed to call git-diff for annotation: $!"; - - _git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo); - - close($diff); -} - -sub _git_diff_parse { - my ($diff, $parents, $rev, %revinfo) = @_; - - my $ri = 0; - - my $slines = $revs{$rev}{'lines'}; - my (%plines, %pi); - - my $gotheader = 0; - my ($remstart); - my $parent_count = @$parents; - - my $diff_header_regexp = "^@"; - $diff_header_regexp .= "@" x @$parents; - $diff_header_regexp .= ' -\d+,\d+' x @$parents; - $diff_header_regexp .= ' \+(\d+),\d+'; - $diff_header_regexp .= " " . ("@" x @$parents); - - my %claim_regexps; - my $allparentplus = '^' . '\\+' x @$parents . '(.*)$'; - - { - my $i = 0; - foreach my $parent (@$parents) { - - $pi{$parent} = 0; - my $r = '^' . '.' x @$parents . '(.*)$'; - my $p = $r; - substr($p,$i+1, 1) = '\\+'; - - my $m = $r; - substr($m,$i+1, 1) = '-'; - - $claim_regexps{$parent}{plus} = $p; - $claim_regexps{$parent}{minus} = $m; - - $plines{$parent} = []; - - $i++; - } - } - - DIFF: - while(<$diff>) { - chomp; - #printf("%d:%s:\n", $gotheader, $_); - if (m/$diff_header_regexp/) { - $remstart = $1 - 1; - # (0-based arrays) - - $gotheader = 1; - - foreach my $parent (@$parents) { - for (my $i = $ri; $i < $remstart; $i++) { - $plines{$parent}[$pi{$parent}++] = $slines->[$i]; - } - } - $ri = $remstart; - - next DIFF; - - } elsif (!$gotheader) { - # Skip over the leadin. - next DIFF; - } - - if (m/^\\/) { - ; - # Skip \No newline at end of file. - # But this can be internationalized, so only look - # for an initial \ - - } else { - my %claims = (); - my $negclaim = 0; - my $allclaimed = 0; - my $line; - - if (m/$allparentplus/) { - claim_line($ri, $rev, $slines, %revinfo); - $allclaimed = 1; - - } - - PARENT: - foreach my $parent (keys %claim_regexps) { - my $m = $claim_regexps{$parent}{minus}; - my $p = $claim_regexps{$parent}{plus}; - - if (m/$m/) { - $line = $1; - $plines{$parent}[$pi{$parent}++] = [ $line, '', '', '', 0 ]; - $negclaim++; - - } elsif (m/$p/) { - $line = $1; - if (get_line($slines, $ri) eq $line) { - # Found a match, claim - $claims{$parent}++; - - } else { - die sprintf("Sync error: %d\n|%s\n|%s\n%s => %s\n", - $ri, $line, - get_line($slines, $ri), - $rev, $parent); - } - } - } - - if (%claims) { - foreach my $parent (@$parents) { - next if $claims{$parent} || $allclaimed; - $plines{$parent}[$pi{$parent}++] = $slines->[$ri]; - #[ $line, '', '', '', 0 ]; - } - $ri++; - - } elsif ($negclaim) { - next DIFF; - - } else { - if (substr($_,scalar @$parents) ne get_line($slines,$ri) ) { - foreach my $parent (@$parents) { - printf("parent %s is on line %d\n", $parent, $pi{$parent}); - } - - my @context; - for (my $i = -2; $i < 2; $i++) { - push @context, get_line($slines, $ri + $i); - } - my $context = join("\n", @context); - - my $justline = substr($_, scalar @$parents); - die sprintf("Line %d, does not match:\n|%s|\n|%s|\n%s\n", - $ri, - $justline, - $context); - } - foreach my $parent (@$parents) { - $plines{$parent}[$pi{$parent}++] = $slines->[$ri]; - } - $ri++; - } - } - } - - for (my $i = $ri; $i < @{$slines} ; $i++) { - foreach my $parent (@$parents) { - push @{$plines{$parent}}, $slines->[$ri]; - } - $ri++; - } - - foreach my $parent (@$parents) { - $revs{$parent}{lines} = $plines{$parent}; - } - - return; -} - -sub get_line { - my ($lines, $index) = @_; - - return ref $lines->[$index] ne '' ? $lines->[$index][0] : $lines->[$index]; -} - -sub git_cat_file { - my ($rev, $filename) = @_; - return () unless defined $rev && defined $filename; - - my $blob = git_ls_tree($rev, $filename); - die "Failed to find a blob for $filename in rev $rev\n" if !defined $blob; - - my $catfile = open_pipe("git","cat-file", "blob", $blob) - or die "Failed to git-cat-file blob $blob (rev $rev, file $filename): " . $!; - - my @lines; - while(<$catfile>) { - chomp; - push @lines, $_; - } - close($catfile); - - return @lines; -} - -sub git_ls_tree { - my ($rev, $filename) = @_; - - my $lstree = open_pipe("git","ls-tree",$rev,$filename) - or die "Failed to call git ls-tree: $!"; - - my ($mode, $type, $blob, $tfilename); - while(<$lstree>) { - chomp; - ($mode, $type, $blob, $tfilename) = split(/\s+/, $_, 4); - last if ($tfilename eq $filename); - } - close($lstree); - - return $blob if ($tfilename eq $filename); - die "git-ls-tree failed to find blob for $filename"; - -} - - - -sub claim_line { - my ($floffset, $rev, $lines, %revinfo) = @_; - my $oline = get_line($lines, $floffset); - @{$lines->[$floffset]} = ( $oline, $rev, - $revinfo{'author'}, $revinfo{'author_date'} ); - #printf("Claiming line %d with rev %s: '%s'\n", - # $floffset, $rev, $oline) if 1; -} - -sub git_commit_info { - my ($rev) = @_; - my $commit = open_pipe("git-cat-file", "commit", $rev) - or die "Failed to call git-cat-file: $!"; - - my %info; - while(<$commit>) { - chomp; - last if (length $_ == 0); - - if (m/^author (.*) <(.*)> (.*)$/) { - $info{'author'} = $1; - $info{'author_email'} = $2; - $info{'author_date'} = $3; - } elsif (m/^committer (.*) <(.*)> (.*)$/) { - $info{'committer'} = $1; - $info{'committer_email'} = $2; - $info{'committer_date'} = $3; - } - } - close($commit); - - return %info; -} - -sub format_date { - if ($rawtime) { - return $_[0]; - } - my ($timestamp, $timezone) = split(' ', $_[0]); - my $minutes = abs($timezone); - $minutes = int($minutes / 100) * 60 + ($minutes % 100); - if ($timezone < 0) { - $minutes = -$minutes; - } - my $t = $timestamp + $minutes * 60; - return strftime("%Y-%m-%d %H:%M:%S " . $timezone, gmtime($t)); -} - -# Copied from git-send-email.perl - We need a Git.pm module.. -sub gitvar { - my ($var) = @_; - my $fh; - my $pid = open($fh, '-|'); - die "$!" unless defined $pid; - if (!$pid) { - exec('git-var', $var) or die "$!"; - } - my ($val) = <$fh>; - close $fh or die "$!"; - chomp($val); - return $val; -} - -sub gitvar_name { - my ($name) = @_; - my $val = gitvar($name); - my @field = split(/\s+/, $val); - return join(' ', @field[0...(@field-4)]); -} - -sub open_pipe { - if ($^O eq '##INSERT_ACTIVESTATE_STRING_HERE##') { - return open_pipe_activestate(@_); - } else { - return open_pipe_normal(@_); - } -} - -sub open_pipe_activestate { - tie *fh, "Git::ActiveStatePipe", @_; - return *fh; -} - -sub open_pipe_normal { - my (@execlist) = @_; - - my $pid = open my $kid, "-|"; - defined $pid or die "Cannot fork: $!"; - - unless ($pid) { - exec @execlist; - die "Cannot exec @execlist: $!"; - } - - return $kid; -} - -package Git::ActiveStatePipe; -use strict; - -sub TIEHANDLE { - my ($class, @params) = @_; - my $cmdline = join " ", @params; - my @data = qx{$cmdline}; - bless { i => 0, data => \@data }, $class; -} - -sub READLINE { - my $self = shift; - if ($self->{i} >= scalar @{$self->{data}}) { - return undef; - } - return $self->{'data'}->[ $self->{i}++ ]; -} - -sub CLOSE { - my $self = shift; - delete $self->{data}; - delete $self->{i}; -} - -sub EOF { - my $self = shift; - return ($self->{i} >= scalar @{$self->{data}}); -} diff --git a/git.c b/git.c index d7103a4..b32ee0f 100644 --- a/git.c +++ b/git.c @@ -219,6 +219,7 @@ static void handle_internal_command(int int option; } commands[] = { { "add", cmd_add, RUN_SETUP }, + { "annotate", cmd_annotate, }, { "apply", cmd_apply }, { "archive", cmd_archive }, { "cat-file", cmd_cat_file, RUN_SETUP }, -- 1.4.2.3.gbf37d ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: perhaps time to remove git_blame from gitweb, and git-annotate? 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano ` (2 preceding siblings ...) 2006-10-09 10:32 ` [PATCH 1/1] Remove git-annotate.perl and create a builtin-alias for git-blame Ryan Anderson @ 2006-10-09 10:37 ` Ryan Anderson 2006-10-09 22:33 ` Obituary for git-annotate Junio C Hamano 3 siblings, 1 reply; 14+ messages in thread From: Ryan Anderson @ 2006-10-09 10:37 UTC (permalink / raw) To: Junio C Hamano Cc: git, Luben Tuikov, Petr Baudis, Jakub Narebski, Ryan Anderson, Johannes Schindelin, Martin Langhoff, Martyn Smith, Fredrik Kuivinen, Linus Torvalds On Thu, Oct 05, 2006 at 01:13:15AM -0700, Junio C Hamano wrote: > It's been a while since we lost git_blame from %actions list. I > am wondering maybe it's time to remove it, after 1.4.3 happens. I certainly have no objection. In fact, I sent a patch a moment ago. (I didn't keep the cc: on it, I figured there was too high a chance of mishap when pasting the cc: list.) I forgot to mentio it in the email, but I have the change pullable from: http://h4x0r5.com/~ryan/git/ryan.git/ del-annotate (and gitwebed from http://h4x0r5.com/~ryan/gitweb.cgi ) -- Ryan Anderson sometimes Pug Majere ^ permalink raw reply [flat|nested] 14+ messages in thread
* Obituary for git-annotate 2006-10-09 10:37 ` perhaps time to remove git_blame from gitweb, and git-annotate? Ryan Anderson @ 2006-10-09 22:33 ` Junio C Hamano 0 siblings, 0 replies; 14+ messages in thread From: Junio C Hamano @ 2006-10-09 22:33 UTC (permalink / raw) To: git; +Cc: Ryan Anderson, Fredrik Kuivinen Ryan Anderson <ryan@michonline.com> writes: > On Thu, Oct 05, 2006 at 01:13:15AM -0700, Junio C Hamano wrote: >> It's been a while since we lost git_blame from %actions list. I >> am wondering maybe it's time to remove it, after 1.4.3 happens. > > I certainly have no objection. In fact, I sent a patch a moment ago. > (I didn't keep the cc: on it, I figured there was too high a chance of > mishap when pasting the cc: list.) So it's finally settled between annotate and blame. It is kind of sad to see one of them had to go while these stem from slightly different algorithm sketches [*1*]. But for 8 months of its existence, it served us well as the git-cvsserver backend. May it rest in peace. Having said that, there are a few things in git-blame that interested people may want to further look into. Annotation by git-blame is done by "passing the blame to parents" principle. You start from the final form of the blob, and compare it with its counterpart in the parent version (rename detection is used to pick which file in the parent version to compare against). The lines the commit inherited from its parent are not responsibility of the child so the algorithm passes blame on them to the parent. The lines the commit changed from the parent are blamed on the child. When this is done, the parent "temporarily" takes responsibility for those lines that child did not change -- it just becomes "suspect" for those lines when we compare parent and child. And then the algorithm goes further down the ancestry to give the parent the chance to exonerate itself by passing blames for the lines it is suspect for, by passing the blame to its parent. When sifting the lines into "inherited" and "our responsibility", internally git-blame runs "diff", which expresses the changes as "these lines are deleted and these are inserted by the child". Lines outside are clearly inherited from the parent. This has an interesting effect on blame output. Suppose the original file had two groups of lines; group A followed by group B. A commit changes the file so that it has group B followed by group A. What git-blame sees as diff between the two is either: -A B +A or +B A -B In either case, it would end up giving blame to the child for one group (the first diff blames the child for A lines) and pass the blame for the other one to the parent. If we used something other than "diff" (Delete Insert File vs File ;-)), that expresses changes as "these are moved from there, these are inserted anew" (call that "miff"), then we should be able to assign blame more accurately. The above example case would be expressed as "group A came from the top part of the parent, group B came from the bottom part of the parent". Passing of the blame based on that expression would blame the child for neither group of lines. Further, if we use "ciff" that expresses changes as "these are copied from there, these are inserted anew", we can do a lot more interesting thing. We can track code movement across files, and that is not limited to renames. For example, suppose that the parent had files F1 and F2 and the child moved a function and copy-and-pasted a comment block from F1 to F2, and we are annotating lines in F2. The current git-blame sees that the function and comment block appeared from nowhere into F2 and blames the child for them. However, when annotating F2, we could: - use concatenation of all files in the parent that was modified between parent and child (or just "all files in the parent" -- the difference is exactly like plain -C vs -C --find-copies-harder) as the source image; - use lines of F2 in the child as the destination image; - run "ciff" algorithm to see where each line of F2 in the child came from (either copied from existing file somewhere in the parent, or inserted anew by the child). This would find that the function and the comment block were copied from F1 in the parent. An interesting property of this is that when the parent passes down the blame for the function the child moved in the above example further to its parent, we do not necessarily have to run "ciff" algorithm on file F1 as the whole. We only need to give the function (i.e. the lines the parent is still suspect for) [*2*]. So this makes destination image fed to "ciff" smaller as more lines are blamed on children while digging deeper, which may compensate for the need to feed not just that file but other files for copy detection on the source image side. [*1*] I think annotate follows this sketch http://thread.gmane.org/gmane.comp.version-control.git/14819/focus=14867 while blame follows this sketch http://thread.gmane.org/gmane.comp.version-control.git/5453/focus=5483 [*2*] we may need to use a handful surrounding context lines for better identification of copy source by the "ciff" algorithm but that is a minor implementation detail. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-10-09 22:34 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-05 0:59 [PATCH 1/2] gitweb: blame: Print just a single new line char per table row Luben Tuikov 2006-10-05 2:35 ` Junio C Hamano 2006-10-05 6:48 ` Luben Tuikov 2006-10-05 8:13 ` perhaps time to remove git_blame from gitweb, and git-annotate? Junio C Hamano 2006-10-06 13:07 ` Johannes Schindelin 2006-10-06 17:52 ` Luben Tuikov 2006-10-07 5:37 ` Martin Langhoff (CatalystIT) 2006-10-06 16:16 ` Petr Baudis 2006-10-06 18:55 ` Luben Tuikov 2006-10-06 19:08 ` Petr Baudis 2006-10-06 20:21 ` Luben Tuikov 2006-10-09 10:32 ` [PATCH 1/1] Remove git-annotate.perl and create a builtin-alias for git-blame Ryan Anderson 2006-10-09 10:37 ` perhaps time to remove git_blame from gitweb, and git-annotate? Ryan Anderson 2006-10-09 22:33 ` Obituary for git-annotate Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).