linuxbashgitgit-ls-filesgit-ls-remote

Why do git ls-remote and git ls-files fail with some relative paths?


Suppose I have a git repo at ~/dev/company/products/company-common. From several other filesystem location I try to execute ls-files or ls-remote on that repo. All work, except for the last one. What could be a reason the last one doesn't work?

(N.B. I have a 2-line bash prompt):

user@machine:products (~/dev/company/products)
$ git ls-remote company-common HEAD 
f25b342b384de1b82cb67b6f530303b4fac37ff0    HEAD

user@machine:products (~/dev/company/products)
$ git ls-remote ../products/company-common HEAD
f25b342b384de1b82cb67b6f530303b4fac37ff0    HEAD

user@machine:products (~/dev/company/products)
$ git ls-remote ../../company/products/company-common HEAD
f25b342b384de1b82cb67b6f530303b4fac37ff0    HEAD

user@machine:products (~/dev/company/products)
$ cd gui

user@machine:gui [master] (~/dev/company/products/gui)
$ git ls-remote ../company-common HEAD
f25b342b384de1b82cb67b6f530303b4fac37ff0    HEAD

user@machine:gui [master] (~/dev/company/products/gui)
$ cd dummy/

user@machine:dummy-application [master] (~/dev/company/products/gui/dummy)
$ git ls-remote ../../company-common HEAD
fatal: '../../company-common' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

None of the directories involved is a symlink. I've only shown one line of output from each command (except for the last one)


Solution

  • The interesting thing is that git ls-remote works at all here.

    The first argument you pass to git ls-remote should be a URL (https://host/..., ssh://git@github.com/..., and so on) or the name of a remote (typically origin). However, Git accepts local file system paths in place of file://... URLs.

    When Git does that last trick, it seems to do it somewhat weirdly and inconsistently. In my experiments I got somewhat different behavior, but it was still weird.

    Aside from academic curiosity and/or possible internal bugs, you should just stop using git ls-remote here and use git rev-parse directly. If you want to get a revision hash ID from the current repository, just run git rev-parse:

    git rev-parse HEAD
    

    for instance. If you want to get one from some other Git repository in file system location X, use:

    git -C X rev-parse HEAD
    

    for instance. This behaves well—unlike the odd results you and I are seeing for git ls-remote here, the -C argument makes Git internally chdir for the duration of the rev-parse—and runs faster and is simpler and easier to deal with. It works for git ls-files and all other Git commands too, since it is implemented in the git front end.