This really should be a comment, except that it's too long and needs formatting.
... As ignoring tells Git to not track [the file]
This is where you have gone wrong.
Listing a file path, or a path pattern, in a .gitignore
, does not tell Git not to track the file.
In Git, what makes a file tracked is the presence of that file's path in the index. If the path is in the index, the file is tracked.
The contents of the index change dynamically, as you move from one commit to another. In particular, git checkout commit-or-branch
loads the index (and populates your work-tree) from the commit you select. If that commit contains some particular file, that file's path is now in your index, and that file is now tracked (and has been extracted into your work-tree). If that file's path is not in the commit, that file's path is now not in your index, and that file is now not tracked (and has just been removed from your work-tree, if it was there).
All of this happens regardless of what is in your .gitignore
files (with one modifier: listing a file in .gitignore
gives Git permission to overwrite or delete it, when it might otherwise refuse to do the git checkout
in the first place). So listing a file in .gitignore
does not make Git ignore it. If the file is currently tracked, the .gitignore
listing has no effect at all on it!
What .gitignore
does for untracked files is:
- Shut Git up about the untracked-ness. Otherwise Git will keep pestering you about it, which is annoying.
- Make Git skip the file when you use en-masse
git add
commands like git add -A
or git add .
βin fact, if you try to git add
it by name, Git will tell you that it's untracked now and listed as ignored and if you really want to add it, you will have to use the --force
option.
- And, as mentioned above, give Git permission to clobber the file in certain cases where it would otherwise tell you that checking out some particular existing commit would overwrite or delete it.
The file should probably be named .git-do-not-complain-about-some-files-that-are-untracked-and-by-the-way-feel-free-to-clobber-these-files-too
, or something along these lines. But that name is kind of difficult to use, so it's called .gitignore
.
To see several ways to deal with files that have accidentally been committed, see How to stop tracking and ignore changes to a file in Git? It's also possible to "rewrite history", to make new commits that everyone should switch to using in place of the old commits that contain the accidentally-committed file. However, everyone who has a copy of the repository with the accidentally-committed file must switch over to the new series of commits. In some ways it's easier to just make a new repository in which the file is never committed (this is essentially the same process).