What are the differences between .gitignore and .gitkeep?
Asked Answered
C

7

2593

What are the differences between .gitignore and .gitkeep? Are they the same thing with a different name, or do they both serve a different function?

I don't seem to be able to find much documentation on .gitkeep.

Chaotic answered 29/8, 2011 at 12:11 Comment(0)
D
4502

.gitkeep isn’t documented, because it’s not a feature of Git.

Git cannot add a completely empty directory. People who want to track empty directories in Git have created the convention of putting files called .gitkeep in these directories. The file could be called anything; Git assigns no special significance to this name.

There is a competing convention of adding a .gitignore file to the empty directories to get them tracked, but some people see this as confusing since the goal is to keep the empty directories, not ignore them; .gitignore is also used to list files that should be ignored by Git when looking for untracked files.

Derogatory answered 29/8, 2011 at 12:20 Comment(25)
Informative. I was expecting .gitkeep to flag those .gitignore files that you wanted to keep, as distinct from the other .gitignore 'trash' that should/could be deleted after a branch checkout.Trinitytrinket
Wouldn't it be a better solution to put a README file in the otherwise empty subdirectory that contains a bit of information about what that subdirectory is going to be used for? It seems confusing to have a file called .gitkeep that is not actually part of git.Syllabize
@Syllabize many times, the path of the empty directory (e.g. names of the folders) is sufficient to express it's purpose (examples: templates/cache, upload/thumbs etc). In these cases putting a readme into each of these feels redundant.Culpepper
people who want to keep track of empty directories should be indicating in a README that the directory has to be created or creating the directories using their build tool or whatever tool(s) require the directory to exist ;/Chaplet
@tamouse, @omouse: A .gitignore file with two lines: * and !.gitignore is more than enough clarity to convey what is going on. If more elaboration is needed, add a comment to the top of the file using the # syntax.Vernation
@Syllabize putting a README file is the best solution to make git to track empty folders.Lindbergh
It's worth to notice that the popular Rails framework has slightly changed this convention using .keep files instead of .gitkeep to preserve these empty folders, since git is not the only source control system that does not track empty folders. More details here: github.com/rails/rails/issues/2800Spheno
I just call my file .empty. I guess that makes more sense, at least for me.Fanti
I agree with @Droogans. I don't believe that .gitignore is confusing. Quite the opposite, it means you want to keep the folder AND ignore its contents. .gitkeep doesn't prevent versioning disposable files by accident.Semination
Personally a file named .gitkeep with text inside (as would be found in a readme) makes most sense to me. The name .gitkeep is immediately obvious once you know the convention, then you can open the file if curiosity strikes. README assumes too general a purpose.Neils
I feel like there are two use cases we're arguing about here. If there's a folder that will eventually be full of tracked items, .gitkeep makes more sense than .gitignore, since you're not ignoring anything, you're just keeping the folder there. However, if the folder is never going to have tracked files in it, a .gitignore ignoring those files makes the most sense.Privett
.keep is also a more general empty file, non-specific to git. I use this and see it around.Dominant
My release Engineer added README inside some directories in order to keep track of these directories. Now the Android Project wont build if the README files are not deleted... Just an FYI...Precessional
@RudolfOlah that would be a terrible, .gitkeep are simple and efficient way to track empty directoriesGraphitize
@Graphitize .keep and .gitkeep work however my opinion is unchanged, the build tool and readme should reflect what new directories will be created.Chaplet
I try to mention empty directories list into .gitkeep file but it will not track empty directories, Only folder track where .gitkeep file exist. why so ?Chlor
@pardeep please read the answer carefully. .gitkeep does literally nothing. git does not read its contents to decide what to keep, it only tracks the file as a regular file.Derogatory
If I saw a README in the dir I'm looking at I would have just deleted it instead of coming here.Flotation
As alluded to by @TerNovi, README files are prone to interfere with automation. Using hidden .files should be preferred to extraneous README files.Heptahedron
I've recently published a tiny utility CLI to help with recursively creating and deleting .gitkeep files. You can find it here: pypi.org/project/gitkeep2. You can simply install it by running pip3 install gitkeep2 and then use it by running gitkeep path/to/foo. It supports recursivenes and adding messages to the .gitkeep files in order to make them self-documented.Sair
@Sair You should call your tool "git-keep", not "gitkeep", because then git can find it automatically. It looks in the $PATH for tools beginning "git-" followed by the command you use, i.e. "git keep path/to/dir". This is how you write extensions to git.Dynamo
@Junaid I’ve rolled back your edit because it was gratuitous: it didn’t improve the content nor readability, and in fact misuses a formatting feature to give the false impression that the first paragraph is a quote. Furthermore, your addition of “tl;dr” is nonsensical: the quoted part isn’t a summary of the following, contrary to what “tl;dr” indicates. Please don’t perform such gratuitous edits.Quirites
The purpose was to only bring the answer to the top again because it was indeed useful for me. I didn't want to take any sort of credit & the tl;dr is just a thing I use in my own answers so I used it, that's it. Now that the post is at the top, so I guess mission accomplished. Thanks for reverting the changes. FYI: your words were a little too harsh :DDerrik
Back in my day the file was named 'empty'Divestiture
My summary of these comments: the best solution is a .gitkeep file with a short explanation in it. This makes a hidden file, prevents confusion, does not break builds, contains documentation, and is not redundant.Forage
C
470

