Skip to content

Instantly share code, notes, and snippets.

@arthur-flam
Created December 4, 2022 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arthur-flam/7f699ea5e40d886111e6a72a9589b1d9 to your computer and use it in GitHub Desktop.
Save arthur-flam/7f699ea5e40d886111e6a72a9589b1d9 to your computer and use it in GitHub Desktop.
def list_files_at_revision(path: str, revision: str) -> List[str]:
import subprocess
# Check if the path is a file or a directory
# We can use the `git cat-file` command to check if the path is a file
# The `-e` flag indicates that we want to check if the object exists
# If the object exists, then the command will return 0, otherwise it will return a non-zero value
result = subprocess.run(["git", "cat-file", "-e", f"{revision}:{path}"])
if result.returncode == 0:
# The path is a file, so we can use the `git cat-file` command to retrieve its contents
# The `-p` flag indicates that we want to pretty-print the object's contents
result = subprocess.run(["git", "cat-file", "-p", f"{revision}:{path}"], capture_output=True)
output = result.stdout
# The output is the contents of the file, so we can return it as a list with a single element
return [output.decode("utf-8")]
else:
# The path is a directory, so we can use the `git ls-tree` command to list its contents
# The `-r` flag indicates that we want to list the files recursively
# The `-t` flag indicates that we want to include the file's type (e.g. "blob" for regular files)
# The `-z` flag indicates that we want the output to be separated by null characters, rather than newlines
# This allows us to use the `split()` method to split the output into individual lines, even if the filenames contain newlines
result = subprocess.run(["git", "ls-tree", "-r", "-t", "-z", revision, path], capture_output=True)
output = result.stdout
# Split the output into individual lines
lines = output.split(b"\0")
# The first line is a header, so we can ignore it
files = []
for line in lines[1:]:
# Each line has the following format:
# <mode> SP <type> SP <sha1> TAB <file>
# We want to extract the file name, which is the last part of the line
# So we can split the line on the TAB character and take the last part
file = line.split(b"\t")[-1].decode("utf-8")
files.append(file)
return files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment