Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 826
Pi Fisher Avatar asked Oct 23 '25 10:10

Pi Fisher


2 Answers

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)?)

like image 95
torek Avatar answered Oct 27 '25 02:10

torek


If you are using git ls-tree, you might need to filter the output yourself, to grep what you need.

As mentioned in this thread back in 2012:

There are two uses of "pattern" there, and the former is probably OK but the latter is indeed misleading.

Back when we wrote this command, there were two distinct "pathspec" families, and ls-tree belong to the one with "diff" family that did not take anything but "leading path pattern" (the other one from "ls-files" and "grep" family allowed wildcards). Giving a wildcard to the command in the "ls-tree/diff" family was never supported.

If you change ls-tree to use its paths arguments as pathspec, you will break backward compatibility.

like image 34
VonC Avatar answered Oct 27 '25 02:10

VonC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!