DEV Community

Cover image for Git Lesson: How to Use .gitignore and .gitkeep?
Rita {FlyNerd} Lyczywek
Rita {FlyNerd} Lyczywek

Posted on

Git Lesson: How to Use .gitignore and .gitkeep?

This article is translation of the original post from my blog:
🇵🇱 Git: Jak używać .gitignore i .gitkeep?

If you work with Git and have your repositories on platforms like Github, Gitlab, Bitbucket, etc., you probably come across "dot files" such as .gitignore or .gitkeep. What are they and how do they differ from each other? I'll try to explain briefly.

What is a .gitignore file?

While working with a Git repository, you'll quickly notice that some files and folders are unnecessary. You might encounter files automatically added by your editor, temporary files, or files with environment variables that you definitely don't want to share publicly.

Here comes into play a special file named .gitignore, usually placed directly in the main directory of our repository.

The .gitignore file allows us to specify and exclude from the repository those elements that are unnecessary, be it configuration files, temporary files, or personal data. In other words:

In Git, the .gitignore file is used to specify which files or directories the change tracking process should ignore.

Thanks to .gitignore, developers can avoid accidentally adding unwanted files to the repository. Our repository remains clean and organized, and the change history is not cluttered with irrelevant files.

To ensure files are ignored, one must follow the conventions found in Git's official documentation as Patterns.

For example, by adding the pattern *.log to the .gitignore file, we prevent the tracking of any log files.

Use gitignore templates

Here you can find ready-made .gitignore templates for various technologies and languages such as Python, Java, Kotlin, Go, and many others: https://github.com/github/gitignore/tree/main.

If you can't find something in this project, someone has surely already prepared such a template. Just need to search well 😉

It's also worth noting that there are two approaches to using .gitignore files:

  • 1 – Each repository should contain a standardized .gitignore file that ignores all language-specific files, operating system files, and tools used by its developers (e.g., pycache), as well as any files removed for business reasons (e.g., data files, files too large for the repository).
  • 2 – The developer should be responsible for their own personal .gitignore file, which will ignore all unnecessary repository files related to the languages and tools they are currently using. If there is a .gitignore file in the repository, it is there to accommodate logic specific to that particular repository.

What is a .gitkeep file?

Unlike .gitignore, .gitkeep is not a part of Git's official documentation. It's an unofficial convention used by Git users to track empty directories. Git, by default, does not track empty directories – it doesn't add them to our repository. .gitkeep is a way to circumvent this limitation.

In short, we want to convey to Git:

"Hey, this folder is important, even if it's empty for now".

Since it is a convention rather than a part of the Git tool, it's worth noting that the name is not as important as the location. The file used to track an empty directory can have any name – it doesn't necessarily have to be .gitkeep. You can choose names like .empty, or simply .keep, or any other. It's important to place this file directly in the empty directory that we want to track in the repository. This way, it's no longer empty 😉

.gitignore vs .gitkeep

On one hand, .gitkeep, an elegant and simple solution for tracking empty directories. On the other hand, .gitignore, which besides its primary role, can also be used for this purpose. The choice depends on the context of the project.

How to track an empty folder through gitignore?

Well, you can create a .gitignore file in an empty folder, then add the following lines according to the pattern from the documentation:

# Ignore everything in this directory
*
# But do not ignore this .gitignore file
!.gitignore
Enter fullscreen mode Exit fullscreen mode

* – the asterisk means that all files in the directory are ignored, except for the .gitignore file, which we excluded using the ! exclamation mark, corresponding to negation. Since the .gitignore file is tracked, the entire directory will also be tracked by Git.

Then just add this change to Git, as usual, and commit:

git add "path/to/empty_directory/.gitignore"
git commit -m "Add empty directory"
Enter fullscreen mode Exit fullscreen mode

Importantly, this solution will also work, not just for an empty folder!

In this way, we can add to the repository as an empty directory, a folder that contained files, but for some reason, we do not want to track those files. The folder in Git is not empty – it contains a .gitignore file inside ;)

