gitgit-ls-files

git ls-files for different branch


I want to find all markdown files in the base directory of a specified branch. git ls-files was suggested to me, but the documentation doesn't mention specifying a branch. I want to be able to do this without checking out that branch. Can this be done?


Solution

  • git ls-files examines files in the index or the work-tree (or both). Since the current index and work-tree contents generally reflect the current commit as extracted from the tip of the current branch, it won't work this way. But there is a workaround.

    As VonC notes, git ls-tree examines a tree object, such as that stored in a commit. However, git ls-tree does not accept pathspec arguments such as **/*.md.

    The workaround is to read the commit of interest into a temporary index. To do that cleanly, use mktemp to make a temporary file, then remove the temporary file and use git read-tree to re-create the file as valid a temporary index containing the image of the commit you wish to inspect, which you can then inspect with git ls-files. For example:

    $ cd git
    $ sh -c 'export GIT_INDEX_FILE=$(mktemp); rm $GIT_INDEX_FILE; git read-tree e83c5163316f89bfbde7d9ab23ca2e25604af290; git ls-files -- "*.h" "**/*.h"; rm $GIT_INDEX_FILE'
    cache.h
    $ sh -c 'export GIT_INDEX_FILE=$(mktemp); rm $GIT_INDEX_FILE; git read-tree origin/master; git ls-files -- "*.md"; rm $GIT_INDEX_FILE'
    .github/CONTRIBUTING.md
    .github/PULL_REQUEST_TEMPLATE.md
    README.md
    contrib/vscode/README.md
    

    (Note: the sh -c 'export ...; cmd1; cmd2; cmd3' is all required, although if you're already using a POSIX-compatible shell you can replace sh -c with parentheses for a subshell. We need the environment variable GIT_INDEX_FILE to stay set for just those commands. If your mktemp has -u, consider using that instead of the first rm. See also How portable is mktemp(1)?)