Ignore other .gitignore files than the one in root - gitignore

My Actual Question
I would like that only the .gitignore file in the root of my directory structure ignore files, i.e, the .gitignore files in subdirectories shouldn't ignore files.
To be clear
I don't want to gitignore other .gitignore files. I want them to be commited to git but I don't want them to gitignore other files.
Specific use-case
Let's say I want to commit a boilerplate project structure to git. Let's say the project structure looks like this:
project-root/
│
├── boilerplate/
│ ├──directory/
│ ├──some-other-directory/
│ ├──.env
└── └──.gitignore // Has a line ".env" which will ignore the .env file in this directory
│
├── boilerplate2/
│ ├──directory/
│ ├──some-other-directory/
│ ├──.env
└── └──.gitignore
│
└── .gitignore // The .gitignore in root
Now the .gitignore file in boilerplate directory will gitignore .env which I don't want. How can I stop nested .gitignore files from taking action?
What I tried?
I tried the negation (!) operator in the main .gitignore file. For the sample structure above, it's equivalent to !boilerplate/.env. The .gitignore in root simply doesn't have any power over the .gitignore file in the specified directory. It doesn't override it. Why does it work like that? Is there a workaround?
Edit:
VonC suggests to automate that using scripts, but that's not the question. The question is, how to do that using only .gitignore, if it is possible at all.

