threads / discuss / 20401

blame on a deleted/renamed file

Subject: blame on a deleted/renamed file

## tl;dr

8 messages between Aug 5, 2009 and Aug 5, 2009.

replies: 7people: 5as markdown or json

Dan McGee· Aug 5, 2009, 12:16 UTC · lore

Is there no easy way in git to get a blame on a file that has either been renamed or deleted? I'll step through my thought process, and a quick google and read of the manpage returned nothing obvious. Here is the repository in question if it matters: git://projects.archlinux.org/pacman.git. I located a particular commit I was interested using a plain git-blame: $ git blame scripts/makepkg.sh.in

OK, looks like lines moved around enough that we got stuck here, let's see what this patch did: $ git show e19d7da4

OK, it did a move of a bunch of lines into functions that GIT couldn't quite track: $ git annotate --follow "scripts/makepkg.in" e19d7da4~1 fatal: cannot stat path 'scripts/makepkg.in': No such file or directory

$ git annotate --follow "scripts/makepkg.sh.in" e19d7da4~1 fatal: no such path scripts/makepkg.sh.in in e19d7da4~1

Help? Or do I need to think about writing some sort of patch for it? This is the first thing I have seen svn be able to do[1] that git can't. :)

-Dan
[1] svn annotate http://path/to/repo/path/to/file@2345
Björn Steinbrink· Aug 5, 2009, 12:37 UTC · re: Dan McGee · lore

Re: blame on a deleted/renamed file

On 2009.08.05 07:16:13 -0500, Dan McGee wrote:
Show 9 quoted lines
> Is there no easy way in git to get a blame on a file that has either
> been renamed or deleted? I'll step through my thought process, and a
> quick google and read of the manpage returned nothing obvious. Here is
> the repository in question if it matters:
> git://projects.archlinux.org/pacman.git. I located a particular commit
> I was interested using a plain git-blame:
> $ git blame scripts/makepkg.sh.in
> 
> OK, looks like lines moved around enough that we got stuck here, let's

How did it get stuck? The output I see follows the changes the whole way back through scripts/makepkg.in, scripts/makepkg.in and scripts/makepkg.

Show 7 quoted lines
> see what this patch did:
> $ git show e19d7da4
> 
> OK, it did a move of a bunch of lines into functions that GIT couldn't
> quite track:
> $ git annotate --follow "scripts/makepkg.in" e19d7da4~1
> fatal: cannot stat path 'scripts/makepkg.in': No such file or directory
Where does that --follow come from? I don't see that in the man page.

And scripts/makepkg.in got added in e19d7da4, so its parent didn't have it.

> $ git annotate --follow "scripts/makepkg.sh.in" e19d7da4~1
> fatal: no such path scripts/makepkg.sh.in in e19d7da4~1

Same deal, scripts/makepkg.sh.in didn't exist in e19d7da4~1 either, it got renamed from scripts/makepkg.in in b5f8a44be

> Help? Or do I need to think about writing some sort of patch for it?
> This is the first thing I have seen svn be able to do[1] that git
> can't. :)
Uhm, no, svn fails in the exact same way, not quite unexpected.

doener@atjola:~ $ mkdir h doener@atjola:~ $ cd h doener@atjola:h $ svnadmin create repo doener@atjola:h $ svn co file://$PWD/repo wc Checked out revision 0. doener@atjola:h $ cd wc

doener@atjola:wc $ touch foo; svn add foo; svn commit -m init A foo Adding foo Transmitting file data . Committed revision 1. doener@atjola:wc $ svn mv foo bar; svn commit -m rename A bar D foo Adding bar Deleting foo

Committed revision 2. doener@atjola:wc $ cd ..

doener@atjola:h $ svn blame file://$PWD/repo/bar doener@atjola:h $ svn blame file://$PWD/repo/bar@1 svn: '/bar' is not a file in revision 1

Björn
Matthieu Moy· Aug 5, 2009, 12:54 UTC · re: Björn Steinbrink · lore

Re: blame on a deleted/renamed file

