bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Incorrect recursive behaviour of --exclude-ignore, --exclude-vcs-ignores


From: Kirill Pushkaryov
Subject: Incorrect recursive behaviour of --exclude-ignore, --exclude-vcs-ignores
Date: Sun, 12 Sep 2021 22:47:23 +0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0

Hello!

I've previously posted this here in July 2020, but got no response at all and the problems are still present, so I decided to remind about this.

I consider the issues to be important, because inadvertent omission of files can be very damaging, e.g. to backups.

The original text follows.

I've found that --exclude-ignore option and --exclude-vcs-ignores with .cvsignore act recursively, which contradicts the manual. A trivial patch is attached.

The manual says (6.4):

" `--exclude-vcs-ignores'

    Before archiving a directory, see if it contains any of the following files: `cvsignore', `.gitignore', `.bzrignore', or `.hgignore'. If so, read ignore patterns from these files.

    The patterns are treated much as the corresponding VCS would treat them, i.e.:

    `.cvsignore'

        Contains shell-style globbing patterns that apply only to the directory where this file resides. No comments are allowed in the file. Empty lines are ignored.

<...>

 `--exclude-ignore=file'

    Before dumping a directory, tar checks if it contains file. If so, exclusion patterns are read from this file. The patterns affect only the directory itself.
`--exclude-ignore-recursive=file'

    Same as `--exclude-ignore', except that the patterns read affect both the directory where file resides and all its subdirectories."

By the way, a dot is missing in front of cvsignore in the second line above.

Nevertheless, both options currently (in the latest git revision 01dd89c) act recursively.

How to reproduce for --exclude-ignore:

mkdir test test/a
touch test/b test/a/b
echo b > test/.ign
tar -cvf test.tar --exclude-ignore=.ign test

Current result:

test/
test/.ign
test/a/

Expected result: test/a/b must not be excluded.

The same for --exclude-vcs-ignores:

mkdir test test/a
touch test/b test/a/b
echo b > test/.cvsignore
tar -cvf test.tar --exclude-vcs-ignores test

Current result:

test/
test/a/
test/.cvsignore

Expected result: test/a/b must not be excluded.

I suspect a bug in info_attach_exclist() (exclist.c:116):

      ent = xmalloc (sizeof (*ent));
      ent->excluded = ex;
      ent->flags = file->flags == EXCL_DEFAULT
                   ? file->flags : vcsfile->flags;
      ent->prev = tail;
      ent->next = NULL;

Here file is an exclusion file added by some options. The currently possible values of file->flags are as follows:

a) EXCL_DEFAULT corresponds to --exclude-vcs-ignores option and marks standard VCS exclusion files. Such entries are created by exclude_vcs_ignores();

b) EXCL_RECURSIVE corresponds to --exclude-ignore-recursive;

c) EXCL_NON_RECURSIVE corresponds to --exclude-ignore.

Currently neither EXCL_RECURSIVE nor EXCL_NON_RECURSIVE are propagated from file->flags to ent->flags. Moreover, EXCL_NON_RECURSIVE flag in vcsfile->flags of .cvsignore entry is dropped too, because for .cvsignore file->flags == EXCL_DEFAULT.

It looks like the condition in the code above is just erroneously inverted. I fixed this and the options started to work as expected.

--

WBR, Kirill Pushkaryov.

Attachment: exclist.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]