443

I have a gitignore file that makes git ignore *.dll files, and that is actually the behavior I want. However, if I want an exception ( i.e. to be able to commit foo.dll), how can I achieve this?

Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
roundcrisis
  • 17,276
  • 14
  • 60
  • 92
  • 8
    possible duplicate of [Exceptions in .gitignore](http://stackoverflow.com/questions/2415873/exceptions-in-gitignore) – wallyk Feb 27 '12 at 09:26
  • fwiw, the granddaddy of duplicate answers on this topic--one that you should look over--would probably be [Make .gitignore ignore everything except a few files](https://stackoverflow.com/questions/987142/make-gitignore-ignore-everything-except-a-few-files) - very regular activity and several good answers. I'm a particular fan of [this answer](https://stackoverflow.com/a/29932318/5440638), which seems clear and thorough. – Kay V Jul 20 '18 at 00:02
  • Possible duplicate of [Make .gitignore ignore everything except a few files](https://stackoverflow.com/questions/987142/make-gitignore-ignore-everything-except-a-few-files) – Kay V Jul 20 '18 at 00:04

12 Answers12

610

Use:

*.dll    #Exclude all dlls
!foo.dll #Except for foo.dll

From gitignore:

An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.

Skilldrick
  • 69,215
  • 34
  • 177
  • 229
  • 38
    See also answer form @Matiss Jurgelis - it's important addition – Dan Aug 06 '15 at 10:08
  • 7
    Can I add the exception to my project's gitignore and not my global gitignore? For example, if I wanted to include all DLLs in a directory? My gitignore_global has `*.dll` in it, and my project's gitignore has `!Libs/*.dll` but that doesn't seem to be working. – Joel Kinzel Nov 10 '15 at 21:20
  • 1
    @jkinz, you should try `!Libs/**/*.dll`. – Rosberg Linhares Nov 09 '16 at 20:50
  • @RosbergLinhares Or `!**/Libs/*.dll`, depending on the folder structure. – JAB Dec 04 '17 at 20:18
  • 3
    Thanks, but on a mac adding the comment on the same line as the `!foo.dll` did invalidate the command. If I add the comment on a separate row it works. – Giacomo Mar 07 '18 at 15:18
  • 1
    @Giacomo I had the same on Windows, `#` should be avoided. – Jona Dec 19 '19 at 08:28
378

Git ignores folders if you write:

/js

but it can't add exceptions if you do: !/js/jquery or !/js/jquery/ or !/js/jquery/*

You must write:

/js/* 

and only then you can except subfolders like this

!/js/jquery
Matiss
  • 5,079
  • 2
  • 27
  • 27
67

You can simply git add -f path/to/foo.dll.

.gitignore ignores only files for usual tracking and stuff like git add .

nocksock
  • 5,369
  • 6
  • 38
  • 63
  • 6
    Just for more details, the `-f` tells git to force the adding of this file in the repo since it might ignore it first because of your `.gitignore` – RPDeshaies Apr 21 '16 at 18:24
  • 1
    Which is great if you only have one file, less useful if you need a pattern – Liam Aug 23 '16 at 15:46
  • Good to know. But still better manage all the rules in the .gitignore than not knowing some rules are defined else where, especially in a team context – Vinh Apr 04 '21 at 20:35
24

To exclude everything in a directory, but some sub-directories, do the following:

wp-content/*
!wp-content/plugins/
!wp-content/themes/

Source: https://gist.github.com/444295

Simon Paarlberg
  • 277
  • 2
  • 10
15

Just add ! before an exclusion rule.

According to the gitignore man page:

Patterns have the following format:

...

  • An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.
Robert Munteanu
  • 67,031
  • 36
  • 206
  • 278
6

For Nested Folders, I came up with a solution based on Matiss's answer.

Let's say I want to ignore everything in build/ directory (which is in /app). So I do:

build/*

However, if I want to exclude build/outputs/bundle/release subfolder, I need to play some hide and seek!


/app/build/*
!/app/build/outputs
/app/build/outputs/*
!/app/build/outputs/bundle
/app/build/outputs/bundle/*
!/app/build/outputs/bundle/release

Important Notes:

  • All the paths should start with / and be relative to the .gitignore
  • You have to do it one subfolder at a time. You can see in VS Code (for instance) what it includes and what not at every step.
Aidin
  • 25,146
  • 8
  • 76
  • 67
5

!foo.dll in .gitignore, or (every time!) git add -f foo.dll

Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221
5

If you're working with Visual Studio and your .dll happens to be in a bin folder, then you'll need to add an exception for the particular bin folder itself, before you can add the exception for the .dll file. E.g.

!SourceCode/Solution/Project/bin
!SourceCode/Solution/Project/bin/My.dll

This is because the default Visual Studio .gitignore file includes an ignore pattern for [Bbin]/

This pattern is zapping all bin folders (and consequently their contents), which makes any attempt to include the contents redundant (since the folder itself is already ignored).

I was able to find why my file wasn't being excepted by running

git check-ignore -v -- SourceCode/Solution/Project/bin/My.dll

from a Git Bash window. This returned the [Bbin]/ pattern.

DeanOC
  • 7,142
  • 6
  • 42
  • 56
4

The solution depends on the relation between the git ignore rule and the exception rule:

  1. Files/Files at the same level: use the @Skilldrick solution.
  2. Folders/Subfolders: use the @Matiss Jurgelis solution.
  3. Files/Files in different levels or Files/Subfolders: you can do this:

    *.suo
    *.user
    *.userosscache
    *.sln.docstates
    
    # ...
    
    # Exceptions for entire subfolders
    !SetupFiles/elasticsearch-5.0.0/**/*
    !SetupFiles/filebeat-5.0.0-windows-x86_64/**/*
    
    # Exceptions for files in different levels
    !SetupFiles/kibana-5.0.0-windows-x86/**/*.suo
    !SetupFiles/logstash-5.0.0/**/*.suo
    
Community
  • 1
  • 1
Rosberg Linhares
  • 3,537
  • 1
  • 32
  • 35
1

Since Git 2.7.0 Git will take exceptions into account. From the official release notes:

  • Allow a later "!/abc/def" to override an earlier "/abc" that appears in the same .gitignore file to make it easier to express "everything in /abc directory is ignored, except for ...".

https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.7.0.txt

edit: apparently this doesn't work any more since Git 2.8.0

Erfan
  • 2,959
  • 2
  • 17
  • 21
1

This is how I do it, with a README.md file in each directory:

/data/*
!/data/README.md

!/data/input/
/data/input/*
!/data/input/README.md

!/data/output/
/data/output/*
!/data/output/README.md
Miladiouss
  • 4,270
  • 1
  • 27
  • 34
1

If you have a directory and want to ignore everything with the exception of some files (e.g. *.py files), you can do:

sub-dir/**/*.*
!sub-dir/**/*.py
Miladiouss
  • 4,270
  • 1
  • 27
  • 34
  • This should be higher up. Also, you can explicitly set the deapth (not sure why you would) like so "folder/*/*" and "!folder/*/file" – Torben Nordtorp Apr 25 '23 at 13:02