tags:

views:

211

answers:

3

I'd like to only track certain directories in git in a larger project, where most directories will be excluded and only a few will be tracked. So, I wanted to use the not-operators in my .gitignore or excludes file, ja?

Why is this happening:

% mkdir wtfgit
% cd wtfgit 
% git init
Initialized empty Git repository in /home/foobar/wtfgit/.git/
% mkdir iwantthesefiles
% touch iwantthesefiles/foo
% mkdir idontwantthesefiles
% touch idontwantthesefiles/bar
% vim .gitignore
% cat .gitignore 
*
!iwantthesefiles/        
% git add --all
% git status
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

The "not" syntax works fine for files in the highest directory.

% touch baz          
% vim .gitignore
% cat .gitignore 
*
!iwantthesefiles/
!baz
% git add --all 
% git status    
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   baz
#

How can I get this to give me baz and foo as git tracked files? (Basically, how does the directory NOT-style globbing work at all?! It seems not to.)

Thanks!

A: 

Don't mention the directories in your .gitignore, just the files. Doing this and explicitly adding the directories you want to track should give you what you want:

$ cat > .gitignore << EOF
*
!bar
EOF
$ git add -f iwantthesefiles

This will let git track bar and everything in the directory iwanthesefiles.

William Pursell
A: 

Git is behaving in this manner: it will not ignore a file that is in the repository. Also, to exclude directories, end with a slash. As you can see in the following example, only iwantthesefiles/baz was tracked.

$ cat .gitignore
*/
!iwantthesefiles
$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .gitignore
#       iwantthesefiles/baz
nothing added to commit but untracked files present (use "git add" to track)
$ ls -lhR
.:
total 8.0K
drwxr-xr-x 2 user group 4.0K 2009-12-29 14:24 idonntwantthesefiles
drwxr-xr-x 2 user group 4.0K 2009-12-29 14:24 iwantthesefiles

./idonntwantthesefiles:
total 0
-rw-r--r-- 1 user group 0 2009-12-29 14:22 bar
-rw-r--r-- 1 user group 0 2009-12-29 14:24 baz

./iwantthesefiles:
total 0
-rw-r--r-- 1 user group 0 2009-12-29 14:24 baz
-rw-r--r-- 1 user group 0 2009-12-29 14:19 foo
$ rm -r * && git reset --hard && ls -lhR
HEAD is now at 698c66a monkey
.:
total 4.0K
drwxr-xr-x 2 user group 4.0K 2009-12-29 14:25 iwantthesefiles

./iwantthesefiles:
total 0
-rw-r--r-- 1 user group 0 2009-12-29 14:25 foo

And, to demonstrate that a tracked file overrides .gitignore:

$ mkdir idonntwantthesefiles
$ touch idonntwantthesefiles/baz
$
git add idonntwantthesefiles/baz
$ git commit -m 'llama'
Created commit a62b6d5: llama
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 idonntwantthesefiles/baz
$ echo foobar > idonntwantthesefiles/baz
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   idonntwantthesefiles/baz
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .gitignore
no changes added to commit (use "git add" and/or "git commit -a")
Autocracy
+1  A: 

Reviving an old post, in case someone else stumbles on this:

If you want to ignore all folders/files in the current directory, use a leading slash (/*/ for directories or /* for files); else Git will ignore the pattern recursively, which will cause files in unignored directories to be ignored too...

With that in mind, the !directory/ pattern unignores directories just fine.

Bassam Jabbour