How do I ignore files in Subversion?

command, svn

Solution

(This answer has been updated to match SVN 1.8 and 1.9's behaviour)

You have 2 questions:

Marking files as ignored:

By "ignored file" I mean the file won't appear in lists even as "unversioned": your SVN client will pretend the file doesn't exist at all in the filesystem.

Ignored files are specified by a "file pattern". The syntax and format of file patterns is explained in SVN's online documentation: http://svnbook.red-bean.com/nightly/en/svn.advanced.props.special.ignore.html "File Patterns in Subversion".

Subversion, as of version 1.8 (June 2013) and later, supports 3 different ways of specifying file patterns. Here's a summary with examples:

1 - Runtime Configuration Area - `global-ignores` option:

- This is a client-side only setting, so your `global-ignores` list won't be shared by other users, and it applies to all repos you checkout onto your computer.

- This setting is defined in your Runtime Configuration Area file:

- Windows (file-based) - `C:\Users\{you}\AppData\Roaming\Subversion\config`

- Windows (registry-based) - `Software\Tigris.org\Subversion\Config\Miscellany\global-ignores` in both `HKLM` and `HKCU`.

- Linux/Unix - `~/.subversion/config`

2 - The `svn:ignore` property, which is set on directories (not files):

This is stored within the repo, so other users will have the same ignore files. Similar to how `.gitignore` works.

`svn:ignore` is applied to directories and is non-recursive or inherited. Any file or immediate subdirectory of the parent directory that matches the File Pattern will be excluded.

While SVN 1.8 adds the concept of "inherited properties", the `svn:ignore` property itself is ignored in non-immediate descendant directories:

  cd ~/myRepoRoot                             # Open an existing repo.
  echo "foo" > "ignoreThis.txt"                # Create a file called "ignoreThis.txt".

  svn status                                  # Check to see if the file is ignored or not.
  > ?    ./ignoreThis.txt
  > 1 unversioned file                        # ...it is NOT currently ignored.

  svn propset svn:ignore "ignoreThis.txt" .   # Apply the svn:ignore property to the "myRepoRoot" directory.
  svn status
  > 0 unversioned files                       # ...but now the file is ignored!

  cd subdirectory                             # now open a subdirectory.
  echo "foo" > "ignoreThis.txt"                # create another file named "ignoreThis.txt".

  svn status
  > ?    ./subdirectory/ignoreThis.txt        # ...and is is NOT ignored!
  > 1 unversioned file

(So the file `./subdirectory/ignoreThis` is not ignored, even though "`ignoreThis.txt`" is applied on the `.` repo root).

Therefore, to apply an ignore list recursively you must use `svn propset svn:ignore <filePattern> . --recursive`.

- This will create a copy of the property on every subdirectory.

- If the `<filePattern>` value is different in a child directory then the child's value completely overrides the parents, so there is no "additive" effect.

- So if you change the `<filePattern>` on the root `.`, then you must change it with `--recursive` to overwrite it on the child and descendant directories.

I note that the command-line syntax is counter-intuitive.

- I started-off assuming that you would ignore a file in SVN by typing something like `svn ignore pathToFileToIgnore.txt` however this is not how SVN's ignore feature works.

3- The `svn:global-ignores` property. Requires SVN 1.8 (June 2013):

This is similar to `svn:ignore`, except it makes use of SVN 1.8's "inherited properties" feature.

Compare to `svn:ignore`, the file pattern is automatically applied in every descendant directory (not just immediate children).

- This means that is unnecessary to set `svn:global-ignores` with the `--recursive` flag, as inherited ignore file patterns are automatically applied as they're inherited.

Running the same set of commands as in the previous example, but using `svn:global-ignores` instead:

  cd ~/myRepoRoot                                    # Open an existing repo
  echo "foo" > "ignoreThis.txt"                       # Create a file called "ignoreThis.txt"
  svn status                                         # Check to see if the file is ignored or not
  > ?    ./ignoreThis.txt
  > 1 unversioned file                               # ...it is NOT currently ignored

  svn propset svn:global-ignores "ignoreThis.txt" .
  svn status
  > 0 unversioned files                              # ...but now the file is ignored!

  cd subdirectory                                    # now open a subdirectory
  echo "foo" > "ignoreThis.txt"                       # create another file named "ignoreThis.txt"
  svn status
  > 0 unversioned files                              # the file is ignored here too!

For TortoiseSVN users:

This whole arrangement was confusing for me, because TortoiseSVN's terminology (as used in their Windows Explorer menu system) was initially misleading to me - I was unsure what the significance of the Ignore menu's "Add recursively", "Add *" and "Add " options. I hope this post explains how the Ignore feature ties-in to the SVN Properties feature. That said, I suggest using the command-line to set ignored files so you get a feel for how it works instead of using the GUI, and only using the GUI to manipulate properties after you're comfortable with the command-line.

Listing files that are ignored:

The command `svn status` will hide ignored files (that is, files that match an RCA `global-ignores` pattern, or match an immediate parent directory's `svn:ignore` pattern or match any ancesor directory's `svn:global-ignores` pattern.

Use the `--no-ignore` option to see those files listed. Ignored files have a status of `I`, then pipe the output to `grep` to only show lines starting with "I".

The command is:

svn status --no-ignore | grep "^I"

For example:

svn status
> ? foo                             # An unversioned file
> M modifiedFile.txt                # A versioned file that has been modified

svn status --no-ignore
> ? foo                             # An unversioned file
> I ignoreThis.txt                  # A file matching an svn:ignore pattern
> M modifiedFile.txt                # A versioned file that has been modified

svn status --no-ignore | grep "^I"
> I ignoreThis.txt                  # A file matching an svn:ignore pattern

ta-da!

Problem

How do I ignore files in Subversion? Also, how do I find files which are not under version control?

Original source