Now the .gitignore file in boilerplate directory will gitignore .env which I don't want.
It will not.
If boilerplate/.env is already added (git add --force) and committed, any change to that particular .env file would still be detected, not ignored.
The OP adds:
But when I do git status, git ignores boilerplate/.env due to boilerplate/.gitignore (which isn't commited either)
Then, yes, it will ignore all .env, unless they are themselves versions.
The .gitignore in root simply doesn't have any power over the .gitignore file in the specified directory.
It doesn't override it.
That follows the precedence rules for a .gitignore:
Patterns read from a .gitignore file in the same directory as the path, or in any parent directory (up to the top-level of the working tree), with patterns in the higher level files being overridden by those in lower level files down to the directory containing the file.
In your case, I would:
keep the .env rule
version only .env.tpl template files with default initial value
add a .gitattributes file with a smudge content filter driver script declaration for *.tpl
That smudge script (for instance, 'script_tpl', which can be versioned as well) would be a bash script (which does work even on Windows, since Git for Windows comes with bash.exe):
#!/bin/bash
file="${f%.tpl}" # ex: .env.tpl => .env
if [[ ! "${file}" ]]; then cp "${f}" "${file}"; fi
I would add an senv script to be executed by any collaborator using a local cloned of the repository, in order to register automatically the content filter driver. It would include:
#!/bin/bash
DIR="$( cd "$( dirname "$(readlink -f "${BASH_SOURCE[0]}")" )" && pwd )"
# assuming the smudge script is at the root of the repository
which script_tpl || export PATH=${PATH}:${DIR}
git config --global filter.tpl.smudge 'script_tpl'
That way, any time you switch branch, the smudge script with check if .env does exist and, if not, will create one (which will be ignored by all the various .gitignore files)

Related

Why doesn't this ignore my files recursively?

In my project's root directory there are directories like 'tools':
tools/evaluate/test/
tools/evaluate2
Under test, there are some .py and .csv files. I want to ignore all files except .py, so in my .gitignore, I have this entry:
!tools/**/*.py
I want to recursively ignore all non-python files under tools. What's wrong with that?
if the files you are trying to ignore have been already committed, you need to remove them from the staging area as well, that's done by:
git rm --cached !tools/**/*.py
check the status:
git status
add the files you want to delete to .gitignore i assume manually, i don't know of an automatic way, then finally:
git add .gitignore
git commit -m "Remove unused files"
Two parts are needed here:
# Recursively ignore everything in tools that has an extension:
**/tools/**/*.*
# Except .py files recursively in tools:
!tools/**/*.py

Too many active changes git warnings

i made a clean installation of visual studio code. Why do i get those warnings about Git 99+ warnings. How should i fix this ?
Those are Atom IDE generated files.
Add this to the .gitignore file:
.atom/
If the file not exists, create one in the root of the repository
It looks like you just forgot to ignore all of the generated files in your git directory. You need to find the directory and add it to your .gitignore file. Lets say the directory name is node_modules, so your .gitignore file content should be something like this
node_modules/
Using this way, those all active changes files will be ignored.
If a user sees that message it is most likely, that his git repository root is at the different directory, and probably is at the much higher directory (comparing to his/her repo). It can be checked by running:
git rev-parse --show-toplevel
If that's the case, then deleting hidden folder .git from this higher directory will solve the case.

gitignore misses some binary files (DLLs & PEs)

I use the latest version of Github Desktop. My repo consist of a rather large C# solution with many sub-directories and projects. I'd like to ignore all R#-cache files and compiled binaries using the .gitignore file which resides in the root directory of the local repo directory. There are no other gitignore's anywhere in this repo and none in any parent directories. My current gitignore is this:
*.suo
*.user
_ReSharper.*
bin
obj
packages
*.cache
*.pdb
*.dll
*.exe
*.xml
When I made my changes, recompiled and tested everything, I open Github Desktop. It catches almost all files that should be ignored, only some .dlls, .pdbs and .exes are not ignored and always show up as changed:
Now, there are way more binary files in this repo. Only the specific ones in the screengrab are missed.
Is this fixable, and/or can the gitignore be altered to catch all files that it should catch?
Here's what I tried:
Removed and re-cloned the repository
Removed and manually re-created the gitignore
Right-click->Ignore by file extension from within the GitHub Desktop client. This does not work, worse, it creates duplicate masks in the gitignore
Checked for conflicting gitignore's in directories accessible by Github Desktop
Maybe you have files that were already being tracked by git before you modified the .gitignore? Those files (at least in git 1.9.1) aren't ignored when added to a .gitignore.
For example, I created a "test" directory at the root file one of my repos and put a file in it:
mkdir test
echo "abc" > test/x.txt
I added, committed and pushed it. Then I edited .gitignore at the root and added this line:
x.txt
I also made an edit to test/x.txt AND added a new file:
echo "123" >> test/x.txt
mkdir test2
echo "xyz" > test2/x.txt
Now when I run "git status" I see:
modified: .gitignore
modified: test/x.txt
So test2/x.txt is being properly ignored, but test/x.txt is still being tracked.
To force the file to be ignored, you can delete it, add & commit the deletion together with the .gitignore change, then restore the file.

Mercurial: How to add a file from an ignored folder?

I have added a folder to the file .hgignore and hence the files in it (and inside it subdirectories) are ignored. However, I just added a file to one of the subdirectories of the ignored folder. How do I add that file to list of tracked files?
I guess this is one of the downsides of using a GUI for version control. I am using SourceTree and have little direct exposure to Hg commands (although I have enabled the option to show the commands when they are executed and do observe what Hg is doing in the background). I tried googling the question but couldn't find any relevant result.
You can individually track an ignored file simply by adding it explicitly. From the .hgignore man page:
An untracked file X can be explicitly added with hg add X, even if X would be excluded by a pattern in .hgignore.
Your express intent to add this file is presumed to override your preferences in .hgignore.
The purpose of .hgignore is primarily to not have ignored files included when you add a directory in its entirety.
You need to edit your repository's ".hgignore" file and specify that you want the directory tree to be ignored except this file. For example if you have the following structure:
└── a
├── b.txt
└── c.txt
and you would like to ignore everything but not "c.txt", then depending on the .hgignore file contents you can have:
Without any .hgignore file:
$ hg status
? a/b.txt
? a/c.txt
With a line to ignore everything under "a":
$ cat .hgignore
syntax: regexp
^a/
$ hg status
? .hgignore
And with an other line to ignore everything under "a" but not the "c.txt" file:
$ cat .hgignore
syntax: regexp
^a/(?!c.txt).*
$ hg status
? .hgignore
? a/c.txt
Hope it'll help.

Removing file from .gitignore in webstorm

I was searching the web for hour now...
I can't seem to find where the gitignore file is located,and it's ruining my life. I have to remove one file from there. I'm using WebStorm 8
Any help?
.gitignore can be in any folder inside your git repository. And the patterns in .gitignore of child folder will overwrite the ones in parent folder.
It may be hidden when you use ls in your Git Bash. Just use ls -a.
From the doc:
Patterns read from a .gitignore file in the same directory as the
path, or in any parent directory, with patterns in the higher level
files (up to the toplevel of the work tree) being overridden by those
in lower level files down to the directory containing the file. These
patterns match relative to the location of the .gitignore file.