Search code examples
gitgitignore

Is there a command to "roll up" a tree of gitignores into one parent gitignore?


Over time this large project has acquired quite a few .gitignore files scattered across its many directories. Adding a new .gitignore "at the site" is very handy when you're dealing with some new output folder or something, but it becomes hard to reason about.

Is there a way to "roll up" all these disparate .gitignore files back into the .gitignore at the root of the project? The end result would be a single .gitignore project-wide, with all the other ad-hoc ones removed.

It would be extra special if I could roll up one subtree at a time, or to a common child, so that I can manage the changes a little bit more effectively, but I won't be choosy.


Concrete example:

Before:

root
|- .gitignore
|- subdir1
|  |- .gitignore
|  |- subdir3
|     |- .gitignore
|     |- ignored_file.txt
|- subdir2
   |- .gitignore
# the .gitignore in subdir3
/ignored_file.txt

After:

root
|- .gitignore
|- subdir1
|  |- subdir3
|     |- ignored_file.txt
|- subdir2
# the .gitignore in root
/subdir1/subdir3/ignored_file.txt

Thanks for your time!


Solution

  • The standard linux find command (or its more recent sibling fd) will list the files for you :

    $ find * -name .gitignore
    .gitignore
    subdir1/.gitignore
    subdir1/subdir3/.gitignore
    subdir2/.gitignore
    

    If you have a script that expands a .gitignore file :

    # write a script, which takes a path as input,
    # and prefixes all patterns found within the file with 'path/' :
    $ expand.py subdir1/subdir3/.gitignore
    /subdir1/subdir3/ignored_file.txt
    

    You can combine both :

    $ find * -name .gitignore | xargs -L1 expand.py
    # look only in the subdir1 subdirectory :
    $ find subdir1/ -name .gitignore | xargs -L1 expand.py