Using .gitignore to ignore everything but specific directories

108,574

Solution 1

Here's how I did it - you essentially have to walk up the paths, you can't wildcard more than one level in any direction:

# Ignore everything:
*

# Except for the themes directories:

!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*

Notice how you have to explicitly allow content for each level you want to include. So if I have subdirectories 5 deep under themes, I still need to spell that out.

This is only how it worked for me. If someone cares to offer a more informed explanation by all means.

Also, these answers helpful:
how-do-negated-patterns-work-in-gitignore
how-do-gitignore-exclusion-rules-actually-work


NOTE: I tried using double-wildcard 'globs' but according to this that functionality is system dependent and it didn't work on my mac:

Did NOT work:

!**/wp-content/themes/
!**/wp-content/themes/**

Solution 2

I tried the above and they didn't work so well. A better approach is as follows from here: https://gist.github.com/444295

# This is a template .gitignore file for git-managed WordPress projects.
#
# Fact: you don't want WordPress core files, or your server-specific
# configuration files etc., in your project's repository. You just don't.
#
# Solution: stick this file up your repository root (which it assumes is
# also the WordPress root directory) and add exceptions for any plugins,
# themes, and other directories that should be under version control.
#
# See the comments below for more info on how to add exceptions for your
# content. Or see git's documentation for more info on .gitignore files:
# http://kernel.org/pub/software/scm/git/docs/gitignore.html

# Ignore everything in the root except the "wp-content" directory.
/*
!.gitignore
!wp-content/

# Ignore everything in the "wp-content" directory, except the "plugins"
# and "themes" directories.
wp-content/*
!wp-content/plugins/
!wp-content/themes/

# Ignore everything in the "plugins" directory, except the plugins you
# specify (see the commented-out examples for hints on how to do this.)
wp-content/plugins/*
# !wp-content/plugins/my-single-file-plugin.php
# !wp-content/plugins/my-directory-plugin/

# Ignore everything in the "themes" directory, except the themes you
# specify (see the commented-out example for a hint on how to do this.)
wp-content/themes/*
# !wp-content/themes/my-theme/

Solution 3

modify the first line

*

change it to

/*

Solution 4

Try these answers:

Make .gitignore ignore everything except a few files

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# ...even if they are in subdirectories
!*/

How do I tell Git to ignore everything except a subdirectory?

This ignores root files & root directories, then un-ignores the root bin directory:

/*
/*/
!/bin/

This way you get all of the bin directory, including subdirectories and their files.

Solution 5

If you prefix a pattern with an exclamation point (!) it negates any previous pattern which excluded it. So, presumably, you could ignore everything, then only allow what you want by using this pattern.

Share:
108,574

Related videos on Youtube

Yarin
Author by

Yarin

Products PDF Buddy - Popular online PDF editor Gems Snappconfig - Smarter Rails app configuration

Updated on February 24, 2020

Comments

  • Yarin
    Yarin over 4 years

    My issue is that I have a bunch of WordPress websites in my git repo, of which I want to selectively commit only the content of my themes folders, while ignoring the rest of the redundant files found in WordPress.

    I've used .gitignore files to ignore file types before, but can it be used the other way around- that is to ignore everything BUT a certain folder path?

    root (git repo)
    - / wordpress
    - - / (WordPress Site 1)/wp-content/themes
    - - / (WordPress Site 2)/wp-content/themes
    - - / (WordPress Site 3)/wp-content/themes

    Thanks-

    UPDATE:

    Based on the answers I did the following, but it's not working. Any ideas?

    # Ignore everything:
    *
    # Except for wordpress themes:
    !*/wp-content/themes/*
    

    I've also tried the following variations:

    !*/wp-content/themes*
    !*wp-content/themes/*
    !wp-content/themes/*
    !/wordpress/*/wp-content/themes*
    !wordpress/*/wp-content/themes*
    

    None of these read my themes folders.

  • Yarin
    Yarin about 13 years
    @dappawit- Thanks- concept makes sense, and I got it working for files, but not for my themes folders- see my edits above...
  • Yarin
    Yarin about 13 years
    @irritate- Thanks, did not see these- however, I'm having trouble applying them to my situation. See my edits above...
  • irritate
    irritate about 13 years
    The second link I posted says that you would need both !*/wp-content/themes/ and !*/wp-content/themes/*. Have you tried that variation? Also, as an alternative, you could just use !*/wp-content/themes/ and in each themes directory have its own .gitignore file with !*
  • Yarin
    Yarin about 13 years
    @irritate- no that variation doesn't work either, and anyway I don't see how that would be any different from !*/wp-content/themes*
  • dappawit
    dappawit about 13 years
    I am not an expert on glob patterns, but reading the .gitignore man page, I believe this may work: !wordpress/[write out directories]/wp-content/themes/. Notice the closing slash and no closing asterisk. Also note that * will only match one level, not multiple directories. Here is the man page: kernel.org/pub/software/scm/git/docs/gitignore.html
  • Yarin
    Yarin almost 12 years
    @dwenaus- thanks for sharing this- looks useful for repos rooted in a specific wordpress dir, but won't work on repo w multiple wordpress sites underneath it, which is what I was going for..
  • Axe
    Axe almost 12 years
    Helped me realise I had to put the negation after the other rules thanks
  • random_user_name
    random_user_name about 11 years
    This structure / model is super helpful. I wanted a single repo for a combined Magento / WP install, and with fewer than 30 lines of .gitignore using this technique, I was able to get it narrowed down to just the Magento theme / skin files and the WP theme files. Thanks!
  • dwenaus
    dwenaus about 11 years
    just don't use this setup with auto-deploy because a novice git user could mess up files outside of the indented areas (ie. if they delete all files in the repo by accident and that is auto deployed it'll be messy). Other than that it works well.
  • Admin
    Admin over 10 years
    before git 1.8.4 the ** wildcard only workds if you have no slashes in your pattern, see sparethought.wordpress.com/2011/07/19/…
  • that0n3guy
    that0n3guy over 9 years
    This should work: !/wordpress/*/wp-content/themes/**/*
  • Haktan Suren
    Haktan Suren almost 9 years
    You are the man dude! Especially if your version is >=2.1.4. Ref: git-scm.com/docs/gitignore/2.1.4
  • Scorb
    Scorb over 7 years
    Does this syntax work on windows? It does not seem to be working for me...
  • umbalaconmeogia
    umbalaconmeogia about 7 years
    This work for me. My .gitignore file is like this /* !.gitignore !/vendors
  • klewis
    klewis almost 5 years
    It works wonders on Windows 10. Using it for all kinds of custom projects from Visual Studio Code.
  • MikeyE
    MikeyE over 4 years
    I used a combination of this answer and the one provided by @吴毅凡 , which worked for me.
  • Jet Blue
    Jet Blue about 4 years
    "you have to first allow the parent directory to be included, before you can allow its child directory" - Thank you for pointing this out! Was precisely my problem.
  • codekandis
    codekandis over 3 years
    It's important to have a look at @吴毅凡 answere. The first line need to be changed.
  • Timo
    Timo over 3 years
    I work on windows, the first line works, everything is ignored. But I cannot unignore with !, all remains ignored.