Git Lesson: How to Use .gitignore and .gitkeep?
Tags: git, tutorial, github, development
Published: 2024-01-16 21:38:16

_This article is translation of the original post from my blog_: 
🇵🇱 [Git: Jak używać .gitignore i .gitkeep?](https://www.flynerd.pl/2024/01/gitignore-i-gitkeep.html) 


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
```

`*` – 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:

```bash
git add "path/to/empty_directory/.gitignore"
git commit -m "Add empty directory"
```
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
```

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
```



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
```

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