I have the following directory structure:
./
├── proj-1
│ ├── README.md
│ ├── src/
│ └── test/
└── proj-2
├── README.md
├── src/
└── test/
How can I ignore everything except for the src/
directories using just one .gitignore
file in the root directory?
I've tried:
*
!.gitignore
!/*/src/
!/*/src/*
But that doesn't seem to pick up the directories I want after running git status
.
Any tips?
You have to recursively un-ignore all parent directories of the src
directory tree, then ignore their content:
# Ignore everything
*
# Unignore .gitignore
!.gitignore
# Unignore all directories
!*/
# Ignore contents of all directories
*/*
# Unignore all src subdirectories
!*/src/
# Unignore directory tree under src subdirectories
!*/src/**
So, for a tree that looks like
.
├── proj-1
│ ├── README.md
│ ├── src
│ │ ├── srcfile1
│ │ ├── srcfile2
│ │ ├── srcfile3
│ │ └── subsrc
│ │ ├── subsrcfile1
│ │ ├── subsrcfile2
│ │ └── subsrcfile3
│ └── test
│ ├── testfile1
│ ├── testfile2
│ └── testfile3
├── proj-2
│ ├── README.md
│ ├── src
│ │ ├── srcfile1
│ │ ├── srcfile2
│ │ └── srcfile3
│ └── test
│ ├── testfile1
│ ├── testfile2
│ └── testfile3
└── proj-3
└── file
you get this status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
proj-1/
proj-2/
nothing added to commit but untracked files present (use "git add" to track)
and after adding everything, you get
$ git add * .gitignore
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: proj-1/src/srcfile1
new file: proj-1/src/srcfile2
new file: proj-1/src/srcfile3
new file: proj-1/src/subsrc/subsrcfile1
new file: proj-1/src/subsrc/subsrcfile2
new file: proj-1/src/subsrc/subsrcfile3
new file: proj-2/src/srcfile1
new file: proj-2/src/srcfile2
new file: proj-2/src/srcfile3
.gitignore
has to be added explicitly because the shell doesn't expand *
to include hidden files.