11

I wanted to track some files ignored by a bunch of repos into a single repo.

Here's an example layout:

.
+-- .git
+-- .idea
|-- .gitignore
|-- proj1
|   +-- .git
|   |-- .gitignore
|   |-- foo
|   |   |-- foo.iml
|   |-- bar.c
|   |-- proj1.iml
|-- proj2
    +-- .git
    |-- .gitignore
    +-- bar
    |-- foo.c
    |-- proj2.iml

I want:

  • the root-level repo to include all *.iml files, while each sub-repo individually ignores them
  • all the repos to be independent (the projects don't depend on the root, and can be manipulated separately)
  • this folder structure to be maintained

Any solution?

OrangeDog
  • 36,653
  • 12
  • 122
  • 207

3 Answers3

6

The title of the question and the detailed description seem to ask slightly different questions...

With regards to the title of the question: to exclude nested .gitignore files, but not the root .gitignore itself, add the following line to your root .gitignore file:

*/**/.gitignore

(this will only ignore those .gitignore files that are nested at least one folder level deep)

Alternatively, if you only want to ignore .gitignore files in direct child folders, but still want to include all .gitignore files in indirect (i.e., 2nd level, 3rd level,...) sub-folders use:

*/.gitignore
raner
  • 1,175
  • 1
  • 11
  • 21
  • 1
    To clarify, does this configure the tracking of the files themselves, or the ignoring of the rules in them? The latter is what the question means by "ignore". – OrangeDog Dec 12 '19 at 11:45
  • @StopHarmingMonica This configures the tracking of the nested .gitignore files. The rules in these files (if the files are present) will still apply. You can specify ignore rules locally (and they will be honored, again, locally), but the files won't be tracked. – raner Dec 13 '19 at 08:29
  • 2
    I like to know how to ignore the rules not just the tracking of the `.gitignore` I only want git to recognize the rules of the root `.gitignore` – redanimalwar Feb 13 '21 at 13:22
2

The trick is: a nested repository whole content is ignored by a parent repository.

In the OP's question, no *.iml file would be tracked by the root-level repository, because of the .git subfolder in proj1 and proj2.

But, assuming that proj1/2 content was actually tracked by the parent repository (git subtree, git subrepo), the .gitignore patterns application rules are clear:

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.

So:

I only want git to recognize the rules of the root .gitignore.

That would means a git wrapper script which would:

  • delete the projx/.gitignore
  • add everything
  • restore the deleted .gitignore files

The OP adds in the comments:

Can you setup git to automatically run a "wrapper script"?

Yes: you just define an alias for git (even on Windows, with doskey), which calls your own script.

If I can automatically run a wrappper script on commit that renames the .gitignore b4 commit, it would solve this issue I am having.

You would need a pre-commit hook which would first modify the index by registering in it empty blob for the nested .gitignore (meaning they are not removed, just emptied). Example here.

A post-commit hook can restore the content of those .gitignore.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I just read in the git manual that you can use `$GIT_DIR/info/exclude` but I do not like this solution as even with the fact that this repo if personal for me. But if I understand it right that would actually work as I have the git files moved out of the folder specifically because of the nesting my `.git`is a file with just `gitDir: /path/to/git/files/` I have not tried it yet but it for sure sounds like a better method than this. Can you setup git to automatically run a "wrapper script"? – redanimalwar May 14 '22 at 00:23
  • I recently had a repo that automatically ran a npm command on merge. If I can automatically run a wrappper script on commit that renames the .gitignore b4 commit, it would solve this issue I am having. – redanimalwar May 14 '22 at 00:25
  • @redanimalwar I have edited the answer to answer your comments/question. – VonC May 14 '22 at 03:14
0

Simply add the lower nested gitignores to the top-level gitignore file:

*/**/.gitignore

That will track all files except those marked in the top-level gitignore file.

Another solution to look into may be Git subtrees or Git submodules.

Zaz
  • 46,476
  • 14
  • 84
  • 101