Exclusions on negatives does not seem to work

Hi all,

Currently trying to set up a backup scheduled task in my system. I have restic (0.9.6) running in a container, and I am trying to backup certain files in a folder. The data is present in my container.

However, trying to run the backup command with exclusions does not seem to work the way I think it does. Basically, running this command:

restic -r myrepo backup /my/subfolder --exclude '*'

Does what you expect it to, it creates a snapshot with no files. In my use case, I only want to backup some config xml files. So I want to use a negation on the exclusion like:

restic -r myrepo backup /my/subfolder --exclude '!*/*config.xml'

However, this will start taking the backup of the entire subfolder. I even tried excluding just ‘config.xml’ and that excluded all files with this name. Is my version of restic just not compatible with negation? It’s a few minor versions higher than what is on the docs and there they have exclusions as regex, so ideally this should work

Do you realise that restic is now v0.16.0? Any reason you use one from 2019?

Not saying that upgrading will solve your problem 100% - but a lot of things were fixed and improved in the last 4 years…

According to this forum post, negative exclusion wasn’t added until restic v0.13.0 (release notes, issue, PR). So it seems you will need to update the restic version in the container if you want to make use of them.

I had a look, but can’t see any negative exclusions in the docs for 0.9.6, only for more recent releases. Could you share where you saw the negative exclusions in the docs?

@shd2h I actually went through the hassle and manually installed version 0.15.1 (internal repos and whatnot).

I confirmed in a restic version I am on version 0.15.1.

However, it still does not seem to work. I tried all examples I could find:
'restic -r myrepo backup /my/subfolder --exclude '!*/*config.xml'
'restic -r myrepo backup /my/subfolder --exclude '!config.xml'
'restic -r myrepo backup /my/subfolder --exclude '* !config.xml'

And then I tried a file, as I though the Git ignore style should dictate it as a file:

$HOME/*
!$HOME/*/config.xml

And then including this using the --exclude-file flag. Nothing seems to work.

So far what I’m getting is, --exclude does not allow negatives, only in the exclude file, and that is only allowed on directories not files?

Just in case I was confusing before, I’ll explain my use-case again:
I am trying to start a backup of my my/subfolder. Inside this subfolder, there are instances of config.xml files in all different paths. I want restic to ONLY backup these files, so I would like to have an exclusion rule like “Exclude_everything Negative_exclude_config.xml”. Is this even possible?

Yeah, after further review and experimentation, I don’t think exclude does what you want. This line in the docs seems to explain why:

It works similarly to gitignore, with the same limitation: once a directory is excluded, it is not possible to include files inside the directory.

So it seems you can’t exclude the parent dir, then include individual files inside it.

The above said, if you just want to backup the xml files, it’s simple enough to pass that as the pattern to backup:

restic backup /my/dir/**/config.xml

Full example:

[user@system target]$ ls -lthR
.:
total 4.0K
drwxr-xr-x. 2 user user 80 Aug 19 12:48 2
drwxr-xr-x. 2 user user 80 Aug 19 12:48 1
-rw-r--r--. 1 user user 44 Aug 19 12:25 excludeme

./2:
total 4.0K
-rw-r--r--. 1 user user 44 Aug 19 12:48 excludeme
-rw-r--r--. 1 user user  0 Aug 19 12:39 config.xml

./1:
total 4.0K
-rw-r--r--. 1 user user  0 Aug 19 12:39 config.xml
-rw-r--r--. 1 user user 37 Aug 19 12:25 excludeme
[user@system target]$ restic -r /tmp/repo backup /tmp/target/**/config.xml
enter password for repository: 
repository 253d2671 opened (version 2, compression level auto)
found 3 old cache directories in /home/user/.cache/restic, run `restic cache --cleanup` to remove them
using parent snapshot 57cc665d

Files:           0 new,     0 changed,     2 unmodified
Dirs:            0 new,     4 changed,     0 unmodified
Added to the repository: 1.834 KiB (1.151 KiB stored)

processed 2 files, 0 B in 0:00
snapshot fac61e30 saved
[user@system target]$ restic -r /tmp/repo ls fac61e30
enter password for repository: 
repository 253d2671 opened (version 2, compression level auto)
found 3 old cache directories in /home/user/.cache/restic, run `restic cache --cleanup` to remove them
snapshot fac61e30 of [/tmp/target/1/config.xml /tmp/target/2/config.xml] filtered by [] at 2023-08-19 12:48:44.680539158 +0100 BST):
/tmp
/tmp/target
/tmp/target/1
/tmp/target/1/config.xml
/tmp/target/2
/tmp/target/2/config.xml
[user@system target]$

Does the above do what you’re after? If not you might want to look at using –files-from or similar to pass a more complex listing of patterns to restic.

This cannot work as restic never check the contents of a folder that is excluded. That is if you exclude /my/subfolder then negative patterns within that folder (e.g. !/my/subfolder/config.xml) cannot work.

See Allow excluding/negative-excluding directories only – give meaning to trailing slashes · Issue #4399 · restic/restic · GitHub and Only include some specific file extensions in backup for a more detailed discussion of that behavior.