David
David

Reputation: 9969

How can I write a rule in gitignore to ignore all files except directories in some directory?

So lets say I have a directory structure like so

uploads/
--dir1/
----one.txt
----two.txt
----dir2/
------one.txt
------two.txt

I would like any directory and sub directories of uploads to be tracked but not any files in it with the exception of a dummy file because git doesn't track directories.

I would think something like this would work but it doesn't.

*
!.gitignore

Upvotes: 9

Views: 4953

Answers (1)

Chris Johnsen
Chris Johnsen

Reputation: 224621

When you tell it to ignore *, Git will not recurse into any subdirectories (even though you have a “unignore” pattern that might match something inside one of the directories).

There is a bit of the gitignore pattern language that might help though. A trailing slash forces the pattern to only apply to directories. So, you should be able to use this:

# .gitignore
*
!.keep
!*/

In the demonstration below I use the above .gitignore and have an additional file (named do-not-keep) alongside each .keep file. You can see that it works for multiple levels of subdirectories and does not show the other files. You will have to arrange for each directory to have its own .keep (or whatever) via some independent method.

% git status --short -uall
?? a/.keep
?? a/b/.keep
?? a/b/c/.keep
?? a/b/c/d/.keep
?? e/.keep
?? e/f/.keep
?? e/f/g/.keep
?? h/.keep
?? h/i/.keep
?? j/.keep

This was done with Git 1.7.3.1, but I expect that it will work for other versions as well.

The demonstration setup:

% git init
% mkdir -p a/b/c/d e/f/g h/i j
% zargs -i.. -- **/*(/) -- touch ../.keep ../do-not-keep
% tree -aI .git .                                       
.
|-- .gitignore
|-- a
|   |-- .keep
|   |-- b
|   |   |-- .keep
|   |   |-- c
|   |   |   |-- .keep
|   |   |   |-- d
|   |   |   |   |-- .keep
|   |   |   |   `-- do-not-keep
|   |   |   `-- do-not-keep
|   |   `-- do-not-keep
|   `-- do-not-keep
|-- e
|   |-- .keep
|   |-- do-not-keep
|   `-- f
|       |-- .keep
|       |-- do-not-keep
|       `-- g
|           |-- .keep
|           `-- do-not-keep
|-- h
|   |-- .keep
|   |-- do-not-keep
|   `-- i
|       |-- .keep
|       `-- do-not-keep
`-- j
    |-- .keep
    `-- do-not-keep

10 directories, 21 files

Upvotes: 11

Related Questions