Ltf4an
Ltf4an

Reputation: 837

What should "git rev-list origin..HEAD" return?

The git-rev-list man page shows the following commands:

$ git rev-list origin..HEAD
$ git rev-list HEAD ^origin

However, when I run the 1st command, I get the following error:

$ git rev-list 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>...]'

'origin' refers to the following remote:

$ git remote -v
origin  c:/hands_on/git/learn/clone/../repo_1 (fetch)
origin  c:/hands_on/git/learn/clone/../repo_1 (push)

Am I using the command incorrectly? Also, I thought the rev-list command takes commits as input, so I'm not clear why the man page uses 'origin' which is a remote rather. What have I misunderstood?

Upvotes: 2

Views: 6939

Answers (2)

Ry-
Ry-

Reputation: 224913

git-rev-parse(1) explains how the name of a remote can be used as a ref:

<refname>, e.g. master, heads/master, refs/heads/master
   A symbolic ref name. E.g.  master typically means the commit object
   referenced by refs/heads/master. If you happen to have both heads/master and
   tags/master, you can explicitly say heads/master to tell Git which one you
   mean. When ambiguous, a <refname> is disambiguated by taking the first match
   in the following rules:

    1. If $GIT_DIR/<refname> exists, that is what you mean (this is usually
    useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and
    CHERRY_PICK_HEAD);

    2. otherwise, refs/<refname> if it exists;

    3. otherwise, refs/tags/<refname> if it exists;

    4. otherwise, refs/heads/<refname> if it exists;

    5. otherwise, refs/remotes/<refname> if it exists;

    6. otherwise, refs/remotes/<refname>/HEAD if it exists.

And git-remote(1) explains what refs/remotes/<remote>/HEAD is in the description of git remote set-head:

   set-head
       Sets or deletes the default branch (i.e. the target of the symbolic-ref
       refs/remotes/<name>/HEAD) for the named remote. Having a default branch
       for a remote is not required, but allows the name of the remote to be
       specified in lieu of a specific branch. For example, if the default
       branch for origin is set to master, then origin may be specified wherever
       you would normally specify origin/master.

In other words, it uses the default branch for the remote, and you don’t appear to have one.

Upvotes: 3

poke
poke

Reputation: 387677

As you correctly said, git rev-list is supposed to take a commit range there, so using the name of a remote does not really make sense.

The documentation previously (pre 2006, so very long ago) said the following:

A special notation <commit1>..<commit2> can be used as a short-hand for ^<commit1> <commit2>.

This was then changed with this commit (mailing list discussion) to:

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-rev-list origin..HEAD
$ git-rev-list HEAD ^origin

The commit message for that change was the following:

git-rev-list(1): group options; reformat; document more options

I can only assume, that the use of origin there was a mistake and not meant to literally refer to a remote. The documentation is plastered with inconsistent examples (rev-list alone uses foo/bar/baz, origin/HEAD, and A/B), so I wouldn’t put too much weight on that.

The important part though is, that the command is supposed to work with branches (or any ref in general), and remotes are not valid refs on their own.

Upvotes: 2

Related Questions