git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [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-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 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 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

* 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

* [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

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).