Using command line git, how can I make git show a list of the files that are being tracked in the repository?
If you want to list all the files currently being tracked under the branch master
, you could use this command:
git ls-tree -r master --name-only
If you want a list of files that ever existed (i.e. including deleted files):
git log --pretty=format: --name-only --diff-filter=A | sort - | sed '/^$/d'
The files managed by git are shown by git ls-files
. Check out its manual page.
ls
...or ls -R
git ls-tree
- it is relative to the pwd
.
The accepted answer only shows files in the current directory's tree. To show all of the tracked files that have been committed (on the current branch), use
git ls-tree --full-tree --name-only -r HEAD
--full-tree makes the command run as if you were in the repo's root directory.
-r recurses into subdirectories. Combined with --full-tree, this gives you all committed, tracked files.
--name-only removes SHA / permission info for when you just want the file paths.
HEAD specifies which branch you want the list of tracked, committed files for. You could change this to master or any other branch name, but HEAD is the commit you have checked out right now.
This is the method from the accepted answer to the ~duplicate question https://stackoverflow.com/a/8533413/4880003.
--full-tree
, this gives you all committed, tracked files". Does that mean all files that have ever been committed since the beginning of the repo, or is there some cutoff? The currently accept answer includes a git log
command whose output is a couple thousand lines longer than your command. I'm trying to hunt down large files that were committed almost a decade ago so I can prune them from history.
You might want colored output with this.
I use this one-liner for listing the tracked files and directories in the current directory of the current branch:
ls --group-directories-first --color=auto -d $(git ls-tree $(git branch | grep \* | cut -d " " -f2) --name-only)
You might want to add it as an alias:
alias gl='ls --group-directories-first --color=auto -d $(git ls-tree $(git branch | grep \* | cut -d " " -f2) --name-only)'
If you want to recursively list files:
'ls' --color=auto -d $(git ls-tree -rt $(git branch | grep \* | cut -d " " -f2) --name-only)
And an alias:
alias glr="'ls' --color=auto -d \$(git ls-tree -rt \$(git branch | grep \\* | cut -d \" \" -f2) --name-only)"
glr
alias you provided looked a bit weird so I made a version more consistent with the format of the first alias you provided: alias glr='ls --color=auto -d $(git ls-tree -rt $(git branch | grep \* | cut -d " " -f2) --name-only)'
. Tested with git version 2.20.1
on Debian 10.
Building on the existing answers, you can use tree
to view it a little prettier:
git ls-tree --full-tree --name-only -r HEAD | tree --fromfile .
You probably want to paginate this:
git ls-tree --full-tree --name-only -r HEAD | tree -C --fromfile . | ${PAGER:-less}
This certainly deserves a place as tree
alias in the git config :)
Success story sharing
git
does not version directories directly. Instead it stores files and their paths.ls-tree
will output all the versioned files. To better understand this distinction, try staging an empty directory togit
. The empty directory will never show up in the staged changes. The only way to version such an empty directory is to actually version a file under the directory. For use cases where you need such an empty placeholder directory in version control, you can create a dummy file under the directory, and version that. I hope the explanation is clear.ls-tree master
doesn't show the tracked files in staging area.git log --pretty=format: --name-only --all | sort -u | sed '/^$/d'