18

I have a project with the following structure:

/. /src /project1 /bin /obj /project2 /bin /obj /tools /tool1 /bin 

What can I add to my .git/info/exclude to ignore all bin/obj directories under "src"? I don't want to explicitly specify each project name.

5 Answers 5

25

Try adding these lines to your .gitignore file:

src/*/bin src/*/obj 
Sign up to request clarification or add additional context in comments.

4 Comments

Doesn't work for me with 1.7.0.2.msysgit.0. I posted an answer that works for me.
@Drew: Your answer seems more handy since it matches all directories with less fuss, so I voted it up. That said, I don't know why this answer would not work for you since I am using this technique currently without issue. Perhaps your version of git is old?
@Kendall, actually it's a new machine with a new build of git. What platform are you on? I'm running msysgit on Win7 x64.
On a mac, running git 1.7.0.3 Since you're on windows it's probably the forward slashes, it probably needs you to use backslashes. On a Mac the normal path separator is a forward slash.
17

The accepted answer didn't work for me.

> git --version git version 1.7.0.2.msysgit.0 

Seems that forward slashes don't work with msysgit in the .gitignore file. This works.

*\bin *\obj 

However that will match exclude any files called bin or obj too, which isn't likely to be a problem, except for when it is. The following gets around this (and yes, a forward slash works in this case):

bin/ obj/ *.user *.suo 

This matches files at different depths in the hierarchy beneath the folder in which the .gitignore file is placed. Note that the above didn't work when I included a prefix for a specific subfolder, so I placed this in my Source folder directly.

As a Visual Studio user (presumably the OP is too from bin/obj reference) it's also nice to exclude .user and .suo files.


From the gitignore specification:

Patterns have the following format:

  • A blank line matches no files, so it can serve as a separator for readability.

  • A line starting with # serves as a comment.

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

  • If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in git).

  • If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).

  • Otherwise, git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".

  • A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".

1 Comment

bin/ obj/ *.user *.suo is what you want, if Git Extensions doesn't preview don't worry just added it to your top level .gitignore anyhow :)
9

The most obvious way would be to add these to src/.gitignore :

obj/ bin/ 

This ignores any paths that are in a directory call obj, or a directory called bin from the src directory downwards.

Something like src/*/obj/ in a top-level .gitignore might not work if you have a jagged project hierarchy with some obj and bin directories futher down the tree.

Here's quick test shell script showing the ignore rule in action:

#!/bin/sh mkdir src mkdir tools mkdir src/project1 mkdir src/project2 mkdir tools/tool1 mkdir src/project1/bin mkdir src/project1/obj mkdir src/project2/bin mkdir src/project2/obj mkdir tools/tool1/bin touch testfile touch src/testfile touch tools/testfile touch src/project1/testfile touch src/project2/testfile touch tools/tool1/testfile touch src/project1/bin/testfile touch src/project1/obj/testfile touch src/project2/bin/testfile touch src/project2/obj/testfile touch tools/tool1/bin/testfile git init add_empty() { touch "$1" && git add "$1"; } add_empty dummy add_empty src/dummy add_empty tools/dummy add_empty src/project1/dummy add_empty src/project2/dummy add_empty tools/tool1/dummy git status printf 'obj/\nbin/\n' >src/.gitignore && git add src/.gitignore git status 

The untracked file section of the first status is:

# Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/project1/bin/ # src/project1/obj/ # src/project1/testfile # src/project2/bin/ # src/project2/obj/ # src/project2/testfile # src/testfile # testfile # tools/testfile # tools/tool1/bin/ # tools/tool1/testfile 

And after adding the .gitignore file:

# Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/project1/testfile # src/project2/testfile # src/testfile # testfile # tools/testfile # tools/tool1/bin/ # tools/tool1/testfile 

As a test to prove that git isn't ignoring files called obj and bin but is ignoring obj and bin directories further down the hierarchy after running this script:

#!/bin/sh mkdir src/project3 touch src/project3/testfile && git add src/project3/testfile touch src/project3/obj touch src/project3/bin mkdir src/subdir mkdir src/subdir/proj touch src/subdir/proj/testfile && git add src/subdir/proj/testfile mkdir src/subdir/proj/obj mkdir src/subdir/proj/bin touch src/subdir/proj/obj/testfile touch src/subdir/proj/bin/testfile 

The new untracked files are:

# Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/project1/testfile # src/project2/testfile # src/project3/bin # src/project3/obj # src/testfile # testfile # tools/testfile # tools/tool1/bin/ # tools/tool1/testfile 

4 Comments

I am not sure it would work for all depths. I had trouble with those patterns here: stackoverflow.com/questions/991801/… (and check also the link in the comment of that answer)
If it doesn't, it's a bug. The slash means 'match as a directory only', after that it's treated as a pattern without a slash (trailing slash is removed), so just as a regular file glob and will match anywhere. I'm not sure where the '**' thing comes from as it's not a syntax that git supports.
Addendum, you specifically need a leading slash if you wan't to anchor the match from the current directory, but that's not the case here, we want it anywhere below a directory, not 'anchored' at a directory.
@Charles Thank you for your feedback. I will make further tests, not only for this question, but also for the the other two I linked about in my previous comment.
3

The confusion for me was that once added, whatever mask you put on it, the files will remain in the repository unless forcibly removed, so having added a raw, compiled visual studio solution, I had to clean the repository issuing:

git rm --cached */obj/* git rm --cached */lib/* git rm --cached *.user git rm --cached *.suo git rm --cached *ReSharper 

then, added this to .gitignore:

*/*/bin */*/obj *.user *.suo *ReSharper* 

then committed:

git add . git commit -m "removed user files and binaries from repository" 

Comments

1

I believe you should be able to add

src/*/bin/* 

to .gitignore, and anything that matches the pattern will be ignored.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.