Björn Steinbrink <B.Steinbrink@gmx.de> writes:
> doener@atjola:h $ svn blame file://$PWD/repo/bar
> doener@atjola:h $ svn blame file://$PWD/repo/bar@1
> svn: '/bar' is not a file in revision 1

but "svn blame bar -r 1" here actually means "give me the blame for the file whose name is now 'bar' starting from revision 1". I don't know how to do such thing with a single git command.

-- 
Matthieu
Dan McGee· Aug 5, 2009, 13:54 UTC · re: Björn Steinbrink · lore

Re: blame on a deleted/renamed file

2009/8/5 Björn Steinbrink <B.Steinbrink@gmx.de>:
Show 13 quoted lines
> On 2009.08.05 07:16:13 -0500, Dan McGee wrote:
>> Is there no easy way in git to get a blame on a file that has either
>> been renamed or deleted? I'll step through my thought process, and a
>> quick google and read of the manpage returned nothing obvious. Here is
>> the repository in question if it matters:
>> git://projects.archlinux.org/pacman.git. I located a particular commit
>> I was interested using a plain git-blame:
>> $ git blame scripts/makepkg.sh.in
>>
>> OK, looks like lines moved around enough that we got stuck here, let's
>
> How did it get stuck? The output I see follows the changes the whole way
> back through scripts/makepkg.in, scripts/makepkg.in and scripts/makepkg.

I said nothing about it not following renames. I asked about it following *those lines*. I know it already made the jump from scripts/makepkg.sh.in to scripts/makepkg.in, sorry if I wasn't clear there.

Show 9 quoted lines
>> see what this patch did:
>> $ git show e19d7da4
>>
>> OK, it did a move of a bunch of lines into functions that GIT couldn't
>> quite track:
>> $ git annotate --follow "scripts/makepkg.in" e19d7da4~1
>> fatal: cannot stat path 'scripts/makepkg.in': No such file or directory
>
> Where does that --follow come from? I don't see that in the man page.

It's not. The git-annotate manpage is misleading as heck though; I see now I should have went straight to git-blame instead. Why have the two commands diverged so much?

Thomas Rast had it perfect when suggesting this, which works perfectly (for what I wanted): $ git blame e19d7~1 -- scripts/makepkg.in

> And scripts/makepkg.in got added in e19d7da4, so its parent didn't have
> it.

Not sure where you are seeing that, it was changed in that revision, not added...

Show 5 quoted lines
>> $ git annotate --follow "scripts/makepkg.sh.in" e19d7da4~1
>> fatal: no such path scripts/makepkg.sh.in in e19d7da4~1
>
> Same deal, scripts/makepkg.sh.in didn't exist in e19d7da4~1 either, it
> got renamed from scripts/makepkg.in in b5f8a44be

That was my whole point here- I was stabbing in the dark so I showed you everything I tried because the git-annotate manpage failed me.

Show 30 quoted lines
>> Help? Or do I need to think about writing some sort of patch for it?
>> This is the first thing I have seen svn be able to do[1] that git
>> can't. :)
>
> Uhm, no, svn fails in the exact same way, not quite unexpected.
>
> doener@atjola:~ $ mkdir h
> doener@atjola:~ $ cd h
> doener@atjola:h $ svnadmin create repo
> doener@atjola:h $ svn co file://$PWD/repo wc
> Checked out revision 0.
> doener@atjola:h $ cd wc
>
> doener@atjola:wc $ touch foo; svn add foo; svn commit -m init
> A         foo
> Adding         foo
> Transmitting file data .
> Committed revision 1.
> doener@atjola:wc $ svn mv foo bar; svn commit -m rename
> A         bar
> D         foo
> Adding         bar
> Deleting       foo
>
> Committed revision 2.
> doener@atjola:wc $ cd ..
>
> doener@atjola:h $ svn blame file://$PWD/repo/bar
> doener@atjola:h $ svn blame file://$PWD/repo/bar@1
> svn: '/bar' is not a file in revision 1
svn blame file://$PWD/repo/foo@1 works perfectly though, that was my use case.

