1

I am having troubles with git's reflog command. Reading the official documentation I got the impression that, main being a local branch where you committed a few times, you could for example call git reflog show main@{1} or its equivalent git reflog main@{1} to show the second-to-last commit in the main branch, and that the same thing should apply to HEAD.

If I try to do that, even on a fresh repo with just three commits

$ git reflog main 8a0a764 (HEAD -> main) main@{0}: commit: third commit 44b44f1 main@{1}: commit: second commit b869f71 main@{2}: commit (initial): first commit 

I get the following error:

fatal: ambiguous argument 'main@': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' 

What am I missing?

ETA: I was using a Windows 10 machine with default Windows Terminal shell (PowerShell), and using quotes as suggested seems to have solved the problem.

3
  • Can you add the actual command you ran there? Commented Mar 1, 2021 at 21:13
  • 2
    That error message (ambiguous argument 'main@':) seems to suggest that something is eating the {0} part of your expression. Can you give us more details no just about the command you ran, but about the environment in which you're running it? Commented Mar 1, 2021 at 21:22
  • 2
    Are you running Powershell/Windows ? If yes : you need to quote "main@{1}" Commented Mar 1, 2021 at 22:36

2 Answers 2

3

Unix-like systems have command interpreters called shells. Popular shells include bash and zsh, but there are many more. Each shell has its own special quirks.

It's very common for shells to support file name globbing: e.g., echo * has * expand to all file names, so that echo does not have to do that. I'd be surprised to find a shell that didn't do this (although anything is possible!). This means that if you want to pass a literal * to any command including Git—Git will do its own glob-style expansion, which won't match the shell's in various cases—you need to quote the asterisk. Otherwise the shell says: Aha, an asterisk, I must replace this with something else. So echo '*' makes echo print the literal character *.

The curly brace character gets this kind of treatment sometimes in some shells. For instance, in csh or tcsh, { participates in brace-expansion:

tcsh$ echo {foo,bar}{baz,quux} foobaz fooquux barbaz barquux 

Here, HEAD@{1} triggers brace-expansion, which dumps HEAD@1 into the final Git command. That's not quite what you're seeing—you got HEAD@, with the {1} part stripped—so clearly you are not using either csh or tcsh.

The bash shell does the same kind of trick, but is a bit cleverer:

bash$ echo {foo,bar}{baz,quux} foobaz fooquux barbaz barquux bash$ echo HEAD@{1} HEAD@{1} 

Because there is no comma inside the {1},1 bash left the whole thing alone and hence passed the right thing to echo.

It's clear that whatever shell you are using, it did something with the {1} part. What, and why, will depend on whatever shell you are using. Most shells obey simple quoting rules where single quotes quote everything, though, so 'HEAD@{1}' should work. I tend to use HEAD@\{1} or HEAD@'{1}', which also work, when I'm in this kind of situation. Consult the documentation for your particular shell for more details.


1Bash's brace-expansion also treats double-dot specially when combined with numeric values or single characters; csh/tcsh's does not.

Sign up to request clarification or add additional context in comments.

Comments

0

Works fine for me. I tried it, and this is what I got:

$ git reflog aea0abc (HEAD -> main) HEAD@{0}: commit: three 2f583ad HEAD@{1}: commit: two 0a44af0 HEAD@{2}: commit: one 

And then:

$ git reflog show main@{1} 2f583ad main@{1}: commit: two 0a44af0 main@{2}: commit: one 

So, as has been suggested, it sounds like something about your command line environment is not happy with the syntax of the phrase main@{1} — but you have not told us anything about that environment, so it's hard to say what the issue might be. (I'm using Bash on Mac if that's any help.) As torek's answer suggests, saying git reflog show 'main@{1}' might solve it on your machine.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.