]> Lady’s Gitweb - Gitweb/commit
gitweb: Use "previous" header of git-blame -p in 'blame' view
authorJakub Narebski <redacted>
Fri, 24 Jul 2009 22:44:03 +0000 (00:44 +0200)
committerLady <redacted>
Mon, 6 Apr 2026 04:50:39 +0000 (00:50 -0400)
commite0a6228ec35491febcc3edd1ef6fbba95bce26fd7315b3a45f6c71a88e724ef6
tree811d6fe1c6f482574ddb670b0f9eecb943d56af9459e190e731a2750944b9f09
parent3c8296019ffc1b5e0bcdb3321a7b2dd1aaeab92f47219a948c71eae79be5d542
gitweb: Use "previous" header of git-blame -p in 'blame' view

Luben Tuikov changed 'lineno' link (line number link) from pointing to
'blame' view at given line at blamed commit, to the one at parent of
blamed commit in
  244a70e (Blame "linenr" link jumps to previous state at
           "orig_lineno", 2007-01-04).
This made it possible to do data mining using 'blame' view, by going
through history of a line using mentioned line number link.

Original implementation called "git rev-parse <commit>^" to find SHA-1
of a parent of a given commit once per each blamed line.  In
  39c19ce (gitweb: cache $parent_commit info in git_blame(),
           2008-12-11)
this was improved so rev-parse was called once per each unique commit
in git-blame output.  Alternate solution would be to relax validation
for 'hb' parameter by allowing extended SHA-1 syntax of the form
<rev>^ (perhaps redirecting to gitweb URL with <rev>^ resolved, in
practice moving call to rev-parse to 'the other side of link').

This solution had a bug that it didn't work for boundary commits.
Boundary commits don't have parents, so "git rev-parse <commit>^"
returned literal "<commit>^" (which didn't exists).  Gitweb didn't
detect this situation and passed this result literally as 'hb'
parameter in 'linenr' link.  Following such link currently gives
  400 - Invalid hash base parameter
error; 'hb' parameter is restricted via validate_refname to correct
refnames and doesn't allow for extended SHA-1 syntax.  This bug could
have been fixed alternatively by checking if commit is boundary commit,
or check if rev-parse result is unchanged (still ends in '^' prefix).

The solution employing rev-parse to find parent of commit had inherent
problem if blamed commit renamed file; then name of file would be
different in its parent.  Solving this outside git-blame would be
difficult and costly (at least cost of additional fork for extra git
command).

Currently gitweb uses information in "previous" header, which was
introduced by Junio C Hamano in
  96e1170 (blame: show "previous" information in
           --porcelain/--incremental format, 2008-06-04)
This (currently undocumented) header has the following format:
  "previous <sha1 of parent commit> <filename at parent>"
Using "previous" header solves both problem of performance and the
problem that blamed commit could have renaming blamed file.

Because "previous" header can be repeated for the same commit when
blamed commit is merge (has more than one parent), and we are
interested usually in _first_ parent, currently we store only first
value if blame header repeats.  Using first parent (first "previous"
line) was what gitweb did before; without this change gitweb would use
last parent instead.

If there is no previous commit 'linenr' link points to blamed commit
and blamed filename, making it work correctly for boundary commits.

Acked-by: Luben Tuikov <redacted>
Signed-off-by: Jakub Narebski <redacted>
Signed-off-by: Junio C Hamano <redacted>
gitweb.perl
This page took 0.184324 seconds and 4 git commands to generate.