How-To track an empty folder with .gitignore and .gitkeep when the folder contains some local files?

Does it make sense? Yes, although it's not often needed.

This method is useful if:

  • You want a directory in the repository, but without the files inside it, e.g., a system log folder, but without the log files that are only of interest locally.
  • You want to send the directory structure to the Git repository before there are any files in it, e.g., they will be added later, but you want to define the structure now.
How to track a directory that already has files locally, but should remain empty remotely?

So, the previous point partly answered this question, but maybe we don't like that solution because we have two .gitignore files and we want to differentiate these files.

In the folder, create a .gitkeep file to track the folder in Git, and add lines to the .gitignore file to ignore all files inside our folder.

Step by Step

Step 1. Assume we have a logs folder in our project. This folder contains various system files that we don't want to add to our remote repository.

app
│   .gitignore
│   index.html
│   script.js
│
├───images
│
└───logs
    │   2452321.log
    │   2453111.log
Enter fullscreen mode Exit fullscreen mode

Step 2. In the logs folder, create an empty .gitkeep or .keep file (the name is just a convention).

app
│   .gitignore
│   index.html
│   script.js
│
├───images
│
└───logs
    │   .gitkeep
    │   2452321.log
    │   2453111.log
Enter fullscreen mode Exit fullscreen mode

Step 3. Now, if you want to track the folder, but not its content – which makes sense for logs, add the following content to the .gitignore file:

# Ignore everything inside the logs folder
logs/*
# Do not ignore the .gitkeep file in the logs folder
!logs/.gitkeep
Enter fullscreen mode Exit fullscreen mode

Tada 🎉 We can commit these changes and add them to the repository. Our files inside the logs folder will not appear online.

Top comments (14)

Collapse
 
kurealnum profile image
Oscar

Awesome article! It's worth noting that if you create a file, then decide that you want to .gitignore that file, you can use git rm --cached myawesomefile.txt.

This removes the file from the cache, and assuming that your .gitignore is correct, git will then not allow this file back into the cache.

Collapse
 
moopet profile image
Ben Sinclair

I've never liked using .gitkeep when there are ways of using .gitignore to do the same thing without requiring a hack. Usually, though, my approach is to not store empty directories at all!

Collapse
 
karlkras profile image
Karl Krasnowsky

so you know of a way using .gitignore that will allow you to track empty directories? Please tell.

Collapse
 
moopet profile image
Ben Sinclair

Yes, instead of naming your empty file, ".gitkeep", name it ".gitignore" :)

If you want to ensure the directory stays empty, put a * in it (and possibly ! .gitignore, I can't remember off the top of my head).

Using ".gitkeep" means you save an unrelated file to your repository and does not prevent you from accidentally adding whatever generated files end up under that directory in your local working version.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

This sentence reads like you probably changed it a bunch while editing and left an extra word in by accident :D

Collapse
 
ritaly profile image
Rita {FlyNerd} Lyczywek

thanks! just some translation oversight :D fixed!

Collapse
 
ahmadswalih profile image
Ahmad Swalih

Cool, I knew about .gitignore, but I didn't know about .gitkeep until now.

Collapse
 
ricardogesteves profile image
Ricardo Esteves

Great! Nice article @ritaly .

Collapse
 
morphzg profile image
MorphZG

Thanks for sharing. That is high quality content.

Collapse
 
jnareb profile image
Jakub Narębski

You can use empty .gitignore file instead of non-standard .gitkeep.

Collapse
 
ritaly profile image
Rita {FlyNerd} Lyczywek

yes, I mention that above, that we can track an empty folder through gitignore - it also works if you prefer that way

Collapse
 
blackgirlbytes profile image
Rizèl Scarlett

I didn't know about gitkeep. Thank you!

Collapse
 
dipayansukul profile image
Dipayan Sukul

Nice article elaborating the details

Collapse
 
matin192hp profile image
matin HP

Interesting :)

Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more