42

Some time ago I set up my .gitignore file to not track a folder my_folder with:

my_folder/

Now I want to track only a given file inside said folder, named my_file.md. After making .gitignore look like this:

my_folder/
!my_folder/my_file.md

and checking:

git status

the file does not appear as a change to be committed.

What am I doing wrong?


Add

I tried changing my .gitignore file to:

my_folder/*
!my_folder/my_file.md

as advised but the file is still not showing up as a change to commit after a git status. Do I need to reset something?


Add 2

Attempting to add the file with git add my_folder/my_file.md returns:

The following paths are ignored by one of your .gitignore files:
my_folder/my_file.md
Use -f if you really want to add them.
fatal: no files added

The command git check-ignore -v my_folder/my_file.md gives:

.gitignore:1:my_folder/*    my_folder/my_file.md
Gabriel
  • 40,504
  • 73
  • 230
  • 404
  • 1
    Dupe - but the short answer is use "my_folder/*" http://stackoverflow.com/questions/5533050/gitignore-exclude-folder-but-include-specific-subfolder – Andrew C Oct 04 '14 at 02:49
  • Thanks @AndrewC, I tried that but it is still not working. Not sure what I'm doing wrong. – Gabriel Oct 04 '14 at 14:33
  • 2
    Since you *really* want to add *my_folder/my_file.md* why not use the `-f` flag as it tells you to? – Petr Skocik Oct 04 '14 at 15:54
  • 1
    Note: with git 2.8 (March 2016), your gitignore rules will finally work! See [my edited answer below](http://stackoverflow.com/a/26190177/6309) – VonC Feb 27 '16 at 21:37
  • Because it's a lot easier and feels more intuitive. Are you saying the other answer is incorrect? If so I'll change it back. – Gabriel Jul 13 '16 at 21:29
  • 1
    No, I had included the other answer in mine a long time ago. Mine is more complete and answer your original question. The other does not. – VonC Jul 13 '16 at 21:54
  • Fair enough. Back to original accepted answer then. Cheers. – Gabriel Jul 13 '16 at 23:10

4 Answers4

42

To add to ".gitignore exclude folder but include specific subfolder", one good way to debug those .gitignore file is to use git check-ignore (Git 1.8.4+):

git check-ignore -v my_folder/my_file.md

You would see it is still ignored because of the my_folder/ rule.

That is because it is not possible to re-include a file if a parent directory of that file is excluded.(*)
(*: unless certain conditions are met in git 2.?+, see below)

That is why ignoring the files within that folder (my_folder/*, instead of the folder itself) allows you to exclude one.

Of course, you can force adding a file ignored (git add -f my_folder/my_file.md), but that is not the point of this answer.
The point is to explain why adding !my_folder/my_file.md in .gitignore doesn't work with git 2.6 or less.


Note that with git 2.9.x/2.10 (mid 2016?), it might be possible to re-include a file if a parent directory of that file is excluded if there is no wildcard in the path re-included.

Nguyễn Thái Ngọc Duy (pclouds) is trying to add this feature:

So here, with git 2.8+, this would work:

/my_folder
!my_folder/my_file.md
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • VonC would you take a look at the updated question? I tried this but it isn0t working. – Gabriel Oct 04 '14 at 14:34
  • 1
    @Gabriel did you tried to add it? `git add my_folder/my_file.md`. What does `git check-ignore -v my_folder/my_file.md` returns? – VonC Oct 04 '14 at 15:42
  • @Gabriel strange: just modifying the `.gitignore` (which should be in the same parent folder as `my_folder`) should immediately work. – VonC Oct 04 '14 at 15:54
  • The `.gitignore` file is in the root directory, the same one where `my_folder` is. – Gabriel Oct 04 '14 at 15:55
  • @Gabriel are you sure `my_file.md` is correctly named? Meaning that the case is respected? (`my_file.md`, not `MyFile.MD`) Or that there isn't an extra space after the name? '`my_file.md `' – VonC Oct 04 '14 at 15:56
  • This is strange. Just to be sure I renamed both the folder and the file and it immediately was picked up by `git`. I am 100% sure that the names were correct (I swear, I checked many _many_ times). I changed the folder and file back to their original names and the file is now correctly tracked. Really, don't know what was gaing on here but it is fixed now. Thank you VonC! – Gabriel Oct 04 '14 at 16:04
  • @Vonc As described by knittl below `git add -f ignored_folder/my_file` do it ! – Jean Davy May 05 '15 at 09:49
37

A file will not show up as "change to be committed" if it is not yet tracked (IOW was never added before). Simply add the file with git add, and Git will track the file only, but still ignore the folder.

git add -f ignored_folder/my_file

The -f flag is important, since git will refuse adding files from ignored paths.

knittl
  • 246,190
  • 53
  • 318
  • 364
  • Even if I have `!my_folder/my_file.md`, I still need `git add -f my_folder/my_file.md` – onmyway133 Sep 17 '18 at 12:11
  • 1
    This might be helpful for some people (if they are not using the `!` patern in `.gitignore`) but the accepted answer is more precise in that it deals with the actual problem in the `.gitignore` file and not how to force add a file in an ignored folder. – Nader Ghanbari Nov 25 '18 at 23:12
  • This solution is more helpful than the accepted answer if the file is in more than 1 level of folder for example: ignored_folder/ignored_subfolder1/ignored_subfolder2/my_file – Dika Feb 28 '22 at 07:40
5

when I need track files like this, or only directory structures, I add something like this to my .gitignore file

resources/**/*.*

which means, "ignore all files with extension inside the resources directory including subdirectories".

Then I put an "empty" file inside those directories I want to keep tracked.

Note that only extensionless files are going to be tracked, and that's why this works.

with the option listed above, you can now add this:

!resources/my_needed_file.md

and that's another solution that not includes forced files, but is only an option if you are using files with extensions.

Dharman
  • 30,962
  • 25
  • 85
  • 135
BarzX ___
  • 51
  • 1
  • 4
  • in fact, my solution was about leaving an extensionless file in those directories that I wanted to be tracked, in order to avoid forced tracked files. And another good thing about this solution is that you only need to add those extensionless files at the deepest directories in the tree you want to track, but keep "empty" – BarzX ___ May 14 '20 at 19:49
-1

My Solution:

resources/**/*.*

then added after this line the negation:

!resources/my_needed_file.md

Mihkel L.
  • 1,543
  • 1
  • 27
  • 42