19

I am looking for a way to have output in the same manner as ls-tree, but of my working directory. Whenever I run git ls-tree . it says fatal: Not a valid object name .

2
  • git ls-files probably with -m?
    – Mikel
    Commented Apr 10, 2012 at 4:37
  • 2
    git ls-tree -r HEAD Commented Aug 30, 2016 at 3:15

3 Answers 3

28

git ls-tree only works with git refs, e.g. ls-tree HEAD or ls-tree 1.9.1

Try git ls-files. You probably want the -s and/or -m flags.


As you point out, git ls-files -s will list the files in the index (i.e. files that have been staged).

In theory, you could mess with the index, run git ls-files -s, then try restore it, e.g.

git commit
git add .
git ls-files -s
git reset .
git reset --soft HEAD^

Seems right, and worked in a simple test, but could eat all your files.

2
  • Thank you. I think that properly speaking, what I asked is impossible. The reason is that there is no hashed object for files in the working directory. For the index, however, there are of course hashed objects as you pointed out by suggesting the -s flag. This isn't exactly the same output, but I don't want to bother remaking the functionality of other git commands. :) Commented Apr 10, 2012 at 21:58
  • It seems -m doesn't have the desired effect, as you imply. I had a go a listing the working directory rather than the index. See updated answer. And test before doing it on your real data. :-)
    – Mikel
    Commented Apr 11, 2012 at 1:56
3

This is similar to @mikel's answer, but uses git stash create and ls-tree, as requested by the OP. Also avoids using git reset, which is more likely to break things for the inexperienced user.

This however only works for tracked files.

git ls-tree `git diff --quiet && echo HEAD || git stash create ls-tree` 

This will leave a dangling commit, which will should eventually be removed by git gc. (Actually two dangling commits.) Of course you could search for dangling commits containing ls-tree, but I haven't found a simple way to do so (at least not without quite a bit of sed and grep magic - suggestions welcome ).

Explanation

git ls-tree needs a hash. If the tree is clean (git diff --quiet returns 0) one can use HEAD. If it isn't, git stash create will create a commit and return it's hash.

Untracked

Unfortunately git stash create does not support -a/-u or other flags. Thus it's not possible to show the hashes of untracked files. Getting their information is a bit more complicated:

git stash -a
git ls-tree stash
git ls-tree stash^3
git stash pop

This will first show tracked files (git ls-tree stash) and then untracked files (git ls-tree stash^3). torek provides a good explanation why stash^3 is needed.

1

Tried to find something which is not touching the git repo.

This one is not git only and depends on linux like 'grep'

#from root of repo dir
git ls-tree -r HEAD 
#other dirs
git ls-tree -r HEAD | grep <relative_path_to_repo_root>/
# eg
git ls-tree -r HEAD | grep src/

Also found following (git only) working in subdirectories of repo root

git ls-tree -r --full-name HEAD

However man page (man git-ls-tree) is irritating git logic

   --full-name
       Instead of showing the path names relative to the current working directory, show the full path names.

   --full-tree
       Do not limit the listing to the current working directory. Implies --full-name.

Not the answer you're looking for? Browse other questions tagged or ask your own question.