<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs" -->

---
title: Git: list files at a given commit with ls-tree | daily.dev
description: 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...
canonical: https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Git: list files at a given commit with ls-tree | daily.dev
og:description: 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...
og:url: https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs
og:image: https://api.daily.dev/og/posts/xjMNKX5HS.png
og:image:alt: Git: list files at a given commit with ls-tree
og:image:width: 1200
og:image:height: 630
og:locale: 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 · 1 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 the files in a git repository as they existed at a specific commit?

Run git ls-tree --name-only -r <commit>, replacing <commit> with a SHA, branch name, tag, or relative reference like @~. This reads directly from git's object database, so it can list files at any commit without checking it out, unlike git ls-files which only reflects the current index.

_daily.dev surfaces practical git tips like this for developers scripting repository inspections._

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

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

_Understanding subtle git command differences like this helps developers avoid scripting mistakes, a focus daily.dev supports._

### How do I safely handle file names containing newline characters when scripting with git ls-tree?

Use the -z option with git ls-tree to separate entries with null characters instead of newlines, avoiding quoting issues. For example: git ls-tree --name-only -z -r HEAD | xargs -0 -n1 echo. Without -z, file names containing newlines get quoted, which can break naive line-based parsing.

_daily.dev helps developers building reliable git scripts catch edge cases like newline-containing file names._

## Similar posts on daily.dev

- [gitdatamodel Documentation](https://daily.dev/posts/gitdatamodel-documentation-yvvl6xej7) · Lobsters · 1 upvotes · 0 comments
- [I Built Git from Scratch to Finally Understand What I've Been Using for Years](https://daily.dev/posts/i-built-git-from-scratch-to-finally-understand-what-i-ve-been-using-for-years-3wx3ymzn1) · DEV · 23 upvotes · 0 comments
- [I made my own git](https://daily.dev/posts/i-made-my-own-git-fwqs5dx1b) · Hacker News · 77 upvotes · 4 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)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"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","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs"},"datePublished":"2026-08-06T23:24:26.273Z","dateModified":"2026-09-13T18:30:31.999Z","description":"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...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c0196792ee65b0acfd2b8875b9f08c2c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/c0196792ee65b0acfd2b8875b9f08c2c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Adam Johnson","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Adam Johnson","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/bf70f4401c284aa5b628d1966029342c","url":"https://daily.dev/sources/adamj"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"git,cli,version-control","timeRequired":"PT2M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Adam Johnson","item":"https://daily.dev/sources/adamj"},{"@type":"ListItem","position":3,"name":"Git: list files at a given commit with ls-tree"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/git-list-files-at-a-given-commit-with-ls-tree-xjmnkx5hs#faq","mainEntity":[{"@type":"Question","name":"How do I list all the files in a git repository as they existed at a specific commit?","acceptedAnswer":{"@type":"Answer","text":"Run git ls-tree --name-only -r <commit>, replacing <commit> with a SHA, branch name, tag, or relative reference like @~. This reads directly from git's object database, so it can list files at any commit without checking it out, unlike git ls-files which only reflects the current index. daily.dev surfaces practical git tips like this for developers scripting repository inspections."}},{"@type":"Question","name":"What is the difference between git ls-tree and git ls-files?","acceptedAnswer":{"@type":"Answer","text":"Git ls-files reads from the index (staging area) and only reports the currently checked-out state, while git ls-tree reads directly from the object database and can list files at any commit without checking it out. Passing @ (HEAD) to ls-tree makes the two roughly equivalent, except for staged changes. Understanding subtle git command differences like this helps developers avoid scripting mistakes, a focus daily.dev supports."}},{"@type":"Question","name":"How do I safely handle file names containing newline characters when scripting with git ls-tree?","acceptedAnswer":{"@type":"Answer","text":"Use the -z option with git ls-tree to separate entries with null characters instead of newlines, avoiding quoting issues. For example: git ls-tree --name-only -z -r HEAD | xargs -0 -n1 echo. Without -z, file names containing newlines get quoted, which can break naive line-based parsing. daily.dev helps developers building reliable git scripts catch edge cases like newline-containing file names."}}]}
```

