jkubicek2 hours ago
I'm not sure if I'm the one to blame for this or not, but the earliest reference to ".gitkeep" I can find online is my 2010 answer on Stack Overflow: https://stackoverflow.com/a/4250082/28422

If this is all my fault, I'm sorry.

selridge1 hour ago
This is delightful. Accidental load-bearing SO post.
jkubicek1 hour ago
It's especially funny since my answer is wrong anyway! The other top answer is much better. I did get a lot of early SO brownie points from that one answer though.
juggerl633 minutes ago
Thankfully AI has put an end to the scourge of confidently-wrong SO hallucinations.
beej7114 minutes ago
What am I missing about this use case? It seems like you should just create `build/.gitignore` with `*` in it and `add -f` it and be done.

I'd use `.gitkeep` (or an empty `.gitignore`) if I needed to commit an otherwise-empty hierarchy. But if I'm going to have a `.gitignore` in there anyway, it's not empty.

> The directory is now “tracked” with a single, standard file that will work even after renames.

Does `.gitkeep` not work after renames? Or `.gitignore`?

So I am missing something. :)

Arrowmaster2 hours ago
The author makes a very common mistake of not reading the very first line of the documentation for .gitignore.

  A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected; see the NOTES below for details.
You should never be putting "!.gitignore" in .gitignore. Just do `echo "*" > .gitignore; git add -f .gitignore`. Once a file is tracked any changes to it will be tracked without needing to use --force with git add.
smrq1 minute ago
Why is this approach better than the author's?
ekipan2 hours ago
Yeah, this. Plus a mistake from the article:

  $ echo '*\n!.gitignore' > build/.gitignore
The \n won't be interpreted specially by echo unless it gets the -e option.

Personally if I need a build directory I just have it mkdir itself in my Makefile and rm -rf it in `make clean`. With the article's scheme this would cause `git status` noise that a `/build/` line in a root .gitignore wouldn't. I'm not really sure there's a good tradeoff there.

AgentME2 hours ago
If you have a project template or a tool that otherwise sets up a project but leaves it in the user's hands to create a git repo for it or commit the project into an existing repo, then it would be better for it to create a self-excepting .gitignore file than to have to instruct the user on special git commands to use later.
Kuraj1 hour ago
If you need to do this, I think .gitkeep communicates intent better. You don't need to document it or risk it being removed as thought to be a left over.
cortesoft3 hours ago
Not sure why you can’t just have your build script create the build directory?
andybak3 hours ago
Because you might not have a build script?
drdec1 hour ago
Then why do you need a build directory?
himata41131 hour ago
qemu: mkdir build; cd build; ../configure, some projects are like that
OptionOfT31 minutes ago
For me, I put them in directories that have to be there, because the underlying code doesn't create the directory, and without it, it fails.

Another example is where you want an empty directory mounted in Docker. If the directory is not there it is created with root permissions and then I can't even look into it.

kderbyma42 minutes ago
Arent Gitkeep files specifically for empty folders that are intended to be there?

That is what I have always used them for....

8cvor6j844qw_d62 hours ago
Is .gitkeep an established convention somewhere? I'm curious where the name originated.
abustamam2 hours ago
Seems to originate form this SO post

https://stackoverflow.com/a/4250082/28422

yjftsjthsd-h3 hours ago
I'm confused. Having a file gitignored doesn't stop you from committing it; AFAIK you can just

  touch build/.gitkeep
  git add build/.gitkeep
  git commit build/.gitkeep
And that's it? There's no need to exclude anything.
williadc3 hours ago
The idea is that you don't want to check-in any builds.
yjftsjthsd-h3 hours ago
Sure, so gitignore build/ or whatever. But you don't need to unignore .gitkeep
akerl_2 hours ago
The idea is that instead of adding a nonsense file, you use the native .gitignore functionality.

".gitkeep" is just a human thing; it would work the same if you called it ".blahblah".

So their pitch is that if you want to explicitly keep the existence of the directory as a committed part of the repo, you're better off using the actual .gitignore functionality to check in the .gitignore file but ignore anything else in the directory.

I don't find it amazingly compelling; .gitkeep isn't breaking anything.

dwattttt2 hours ago
This still confuses me. Do you mean to say "use the .gitignore functionality, and check in the .gitkeep file"?
akerl_53 minutes ago
No. Use a .gitignore instead of .gitkeep. Instead of checking in build/.gitkeep, check in build/.gitignore.
dwattttt40 minutes ago
I don't know that I like this approach. It certainly works, but it's not specifically what (people expect) a .gitignore file to be used for. That confusion isn't good: https://thecodelesscode.com/case/222 and https://thecodelesscode.com/case/223
suralind3 hours ago
I want to like it, but I pretty much always have a "cleanup" script that just deletes the entire directory and touches a .gitkeep file. Obviously an even better pattern is to not have any .gitkeep files, but sometimes they are just handy.
macote3 hours ago
The author is misusing .gitkeep. I use it to keep source code folders that don’t contain any code yet, but whose structure is already defined.
xyzzy_plugh3 hours ago
Truly, what purpose does this serve? Defining a hierarchy without using is injecting immediate debt. Just introduce it when stuff goes there! If you really insist then at least put something in the folder. It doesn't take much effort to make the change at least a tiny bit meaningful.

Better yet just do the work. If you want make a commit in a branch that's destined to be squashed or something, sure, but keep it away from the shared history and certainly remove it when it's not needed anymore.

abustamam2 hours ago
I play around with ComfyUI on my computer to make silly images.

To manually install it, you must clone the repo. Then you have to download models into the right place. Where's the right place? Well, there's an empty directory called models. They go in there.

IMO that's an effective use of gitkeep.

akoboldfrying2 hours ago
> Truly, what purpose does this serve?

The simplest answer is that sometimes other existing software that I need to use treats an empty directory (or, hopefully, a directory containing just an irrelevant file like .gitkeep) differently from an absent directory, and I want that software to behave in the first way instead of the second.

A more thorough answer would be: Filesystems can represent empty directories, so a technology that supports versioned filesystems should be able to as well. And if that technology can't quite support fully versioned filesystems -- perhaps because it was never designed with that goal in mind -- but can nevertheless support them well enough to cover a huge number of use cases that people actually have, then massaging it a bit to handle those rough edges still makes sense.

CGamesPlay11 minutes ago
You can rename `.gitkeep` to `.gitignore` and both be happy in that case.
peter-m802 hours ago
No, thanks