216

My programs generally generate huge output files (~1 GB) which I do not want to be backing up to the git repository. So instead of being able to do

git add .

I have to do something like

git add *.c *.cc *.f *.F *.C *.h *.cu

which is a little bit cumbersome...

I feel fairly confident I could write a quicky perl script ls the directory contents into .gitignore and then remove files based on a .gitinclude (or some similar name) file, but that seems a little too hackish. Is there a better way?

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
Daisy Sophia Hollman
  • 6,046
  • 6
  • 24
  • 35

7 Answers7

301

I haven't had need to try this myself, but from my reading of TFM it looks like a negated pattern would do what you want. You can override entries in .gitignore with later negated entries. Thus you could do something like:

*.c
!frob_*.c
!custom.c

To have it ignore all .c files except custom.c and anything starting with "frob_"

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • 26
    Thanks, T.E.D. This worked. All I had to do was start the .gitignore file with * and then list all of my included file patterns proceeded by an exclamation point. – Daisy Sophia Hollman Aug 14 '09 at 19:44
  • 11
    How about folders? I cant find a way to include folders and files inside by negating a rule. – Marcio Cruz Oct 30 '13 at 16:24
  • 4
    About folders please check http://stackoverflow.com/questions/12799855/configure-git-to-track-only-one-file-extension – uzsolt Jul 16 '14 at 05:48
  • 2
    very nice. I am using this to have a repository in my home folder for things like vimrc and bashrc – Martin Capodici Jun 18 '15 at 11:53
  • 1
    @uzsolt does not work if you want to include one specific folder. see http://stackoverflow.com/questions/987142/make-gitignore-ignore-everything-except-a-few-files/29932318#29932318 – DiCaprio Dec 13 '16 at 22:18
  • @dyslexicanaboko - Well, a decade ago when I wrote this, "RTFM" was a pretty typical response online to questions with a reference answer, and the phrase was so ubiquitous that between techies it wasn't even considered particularly rude. People often applied it to themselves (as I did here). These days I don't think I'd necessarily throw that in there... – T.E.D. Jun 17 '18 at 00:12
  • I don't think it hurts sometimes. I run my own blog and the only time I create an article is if I can't find the answer or it wasn't obvious. Usually RTFM or TFM applies - people like to ask before they look it up. Either way I like your reply. – dyslexicanaboko Jun 24 '18 at 01:34
  • It doesn't seem to work with folders. I'm trying to include a specific path to a file, after its upper-level folder has been ignored, that doesn't seem to work. – Shimmy Weitzhandler Jul 19 '20 at 03:41
  • @ShimmyWeitzhandler - Try reading the comments about 5 above yours. – T.E.D. Jul 20 '20 at 12:42
  • After restarting VS things are working now. It was something inside the `.vs` folder, so it's understandable. Thank you. – Shimmy Weitzhandler Jul 21 '20 at 00:46
  • For my case only `!**/my-folder/build` worked. Remember to reapply `.gitignore` as needed. – Jacksonkr Jul 06 '21 at 16:56
93

create .gitignore file in your repository and you want to track only c files and ignore all other files then add the following lines to it....

*
!*.c

'*' will ignore all files

and ! will negate files be to ignored....so here we are asking git not to ignore c files....

Vineel Kumar Reddy
  • 4,588
  • 9
  • 33
  • 37
  • Do you also need `.*` for hidden files? – trusktr Jun 04 '13 at 05:42
  • 3
    The `*` is a wildcard even for `.`, so hidden files are also ignored, but then all hidden files ending in `.c` are included. – tim-phillips Apr 26 '14 at 01:38
  • 2
    Using this method I think files from subfolders are also ignored. Check this for more details http://stackoverflow.com/a/11853075/739436 – Stelian May 04 '15 at 07:38
  • 1
    I used this method in my home directory to only track my .bashrc and .bash_history e.g. `*` followed by `!.bash*` in the .gitignore file – user5359531 Mar 17 '16 at 16:09
  • This is exactly what I was looking for! – Ulf Aslak Dec 09 '16 at 13:44
  • 2
    You might need `*.*` on windows - see the answer by @Smaranjit Maiti – Martin Capodici Jul 07 '17 at 04:03
  • agree with @popas. "man gitignore" states that "An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded." – alpha_989 Dec 09 '17 at 20:11
  • if you have *.c in subdirectories, havin ga * as the first directory, effectively ignores allsubdirectories. So even you include a !*.c after *, the files in the subdirectories wont be included. – alpha_989 Dec 09 '17 at 20:12
  • yep, `*` does not work with my Git version on Windows...only `*.*` works – Csa77 Mar 06 '19 at 17:18
20

The best solution to achieve this

create .gitignore file in repository root, and if you want to include only .c file then you need to add below lines to .gitignore file

*.*
!*.c

this will include all .c file from directory and subdirectory recursively.

using

*
!*.c

will not work on all version of git.

Tested on

git version 2.12.2.windows.2

Smaranjit
  • 659
  • 7
  • 17
13

If you need to ignore files but not a specific file inside a directory, here is how I did it:

# Ignore everything under "directory"
directory/*
# But don't ignore "another_directory"
!directory/another_directory
# But ignore everything under "another_directory"
directory/another_directory/*
# But don't ignore "file_to_be_staged.txt"
!directory/another_directory/file_to_be_staged.txt
gzfrancisco
  • 812
  • 10
  • 14
2

I've seen a number of suggestions for the initial "ignore everything" rule, both here on SO and on other sites, but I found most of them to have thir own annoying usage issues. this has given rise to projects like the distributable .gitinclude.NET and the GH Pages hosted git-do-not-ignore, each of which simply help make this less tedious to manutain.

each of these (and many other blog posts) recommend starting out with a simply * to, quite literally, ignore all files and folders in the current root.

thereafter, including a file is "as simple" as prefixing the path with !, such as !.gitignore to ensure our repo doesn't ignore it's own .gitignore rules file.

the down side of this, is that when Git encounters an ignored folder, for performance reasons it does not check it's contents. trying to not ignore a file in a nested path gets very cumbersome:

# ...when ignoring all files and folders in the current root
*

!custom_path                       # allow Git to look inside this folder
custom_path/*                      # but ignore everything it contains
!custom_path/extras                # allow Git to look inside this folder
custom_path/extras/*               # but ignore everything it contains
!custom_path/extras/path_to_keep   # allow Git to see the file or folder you want to commit

so to offer an alternative idea, I've just configured a .gitignore file in the root of my Windows user profile folder, starting with **/* instead of the commonly seen * or *.*.

thereafter, each path that I want to explicitly include requires only one entry per tree level. slightly simplifying the previous example to the following:

# ...when ignoring all files recursively from the current root
**/*

!custom_path                       # allow Git to look inside this folder
!custom_path/extras                # allow Git to look inside this folder
!custom_path/extras/path_to_keep   # allow Git to see the file or folder you want to commit

this is not exactly a massive difference, but it is enough of a difference to make the file much easier to read and maintain, especially when trying to "un-ignore" a file nested about 5 levels deep...

Andre Greeff
  • 121
  • 5
0

Late to the party, but my solution would be to have a directory for source files and a different directory for executables and program output, something like this:

+ .git
|    (...)
+ bin
|    my_exe.exe
|    my_output.txt
+ src
     some_file.c
     some_file.h 

... and then only add the stuff in src/ to my repository and ignore bin/ entirely.

Christian Severin
  • 1,793
  • 19
  • 38
0

If you're only trying to include dot files, this worked for me...

!.*
copeland3300
  • 581
  • 7
  • 11