Git: list checked-in symlinks - Adam Johnson (original) (raw)

2025-05-19Many links.

Git supports storing symbolic links (symlinks) in your repository, which are filesystem links that point to another file or directory. These are great for when you want to have the same file at multiple locations in your repository, such as some configuration file that is used for multiple sub-projects. But how can you list all the symlinks in your repository?

The answer is to use git ls-files to list all tracked files, with its -s (--stage) option to output a table like:

$ git ls-files --stage 100644 509ea36c2702e17436046c7f5b5d1afab89b654f 0 CHANGELOG.md 120000 0e01b4308c1424d861f0af570038bfd5209c0691 0 README.md 100644 98d03acc98edaf728a186256b5cc25de43447055 0 docs/README.md

There are four columns:

  1. Mode bits
  2. SHA hash of the object
  3. Stage number
  4. File name

The mode bits describe the file permissions, and for symlinks, Git uses the special value 120000. So we can filter this output to select filenames where the mode bits have that value:

$ git ls-files --stage | awk '$1 == "120000" { print $4 }' README.md

That command uses AWK to filter the output with a condition that the first column ($1) is equal to 120000, then prints the fourth column ($4), which is the filename.

Handle newline-containing file names

The above command will misbehave in the incredibly rare case that your repository has a file with a name that contains a newline character (\n). In that case, the output of git ls-files --stage will not be guaranteed to be a single line per file, and the AWK command will not work as expected.

To solve this, use the -z option of git ls-files to separate filenames with a null character (\0) instead of a newline, and switch awk for your favourite programming language that can handle null-terminated strings.

Avoid file listing commands

An alternative solution would be to use a file listing command to list symlinks in the current directory. For example, using find:

$ find . -type l ./README.md

However, such commands will include any symlinks that are not tracked by Git, such as those created by a build process, and you probably don’t want to see those.

Fin

May you find the links you’re looking for,

—Adam


🎉 My book Boost Your Git DX was updated on January 28th!


One summary email a week, no spam, I pinky promise.

Related posts:

Tags: git