Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anchored excludes #604

Open
riastradh opened this issue Dec 20, 2023 · 1 comment
Open

Anchored excludes #604

riastradh opened this issue Dec 20, 2023 · 1 comment

Comments

@riastradh
Copy link

riastradh commented Dec 20, 2023

Suppose I have the following directory tree:

  • ./
    • foo
    • bar
    • a/
      • foo
      • bar

Suppose I want to exclude ./foo, but include everything else -- including ./a/foo.

  • If I use tarsnap -c ... --exclude ./foo ., that excludes both of them.
  • --include isn't open-ended, so I can't use it without enumerating everything else like ./bar too.
  • If I use tarsnap -c ... --exclude /foo ., that doesn't exclude anything.

This comment suggests the possibility of anchored matches for --exclude was considered incompletely and was meant to be re-considered:

tarsnap/tar/matching.c

Lines 70 to 73 in dfcc22d

* The matching logic here needs to be re-thought. I started out to
* try to mimic gtar's matching logic, but it's not entirely
* consistent. In particular 'tar -t' and 'tar -x' interpret patterns
* on the command line as anchored, but --exclude doesn't.

I can use some elaborate system of find(1) patterns piped to tarsnap to achieve the same result, but it would be nice if I could simply specify anchored path patterns in the exclusion file. I think the syntax of --exclude /foo is not currently useful so it could probably be used for this purpose, like in .gitignore files.

I realized this today when I discovered that the exclusion was broader than I intended, resulting in some files not being backed up when I thought they would be for years. (Fortunately, in my case, the files are not important.)

@gperciva
Copy link
Member

Right. The logic (and rationale) of --include and --exclude in BSD tar(1) is rather opaque, as we can see in all the questions on stackoverflow and related sites. That said, we wouldn't want to change the current behaviour, since that would break compatibility with tar (and with previous versions of tarsnap).

I'll look into current libarchive to see if/how they've addressed this, although an initial grep shows that comment is unchanged. I see that GNU tar(1) has a ton of --exclude options -- 12 of them! -- and that's not even counting the 8 options which changes the behaviour of exclude patterns.

As you mentioned, you could use some find(1) magic.

My personal strategy would be to use find with grep:

$ find . -type f | grep -v "^./foo$"
./bar
./a/foo
./a/bar

since I'm already familiar with grep, and I can never remember which find patterns are POSIX or not.

(I'm glad that you noticed the un-backed-up files!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants