1

I came across a git expression, git show master@{3} and I have no idea what it's for and how to use it. I get it what is git show for but the puzzling part here is the @{3}. In my repo I did try this command, and terminal said fatal: Log for 'master' only has 1 entries., so couldn't figure it out from the message.
Could you anyone explain that for me and why I got this specific error. Thanks a ton.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Mat Watershed
  • 45
  • 3
  • 7

2 Answers2

4

See git help revisions for help.

@ alone is a shortcut for HEAD.

HEAD is explained in the same document:

HEAD names the commit on which you based the changes in the working tree.

And the curly brackets are described there, too:

@{<n>}, e.g. @{1}

You can use the @ construct with an empty ref part to get at a reflog entry of the current branch. For example, if you are on branch blabla then @{1} means the same as blabla@{1}.

So, @{3} points to the third prior reflog value from the entry of the current branch.

choroba
  • 231,213
  • 25
  • 204
  • 289
2

As I mentioned before, @ means HEAD.

But regarding the specific error fatal: Log for 'master' only has 1 entries. (specific to this question):

After expiring a reflog and making a single commit, the reflog for the branch would record a single entry that knows both @{0} and @{1}, but we failed to answer "what commit were we on?", i.e. @{1}

That has been fixed with Git 2.31 (Q1 2021), so you should not always see that error message.

See commit 6436a20 (07 Jan 2021), and commit 95c2a71 (06 Jan 2021) by Denton Liu (Denton-L).
(Merged by Junio C Hamano -- gitster -- in commit 440acfb, 25 Jan 2021)

refs: allow @{n} to work with n-sized reflog

Suggested-by: Junio C Hamano
Signed-off-by: Denton Liu

This sequence works

$ git checkout -b newbranch
$ git commit --allow-empty -m one
$ git show -s newbranch@{1}

and shows the state that was immediately after the newbranch was created.

But then if you do

$ git reflog expire --expire=now refs/heads/newbranch
$ git commit --allow=empty -m two
$ git show -s newbranch@{1}

you'd be scolded with

fatal: log for 'newbranch' only has 1 entries

While it is true that it has only 1 entry, we have enough information in that single entry that records the transition between the state in which the tip of the branch was pointing at commit 'one' to the new commit 'two' built on it, so we should be able to answer "what object newbranch was pointing at?".
But we refuse to do so.

Make @{0} the special case where we use the new side to look up that entry.
Otherwise, look up @{n} using the old side of the (n-1)th entry of the reflog.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250