git ignore exception
GitGitignoreGit Problem Overview
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?
Git Solutions
Solution 1 - Git
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.
Solution 2 - Git
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
Solution 3 - Git
You can simply git add -f path/to/foo.dll
.
.gitignore
ignores only files for usual tracking and stuff like git add .
Solution 4 - Git
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
Solution 5 - Git
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.
Solution 6 - Git
!foo.dll
in .gitignore, or (every time!) git add -f foo.dll
Solution 7 - Git
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.
Solution 8 - Git
The solution depends on the relation between the git ignore rule and the exception rule:
-
Files/Files at the same level: use the @Skilldrick solution.
-
Folders/Subfolders: use the @Matiss Jurgelis solution.
-
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
Solution 9 - Git
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
Solution 10 - Git
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
Solution 11 - Git
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
Solution 12 - Git
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.