.gitkeep is just a placeholder. A dummy file, so Git will not forget about the directory, since Git tracks only files.


If you want an empty directory and make sure it stays 'clean' for Git, create a .gitignore containing the following lines within:

# .gitignore sample
# Ignore all files in this dir...
*

# ... except for this one.
!.gitignore

If you desire to have only one type of files being visible to Git, here is an example how to filter everything out, except .gitignore and all .txt files:

# .gitignore to keep just .txt files
# Filter everything...
*

# ... except the .gitignore...
!.gitignore

# ... and all text files.
!*.txt
Conduit answered 20/7, 2012 at 13:2 Comment(7)
I like this practice myself. If there was source code in these directories there would be no need for .gitkeep and general it is temp/cache/user content which during testing would be generated anyways causing you to have to also .gitignore those filesHydrated
Why do you need ! in front of .gitignore ? Is that in order to escape the dot ?Sartorius
@Sartorius - No, the ! negates the following part, like it usually does in programming.Conduit
There is no need to put !.gitignore in a git ignore file, either add the file then edit it, or force add it with appropriate contents ("*" to ignore everything, or nothing to simply make sure the folder exists) further example.Paramagnet
From your link: Since the git ignore file is already in the repo it is not necessary to not-ignore it - it is already tracked. ------ If it is not, and you do not do a forceful add, you might forget about it. In trivial cases, no problem, but if it is a bigger file you might be upset. Using !.gitignore prevents you from shooting yourself in your foot. I prefer it, having burned myself in the past.Conduit
(..)A dummy file, so git will not forget about the directory, since git tracks only files.(..) well.. in Linux world everything is a file. And let don't forget that git was created by guy who create Linux in the first place.Genotype
It need not be empty. I've found it useful to make the .gitkeep file store text explaining why this directory is important to keep in source control. I've written a tiny utility that makes creating self-documented .gitkeep files very easily —e.g. gitkeep path/to/foo -m "This is where we'll later add X stuff." you can install it with pip3 install gitkeep2 and find it at pypi.org/project/gitkeep2Sair
S
150
.gitignore

is a text file comprising a list of files in your directory that git will ignore or not add/update in the repository.

.gitkeep

Since Git removes or doesn't add empty directories to a repository, .gitkeep is sort of a hack (I don't think it's officially named as a part of Git) to keep empty directories in the repository.

Just do a touch /path/to/emptydirectory/.gitkeep to add the file, and Git will now be able to maintain this directory in the repository.