Sorry for doing like a point-by-point refute of your response here, I probably wasn't clear enough in my original email. However, thank you Thomas Rast for your suggestions, as the git-blame syntax is much more powerful and allows me to do exactly what I wanted.

Does anyone object to making the following wording in the git-annotate manpage: The only difference between this command and linkgit:git-blame[1] is that they use slightly different output formats, and this command exists only for backward compatibility to support existing scripts, and provide a more familiar command name for people coming from other SCM systems.

slightly stronger? git-blame destroys git-annotate as far as I can see with the "rev first then file" syntax which actually allows you to get past annotations on renamed or deleted files.

-Dan
Björn Steinbrink· Aug 5, 2009, 14:09 UTC · re: Dan McGee · lore

Re: blame on a deleted/renamed file

On 2009.08.05 08:54:09 -0500, Dan McGee wrote:
Show 19 quoted lines
> 2009/8/5 Björn Steinbrink <B.Steinbrink@gmx.de>:
> > On 2009.08.05 07:16:13 -0500, Dan McGee wrote:
> >> Is there no easy way in git to get a blame on a file that has either
> >> been renamed or deleted? I'll step through my thought process, and a
> >> quick google and read of the manpage returned nothing obvious. Here is
> >> the repository in question if it matters:
> >> git://projects.archlinux.org/pacman.git. I located a particular commit
> >> I was interested using a plain git-blame:
> >> $ git blame scripts/makepkg.sh.in
> >>
> >> OK, looks like lines moved around enough that we got stuck here, let's
> >
> > How did it get stuck? The output I see follows the changes the whole way
> > back through scripts/makepkg.in, scripts/makepkg.in and scripts/makepkg.
> 
> I said nothing about it not following renames. I asked about it
> following *those lines*. I know it already made the jump from
> scripts/makepkg.sh.in to scripts/makepkg.in, sorry if I wasn't clear
> there.

Hm, I still don't see what you mean. For some lines it stopped at e19d7da4, yeah, but those were new lines, added in that commit, at least those that I checked (e.g. "local ct=0" in generate_checksums()). For the others, it already went back further.

Show 5 quoted lines
> > And scripts/makepkg.in got added in e19d7da4, so its parent didn't have
> > it.
> 
> Not sure where you are seeing that, it was changed in that revision,
> not added...

No idea, I guess I got confused by the various makepkg.* versions :-/ Especially by the "stab in the dark" blame call. ;-)

Show 14 quoted lines
> >> $ git annotate --follow "scripts/makepkg.sh.in" e19d7da4~1
> >> fatal: no such path scripts/makepkg.sh.in in e19d7da4~1
> >
> > Same deal, scripts/makepkg.sh.in didn't exist in e19d7da4~1 either, it
> > got renamed from scripts/makepkg.in in b5f8a44be
> 
> That was my whole point here- I was stabbing in the dark so I showed
> you everything I tried because the git-annotate manpage failed me.
> 
> >> Help? Or do I need to think about writing some sort of patch for it?
> >> This is the first thing I have seen svn be able to do[1] that git
> >> can't. :)
> >
> > Uhm, no, svn fails in the exact same way, not quite unexpected.
[...]
Show 5 quoted lines
> > doener@atjola:h $ svn blame file://$PWD/repo/bar
> > doener@atjola:h $ svn blame file://$PWD/repo/bar@1
> > svn: '/bar' is not a file in revision 1
> 
> svn blame file://$PWD/repo/foo@1 works perfectly though, that was my use case.

Yeah, with the old name, and that works in git too, same deal as with the previous one, I've been totally confused, sorry.

> Sorry for doing like a point-by-point refute of your response here, I
> probably wasn't clear enough in my original email.

No problem, pointing out my mistakes is the best you could do. And basically, I (wrongly) did the same to your mail. ;-)

Björn
Thomas Rast· Aug 5, 2009, 13:24 UTC · re: Dan McGee · lore

