Git: Don’t create .gitkeep
files, use .gitignore
instead
Git only tracks files, not directories. It will only create a directory if it contains a tracked file. But sometimes you need to “track” a directory, to ensure it exists for fresh clones of a repository. For example, you might need an output directory called build
.
In this post, we’ll look at two ways to achieve this. First, the common but slightly flawed .gitkeep
technique, then a simpler one using only a .gitignore
file.
The .gitkeep
technique
This technique uses an empty file called .gitkeep
:
build
└── .gitkeep
The empty file ensures that Git creates the directory with minimal cost. Any other filename may be used, as Git doesn’t treat .gitkeep
files any differently.
To set this up, you might create an empty file with touch
:
$ touch build/.gitkeep
Then ignore all files in the directory, except .gitkeep
, by adding patterns in the repository’s .gitignore
file:
/build/*
!/build/.gitkeep
The first pattern ignores everything in the build
directory. The second one then un-ignores the .gitkeep
file, allowing it to be committed.
This technique works, but it has some downsides:
- It requires editing two files.
- If the directory is renamed,
.gitignore
needs updating, which is easy to miss. .gitkeep
is not a name recognized by Git, so there’s no documentation on it, potentially confusing other developers.
There’s a better way that doesn’t have these flaws.
The better .gitignore
technique
This technique uses only a short .gitignore
file inside the directory:
build
└── .gitignore
The .gitignore
file has these contents:
*
!.gitignore
The first pattern ignores all files in the directory. The second one then un-ignores the .gitignore
file, so it can be committed.
You can create this file with echo
and file redirection:
$ echo '*\n!.gitignore' > build/.gitignore
When you add and commit the directory, Git will pick up on the .gitignore
file first, skipping other files within the directory:
$ git add build
$ git status
On branch main
Changes to be committed:
new file: build/.gitignore
$ git commit -m "Track build directory"
[main 1cc9120] Track build directory
1 file changed, 2 insertions(+)
create mode 100644 build/.gitignore
The directory is now “tracked” with a single, standard file that will work even after renames.
Read my book Boost Your Git DX for many more Git lessons.
One summary email a week, no spam, I pinky promise.
Related posts:
- Git: Output the top-level directory of the current repository
- Git: Output just the current branch name
- Git: How to add and remove execute permissions
Tags: git