Is there a way to tell git to only include certain files instead of ignoring certain files?

Viewed 98586

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?

7 Answers

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

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.

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

!.*

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...

Related