Re: blame on a deleted/renamed file

Dan McGee wrote:
Show 5 quoted lines
> 
> This is the first thing I have seen svn be able to do[1] that git
> can't. :)
> 
> [1] svn annotate http://path/to/repo/path/to/file@2345

The only thing broken is git-annotate's guessing code to see if you use the 'git annotate <file> <revision>' (legacy) or 'git annotate <revision> <file>' syntax.

I'd simply write the unambiguous
  git blame e19d7da4~1 -- "scripts/makepkg.in"

and similarly for other revisions. And you'll immediately notice that git *can* do this.

> OK, it did a move of a bunch of lines into functions that GIT couldn't
> quite track:
You can try
  git blame -C -C scripts/makepkg.sh.in

to let git try *really* hard to find out where the lines come from. Note that it does find some lines from older commits, e.g.,

  2ef1c841 scripts/makepkg.in    (Dag Odenhall                2007-05-30 23:04:36 +0200  470)

in the body of download_sources, which was moved (but apparently not changed) in e19d7da4 (Andrew Fyfe, 2007-06-01 22:10:27 +0100).

-- 
Thomas Rast
trast@{inf,student}.ethz.ch
Junio C Hamano· Aug 5, 2009, 17:25 UTC · re: Dan McGee · lore

Re: blame on a deleted/renamed file

Dan McGee <dpmcgee@gmail.com> writes:
> $ git annotate --follow "scripts/makepkg.in" e19d7da4~1
> fatal: cannot stat path 'scripts/makepkg.in': No such file or directory
Syntax error.  "git blame e19d7da4~1 -- scrits/makepkg.in".
Björn Steinbrink· Aug 5, 2009, 16:56 UTC · lore

Re: blame on a deleted/renamed file

On 2009.08.05 10:49:09 -0500, Dan McGee wrote:
Show 27 quoted lines
> 2009/8/5 Björn Steinbrink <B.Steinbrink@gmx.de>:
> > Hm, I still don't see what you mean. For some lines it stopped at
> > e19d7da4, yeah, but those were new lines, added in that commit, at least
> > those that I checked (e.g. "local ct=0" in generate_checksums()). For
> > the others, it already went back further.
> 
> Thought I'd just clarify the lines off-list that I actually cared about:
> 
>     # fix flyspray #6246
>     local file_type=$(file -bizL "$file")
>     local cmd=''
>     case "$file_type" in
>       *application/x-tar*|*application/zip*|*application/x-zip*|*application/x-cpio*)
>         cmd="bsdtar -x -f" ;;
>       *application/x-gzip*)
>         cmd="gunzip -d -f" ;;
>       *application/x-bzip*)
>         cmd="bunzip2 -f" ;;
>       *application/x-xz*)
>         cmd="xz -d -f" ;;
>       *)
>         # Don't know what to use to extract this file,
>         # skip to the next file
>         continue;;
> 
> Which moved in that commit into a bash function, and I wanted to trace
> them back further.

Ah, ok. Most of these got changed later, so the blame is right for them, but for example the *application/x-gzip*) line was just literally moved in the file, and blame should be able to follow at least that one. And it does that as long as you don't cross commit 68c10690eae369928b6cdc2d658588ad06e4b1a5, which changed the cmd="..." lines. Even with -M5 -C5 -C5 -C5 (which should set the scores low enough, and enables the hardest following mode) it starts to blame that line to e19d7da4 then. The same is true if you blame too few lines.

git blame -M5 -C5 -C5 -C5 -w -L/x-gzip/,+3 \
	68c10690eae369928b6cdc2d658588ad06e4b1a5^ -- scripts/makepkg.sh.in
vs.
git blame -M5 -C5 -C5 -C5 -w -L/x-gzip/,+2 \
	68c10690eae369928b6cdc2d658588ad06e4b1a5^ -- scripts/makepkg.sh.in
The first one follows back to 7ed7977e, the other stops at e19d7da4.
I wonder whether that's a plain limitation, or a bug...
Björn

← back to recent threads