Shallop answered 29/8, 2011 at 12:21 Comment(5)
You can have as many .gitignores as you want, if you do not want to specify the full path to every folder every time.Conduit
I try to mention empty directories list into .gitkeep file but it will not track empty directories, Only folder track where .gitkeep file exist. why so ?Chlor
.gitkeep does not work like .gitignore. It's not a list of directories to keep around. It is merely an empty file that lives in the directory you want to keep around. It can be named anything you want .keep, etc. So you can have a directory like /foo/bar and the gitkeep file will be /foo/bar/.gitkeepShallop
@Conduit how would having multiple .gitignores save you from specifying the full path to every folder every time? I think I'm missing something obvious.Shrewsbury
@Shrewsbury Assuming you have /abc/def/somefile. If your git is in /abc/, you would have to ignore ./dev/somefile. If you place your gitgnore inside /abc/def, then you only need to ignore ./somefileFlavius
I
8

Many people prefer to use just .keep since the convention has nothing to do with git.

Indue answered 16/10, 2020 at 20:41 Comment(3)
arguably, the reason for the convention is almost explicitly because of gitQuantifier
@Quantifier Perforce also needs files present to track a folder.Zicarelli
I downvoted this answer, because I think doing that is a big downgrade to readabiliy. Even if it is not a git feature, you add that file solely because of git. A file called "keep" can easily be mistaken for something important when you start to add other stuff to the folder and it's als not easy to google what that is, if you have no idea.Mayor
Y
5

A file .gitignore is used to tell Git which files and folders it should ignore. Often, these files are build artefacts, temporary files, or other types of files that don't belong in the repository. Git will disregard any directory or file that fits a pattern in the .gitignore file.

Example:

# Ignore .DS_Store files
.DS_Store

# Ignore build artifacts
build/

# Ignore log files
*.log

Contrarily, a .gitkeep file is utilised in Git to maintain a directory that would otherwise be empty. Git does not by default track empty folders, thus you must add a .gitkeep file to that directory if you wish to keep it in your repository. The filename is more significant than the file's actual contents.

Example of .gitkeep file

# This file is used to keep the directory empty in Git

In summary. The .gitignore command is used to tell Git which files and folders to ignore. To maintain a Git directory that would otherwise be empty, use .gitkeep. They are distinct from one another and have different functions.

Yoon answered 1/3, 2023 at 12:3 Comment(1)
Important to note: .gitkeep is not a git feature. This just became common practice. You can call the file whatever you want, because as long as there is at least on file in a folder, the folders will be tracked too.Mayor
S
2

This is not an answer to the original question "What are the differences between .gitignore and .gitkeep?" but posting here to help people to keep track of empty dir in a simple fashion. To track empty directory and knowling that .gitkeep is not official part of git,

enter image description here

just add a empty (with no content) .gitignore file in it.

So for e.g. if you have /project/content/posts and sometimes posts directory might be empty then create empty file /project/content/posts/.gitignore with no content to track that directory and its future files in git.

Satin answered 21/11, 2020 at 14:10 Comment(6)
I disagree. The fact that .gitkeep is not an official part of git is absolutely not a reason to misuse .gitignore. An empty .gitignore is confusing and meaningless. Where as an empty .gitkeep is clearly a placeholder to "keep" the directory in git.Trin
I believe that is your point of view not of allSatin
To be clear, your point of view is that it's OK (or a good idea) to extend the official .gitignore file purpose so that it doubles up as a placeholder when empty? Like I said, I cannot disagree more. Perhaps you could edit your answer to explain your reasoning or back up your point of view? Right now it is a baseless answer and fully deserves my downvote.Trin
Ah, I realize I have stumbled in to a conventions war. I just noticed the comments on the accepted answer. Maybe there are two conventions here, and maybe each has their own number of followers so that popularity differs. I would still like to hear the arguments FOR this convention because maybe I will change my mind.Trin
My argument is that when i searched online for more info on .gitkeep I found all content from community and none from official Git docs. I prefer to follow official docs firstSatin
I see that. But can you show in the official Git docs where it directs people to add empty .gitignore files?Trin
P
0

If you want to ignore everything in a subdirectory but have the subdirectory itself (and for that the .gitkeep file) added to Git, you have to add this to .gitignore:

build/*
!build/.gitkeep

This means ignore everything under the build directory, but exclude .gitkeep from the ignore pattern.

Phelgon answered 20/10, 2023 at 15:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.