0

Having an initial repository I create a Test.TXT file and fill it in with this content:

Version 1
Version 1
Version 1

Next, it is committed:

$ git commit -am Version1

And the Test.TXT has suffered some ammendment:

Version 1
Version 2
Version 1

$ git commit -am Version2

Now I'm curious to find out what changes were made to the file since Version1:

$ git log --oneline -- Test.TXT
f315c22 (HEAD -> master) Version2
3b173c2 Version1

$ git blame 3b173c2 .. -- Test.TXT
^3b173c2 (Mergasov 2020-10-06 13:49:50 +0300 1) version 1
^3b173c2 (Mergasov 2020-10-06 13:49:50 +0300 2) version 1
^3b173c2 (Mergasov 2020-10-06 13:49:50 +0300 3) version 1

Such blame's output is a bit unexpected for me.

Firtsly, what does the caret symbol (^) stand for here? The blame docs refer to it as a boundary marker (that is, it marks the first commit for a file). But if I type in the HEAD (it's the second commit of the Test.TXT) instead of 3b173c2, I would get ^f315c22 (in every rows) yet again.

So using git blame in this way just cause appearence of the version of a file which fits the choosed SHA1 commit, doesn't it? It doesn't even show SHA1 of either previous commits (such result can be achieved by using blame without two dots) nor following ones (it that I try to accomplish). In lieu we can see the typed SHA1 version setting off by the caret symbol.

Can anyone explain what's the reason to use this command (with the double dot)?

Ilya Loskutov
  • 1,967
  • 2
  • 20
  • 34

2 Answers2

3

If you were to simply execute the command (in the repo root):

git blame ..

git would tell you:

$ git blame ..
fatal: '..' is outside repository

The argument:

..

in this case, is a reference to the parent directory. If you then pass a file as argument:

git blame .. -- changelog.txt

You'll notice that the output has the ^abcdbeef syntax for each line as well as your name as the committer (while it may in fact have been someone elses file). The ^ before a reference means its not reachable from your current branch/reference.

zrrbite
  • 1,180
  • 10
  • 22
  • How blame interprets a double dot here? Clearly, it's not a path to a revision (cause `3b173c2 ..` is a wrong one). So what's a path does blame expect? You said commits marked with `^` are not reachable. Where are they not reachable from? From a parent directory (as I understand you "current branch" means external, in a parent directory, doesn't)? – Ilya Loskutov Oct 06 '20 at 14:51
  • `3b173c2` is the reference pointed to by `HEAD`. So it's basically showing you a blame for a file that would be outside of your repository (`..`) / Not accessible from your repository (`^HEAD`). It's a quirky output which does not really have a lot of uses, imo. – zrrbite Oct 07 '20 at 06:41
-2

Well.... the .. seem to point to the parent directory, as zbrrbite is saying... this is the first time I see it used like that.... (.. and then providing a fulename). I know you can use it if you mean to ask blame to analyze only a subset of revisions, not the full story of a file (like..... version-from-a-year-ago..some-branch). Then given that you are providing a revision specifically, git is not actually checking the file as it is on your current revision. It is blaming the file as it was on that revision..... the ^ means, to the best of my understanding, that it is in the limit of the range of revisions that it has for analysis (say..... a project that is 10 years old, you might have asked blame to check from the last 5 years.... it might have found that the line came from the first revisions of those 5 years.... there might be more revisions older than it involved, but it can't check further back because of your restriction to be only from the last 5 years.... hence you get a ^). If you provided HEAD (and you are standing on the second revision) as the revision, you might get the new revision if the line was somehow changed on that revision..... but you are getting the new revision on every line when running blame with HEAD? That sounds like you changed EOL format of the file. What happens if you try git blame -w -- the-file?

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • As I said in my question `$ git blame -- Test.JS` returns a list of changes up to this specific revision. You tell about it (and yes, the caret symbol here refers to either the first revision of a file or revisions "beyound the scope"). I've got this. Surprises begin if blame gets double dot as an argument (note in my case `..` isn't a path to a revision it's the different argument at all). – Ilya Loskutov Oct 06 '20 at 14:22