---
title: "Git: list files at a given commit with ls-tree"
url: https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs
source_url: https://adamj.eu/tech/2026/08/07/git-list-files-at-commit
type: article
source: "Adam Johnson"
published: 2026-08-06T23:24:26.273Z
updated: 2026-08-06T23:24:52.093Z
tags: ["git", "cli", "version-control"]
reading_time: 2
upvotes: 0
comments: 0
language: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Git: list files at a given commit with ls-tree

**[Adam Johnson](https://daily.dev/sources/adamj)** · 2 min read · 0 upvotes · 0 comments

## Summary

A concise guide to using `git ls-tree` with the `-r` and `--name-only` flags to list all files in a repository as they existed at any given commit. Covers the difference between `git ls-tree` (reads from Git's object database, works on any commit) and `git ls-files` (reads from the index, limited to current checkout). Also explains how to restrict output to a specific directory using path arguments, and how to handle file names containing newlines when scripting by using the `-z` flag for null-delimited output.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://adamj.eu/tech/2026/08/07/git-list-files-at-commit>

## Questions this post answers

### How do I list all files in a Git repository as they were at a specific commit without checking it out?

Use `git ls-tree --name-only -r <commit>`, replacing `<commit>` with any commit reference — a SHA, branch name, tag, or relative reference like `@~`. The `-r` flag recurses into subdirectories, and `--name-only` omits the mode bits, object type, and SHA hash. Unlike `git ls-files`, `git ls-tree` reads directly from Git's object database and works on any commit.

_Developers navigating Git history and commit archaeology share tips like these on daily.dev._

### What is the difference between git ls-tree and git ls-files?

`git ls-files` reads from the index (staging area) and can only report on the currently checked-out state, including any staged changes. `git ls-tree` reads from Git's object database and can list files at any commit without checking it out. Passing `@` (HEAD) to `git ls-tree` makes the two roughly equivalent, except for staged changes.

_Teams standardizing Git workflows find comparisons like this on daily.dev._

### How do I handle file names with newlines when scripting git ls-tree?

Use the `-z` flag to separate entries with null characters instead of newlines, which also prevents quoting of unusual file names. Pipe the output to `xargs -0 -n1` for safe per-entry processing: `git ls-tree --name-only -z -r HEAD | xargs -0 -n1 echo`. Without `-z`, `git ls-tree` quotes file names containing newlines, which can break naive line-by-line parsing.

_Developers writing Git automation scripts encounter edge cases like this — daily.dev surfaces the practical details._

## Similar posts on daily.dev

- [Git: count files in a repository](https://daily.dev/posts/git-count-files-in-a-repository-wjqf1zi7u) · Adam Johnson · 2 upvotes · 0 comments

---

Tags: [#git](https://daily.dev/tags/git), [#cli](https://daily.dev/tags/cli), [#version-control](https://daily.dev/tags/version-control)

[View this post on daily.dev](https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs)
