rustic icon indicating copy to clipboard operation
rustic copied to clipboard

Include and exclude globs cause all files to be ignored in backup

Open DianaNites opened this issue 2 years ago • 6 comments

I'm trying to exclude some directories from my backup, and using globs to do so per this discussion

Using any include glob causes every single file to be ignored in the backup, but leaves directories. It will report Files: 0 new, 0 changed, 0 unchanged and the resulting snapshot reports 0 files, however many dirs it found, and 0 bytes size.

The behavior does not depend on the order of the globs.

My use-case for this is I want to ignore a large directory, steam games, by "default". But some games store their saves next to them, so they need to be backed up. The behavior I expect is that explictly providing a path later in the list will "override" or "inject" it, ignoring the exclusion. I explictly put it there, after all.

Writing this I've realized that adding it as an entirely separate backup source kind of achieves this, but then as i understand it, it would create a ton of disconnect snapshots for all the different paths and generally be rather annoying and unwieldy, as well as very verbose?

config
[[backup.sources]]
source = "/some/path"
glob = [
    "!/some/path/to/exclude",

"/some/path/to/exclude/some/exception",

# Or

    "/some/exception",
]

System

rustic 0.5.4 6.3.9-arch1-1

DianaNites avatar Jun 25 '23 03:06 DianaNites

~~It seems that include glob is not working at all... when I configure it, no files are backed up.~~

Nvm it works if I do an absolute path. But I'd expect relative path to work?

Basically this works:

[[backup.sources]]
source = "/backup"
glob = ["/backup/Pictures/**/*"]

This doesn't:

[[backup.sources]]
source = "/backup"
glob = ["Pictures/**/*"]

Sorry if unrelated.

will-molloy avatar Jul 20 '23 01:07 will-molloy

~It seems that include glob is not working at all... when I configure it, no files are backed up.~

Nvm it works if I do an absolute path. But I'd expect relative path to work?

Basically this works:

[[backup.sources]]
source = "/backup"
glob = ["/backup/Pictures/**/*"]

This doesn't:

[[backup.sources]]
source = "/backup"
glob = ["Pictures/**/*"]

Sorry if unrelated.

I just took a look at the code. Im not a rust dev

The filtering takes place in this section:

https://github.com/rustic-rs/rustic/blob/774604924fa56b17ae4715711df80c34b2dfd2cb/crates/rustic_core/src/backend/ignore.rs#L119-L130

When i understand this correctly, OverrideBuilder builds a list of matches for the glob's provided.

Now, OverrideBuilder, from the documentation, takes in a path in the "new" function: "Matching is done relative to the directory path provided."

The directory path provided to the function is "/". So when you provide the glob "Pictures/**/*", OverrideMatcher will actually prefix a "/" to it, so it creates matches for /Pictures/**/*.

With an absolute path this isnt a problem, as you can see when you, for example, try ls -l //sys/class/ on a GNU/Linux machine. So when you use the absolute glob in your example, it will just work fine.

cactushydrocodone avatar Jul 20 '23 23:07 cactushydrocodone

@DianaNites Sorry for the late answer - I somehow delayed the answer as I intended to start an effort about how to generally improve including/excluding. But then that topic got out of sight.

I think that a glob like this will work in your case:

glob = [
    "/some/path/to/exclude",
    "!/some/path/to/exclude/**",
    "/some/path/to/exclude/some/exception",
]

The problem is, if you exclude the complete /some/path/to/exclude/, it won't be even traversed and therefore your include pattern isn't even applied.

But I agree that this is absolutely not user-friendly, so I think we have to do something about this!

aawsome avatar Jul 22 '23 02:07 aawsome

@cactushydrocodone Thanks a lot for your analyis! I think you are right and using the OverrideBuilder with / obviously wasn't a good idea! I'll add a PR to change this.

aawsome avatar Jul 22 '23 02:07 aawsome