How to 'git blame' on the remote-side repository?

别等时光非礼了梦想. 提交于 2019-12-03 19:26:47

问题


on my server I host my personal git remote-side projects (with gitosis), and I have built a web interface to browse the repositories (something like Github).

On the remote-side, you are not allowed to do a lot of stuff, because a working tree is missing, and this is correct: btw, for a repository explorer, with few commands I can do almost everything.

Except for git blame.

I'm not able to find out how to blame a file without a working tree, within the remote-side repository. Got you some ideas?


回答1:


The following should work even in bare repositories:

git blame <rev> -- <path>

E.g.

git blame master -- README.txt



回答2:


I'm not able to find where the git docs talk about -- option, by the way this works greatly

Actually, this is necessary because "git blame" is prepared to take an ancient odd argument order "blame <path> <rev>" in addition to the usual "blame [<rev>] <path>".

That means, as Git 2.17 (Q2 2018) will explain "git blame HEAD COPYING" in a bare repository failed to run, while "git blame HEAD -- COPYING" run just fine.

But from 2.17 on, you won't need '--' anymore.

See commit 0c668f5 (05 Feb 2018) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 0c668f5, 07 Feb 2018)

blame: tighten command line parser

An ancient odd argument order "blame <path> <rev>" in addition to the usual "blame [<rev>] <path>" has at least two negative ramifications:

  • In order to tell these two apart, it checks if the last command line argument names a path in the working tree, using file_exists().
    However, "blame <rev> <path>" is a request to explain each and every line in the contents of <path> stored in revision <rev> and does not need to have a working tree version of the file. A check with file_exists() is simply wrong.

  • To coerce that mistaken file_exists() check to work, the code calls setup_work_tree() before doing so, because the path it has is relative to the top-level of the project tree.
    However, "blame <rev> <path>" MUST be usable even in a bare repository, and there is no reason for letting setup_work_tree() complain and die with "This operation must be run in a work tree".

To correct the former, switch to check if the last token is a revision (and if so, parse arguments using "blame <path> <rev>" rule).

Correct the latter by getting rid of setup_work_tree() and file_exists() check--the only case the call to this function matters is when we are running "blame <path>" (i.e. no starting revision and asking to blame the working tree file at <path>, digging through the HEAD revision), but there is a call in setup_scoreboard() just before it calls fake_working_tree_commit().

So in short, starting Git 2.17, this will work in a bare repo:

git blame master -- README.txt

And with Git 2.22, the error message "This operation must be run in a work tree" should disappear!

"git blame -- path" in a non-bare repository starts blaming from the working tree, and the same command in a bare repository errors out because there is no working tree by definition.
The command has been taught to instead start blaming from the commit at HEAD, which is more useful.

See commit a544fb0 (07 Apr 2019) by SZEDER Gábor (szeder).
(Merged by Junio C Hamano -- gitster -- in commit d8620d3, 25 Apr 2019)

blame: default to HEAD in a bare repo when no start commit is given

When 'git blame' is invoked without specifying the commit to start blaming from, it starts from the given file's state in the work tree.
However, when invoked in a bare repository without a start commit, then there is no work tree state to start from, and it dies with the following error message:

$ git rev-parse --is-bare-repository
true
$ git blame file.c
fatal: this operation must be run in a work tree

This is misleading, because it implies that 'git blame' doesn't work in bare repositories at all, but it does, in fact, work just fine when it is given a commit to start from.

We could improve the error message, of course, but let's just default to HEAD in a bare repository instead, as most likely that is what the user wanted anyway (if they wanted to start from an other commit, then they would have specified that in the first place).

'git annotate' is just a thin wrapper around 'git blame', so in the same situation it printed the same misleading error message, and this patch fixes it, too.


Note: if you are using gitweb to see the "blames", as recommended by Jakub Narębski , there is a rather old bug in gitweb, where the incremental blame output in javascript actions mode never worked.
This is fixed with Git 2.24 (Q4 2019).

See commit 52bd3e4 (27 Oct 2019) by Robert Luberda (roblub).
(Merged by Junio C Hamano -- gitster -- in commit 0d6799e, 30 Oct 2019)

gitweb: correctly store previous rev in javascript-actions mode

Signed-off-by: Jonathan Nieder
Signed-off-by: Robert Luberda
Acked-by: Jakub Narębski

Without this change, the setting

$feature{'javascript-actions'}{'default'} = 2;

in gitweb.conf breaks gitweb's blame page: clicking on line numbers displayed in the second column on the page has no effect.

For comparison, with javascript-actions disabled, clicking on line numbers loads the previous version of the line.

Addresses https://bugs.debian.org/741883.



来源:https://stackoverflow.com/questions/4169556/how-to-git-blame-on-the-remote-side-repository

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!