How to solve the "ambiguous argument 'origin..HEAD'"...

hustnzj發表於2022-09-07

I often use git log subtraction feature to check the difference between branches. But in the last few days, I found that it didn’t work in some repositories.

$ my-git-repo git:(master) git log origin..HEAD
fatal: ambiguous argument 'origin..HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

In the official docs, there are description about this feature:

A special notation “<commit1>..<commit2>“ can be used as a short-hand for “^<commit1> <commit2>“. For example, either of the following may be used interchangeably:
$ git log origin..HEAD
$ git log HEAD ^origin

It can be inferred that the origin and HEAD represent the origin/<branch-name> and <current-checkout-branch-name> respectively. But Why this notation can only be used in some repositories?

In some repository which is not cloned, we just add some remote repository with git remote add <name> <url> without -m <master> flag. So the symbolic-ref refs/remotes/<name>/HEAD is not set up to point at remote’s <master> branch.

In origin..HEAD, origin should be interpreted as origin/HEAD which is the symbolic-ref refs/remotes/origin/HEAD that is not set up yet.

➜  my-git-repo git:(master) ll -at .git/refs/remotes/origin
total 8
drwxr-xr-x  5 administrator  staff   160B Sep  6 10:22 ..
drwxr-xr-x  3 administrator  staff    96B Sep  6 10:17 .
-rw-r--r--  1 administrator  staff    41B Sep  6 10:15 master

To set up the origin/HEAD to point to a origin/<branch-name>, we need to use git remote set-head command.

To set it explicitly:

git remote set-head origin master 

Or to query the remote and automatically set origin/HEAD to the remote’s current branch.

git remote set-head origin -a

After set up, the symbolic-ref refs/remotes/origin/HEAD can be found:

➜  my-git-repo git:(master) ll -at .git/refs/remotes/origin
total 16
drwxr-xr-x  4 administrator  staff   128B Sep  7 09:19 .
-rw-r--r--  1 administrator  staff    32B Sep  7 09:19 HEAD
drwxr-xr-x  5 administrator  staff   160B Sep  6 10:22 ..
-rw-r--r--  1 administrator  staff    41B Sep  6 10:15 master

And run git branch -r, Now the origin/HEAD is pointing to the remote master branch.

  central/master
  john/pink-page
  origin/HEAD -> origin/master
  origin/master

Then we can run git log origin..HEAD without any errors. Great!

$ git log origin..HEAD

The result as below:

commit 2847256281538899f13be63dd4f84e345d900248 (HEAD -> master)
Author: hustnzj <27875723+hustnzj@users.noreply.github.com>
Date:   Sun Sep 4 10:16:52 2022 +0800

    Add .DS_Store into .gitignore file

commit e3e4b9d2bb6754fb64ad2e88071e923f49596203 (tag: v2.0-lw, central/master)
Author: hustnzj <27875723+hustnzj@users.noreply.github.com>
Date:   Sun Sep 4 10:16:52 2022 +0800

    Add .gitignore file

Conclusion

The reason of “ambiguous argument ‘origin..HEAD’” error is the default branch of the named remote is not exist. So we need to set the default branch (i.e. the target of the symbolic-ref refs/remotes/<name>/HEAD) for the named remote if we don’t want to specify the branch everywhere.

References

version control - Why is “origin/HEAD” shown when running “git branch -r”? - Stack Overflow
git - fatal: ambiguous argument ‘origin’: unknown revision or path not in the working tree - Stack Overflow

本作品採用《CC 協議》,轉載必須註明作者和本文連結
日拱一卒

相關文章