18

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 .

mfaani
  • 33,269
  • 19
  • 164
  • 293
Alexander Bird
  • 38,679
  • 42
  • 124
  • 159

3 Answers3

27

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.

mfaani
  • 33,269
  • 19
  • 164
  • 293
Mikel
  • 24,855
  • 8
  • 65
  • 66
  • 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. :) – Alexander Bird Apr 10 '12 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 Apr 11 '12 at 01: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.

Morty
  • 2,889
  • 2
  • 19
  • 28
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.
grenix
  • 623
  • 7
  • 15