diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | tar/bsdtar.1 | 12 | ||||
-rw-r--r-- | tar/bsdtar.c | 31 | ||||
-rw-r--r-- | tar/bsdtar.h | 1 | ||||
-rw-r--r-- | tar/cmdline.c | 1 | ||||
-rw-r--r-- | tar/test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tar/test/test_option_exclude_vcs.c | 230 |
7 files changed, 277 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 186126be..5cded0e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -995,6 +995,7 @@ bsdtar_test_SOURCES= \ tar/test/test_option_b.c \ tar/test/test_option_b64encode.c \ tar/test/test_option_exclude.c \ + tar/test/test_option_exclude_vcs.c \ tar/test/test_option_fflags.c \ tar/test/test_option_gid_gname.c \ tar/test/test_option_grzip.c \ diff --git a/tar/bsdtar.1 b/tar/bsdtar.1 index 132e1145..4c0fe818 100644 --- a/tar/bsdtar.1 +++ b/tar/bsdtar.1 @@ -204,6 +204,18 @@ Do not process files or directories that match the specified pattern. Note that exclusions take precedence over patterns or filenames specified on the command line. +.It Fl Fl exclude-vcs +Do not process files or directories internally used by the +version control systems +.Sq CVS , +.Sq RCS , +.Sq SCCS , +.Sq SVN , +.Sq Arch , +.Sq Bazaar , +.Sq Mercurial +and +.Sq Darcs . .It Fl Fl fflags (c, r, u, x modes only) Archive or extract file flags. This is the reverse of diff --git a/tar/bsdtar.c b/tar/bsdtar.c index e70b3929..280a0a16 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -129,6 +129,28 @@ static void version(void) __LA_DEAD; (ARCHIVE_EXTRACT_SECURE_SYMLINKS \ | ARCHIVE_EXTRACT_SECURE_NODOTDOT) +static char const * const vcs_files[] = { + /* CVS */ + "CVS", ".cvsignore", + /* RCS */ + "RCS", + /* SCCS */ + "SCCS", + /* SVN */ + ".svn", + /* git */ + ".git", ".gitignore", ".gitattributes", ".gitmodules", + /* Arch */ + ".arch-ids", "{arch}", "=RELEASE-ID", "=meta-update", "=update", + /* Bazaar */ + ".bzr", ".bzrignore", ".bzrtags", + /* Mercurial */ + ".hg", ".hgignore", ".hgtags", + /* darcs */ + "_darcs", + NULL +}; + int main(int argc, char **argv) { @@ -318,6 +340,15 @@ main(int argc, char **argv) lafe_errc(1, 0, "Couldn't exclude %s\n", bsdtar->argument); break; + case OPTION_EXCLUDE_VCS: /* GNU tar */ + for(t=0; vcs_files[t]; t++) { + if (archive_match_exclude_pattern( + bsdtar->matching, + vcs_files[t]) != ARCHIVE_OK) + lafe_errc(1, 0, "Couldn't " + "exclude %s\n", vcs_files[t]); + } + break; case OPTION_FFLAGS: bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS; diff --git a/tar/bsdtar.h b/tar/bsdtar.h index 543a228c..c61d568f 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -135,6 +135,7 @@ enum { OPTION_CHROOT, OPTION_CLEAR_NOCHANGE_FFLAGS, OPTION_EXCLUDE, + OPTION_EXCLUDE_VCS, OPTION_FFLAGS, OPTION_FORMAT, OPTION_GID, diff --git a/tar/cmdline.c b/tar/cmdline.c index 66cf4c2d..21558e12 100644 --- a/tar/cmdline.c +++ b/tar/cmdline.c @@ -85,6 +85,7 @@ static const struct bsdtar_option { { "disable-copyfile", 0, OPTION_NO_MAC_METADATA }, { "exclude", 1, OPTION_EXCLUDE }, { "exclude-from", 1, 'X' }, + { "exclude-vcs", 0, OPTION_EXCLUDE_VCS }, { "extract", 0, 'x' }, { "fast-read", 0, 'q' }, { "fflags", 0, OPTION_FFLAGS }, diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt index d7de42d6..459d9dcb 100644 --- a/tar/test/CMakeLists.txt +++ b/tar/test/CMakeLists.txt @@ -40,6 +40,7 @@ IF(ENABLE_TAR AND ENABLE_TEST) test_option_b.c test_option_b64encode.c test_option_exclude.c + test_option_exclude_vcs.c test_option_fflags.c test_option_gid_gname.c test_option_grzip.c diff --git a/tar/test/test_option_exclude_vcs.c b/tar/test/test_option_exclude_vcs.c new file mode 100644 index 00000000..20215113 --- /dev/null +++ b/tar/test/test_option_exclude_vcs.c @@ -0,0 +1,230 @@ +/*- + * Copyright (c) 2019 Martin Matuska + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_option_exclude_vcs) +{ + assertMakeDir("in", 0755); + assertChdir("in"); + assertMakeFile("file", 0644, ""); + assertMakeDir("dir", 0755); + assertMakeDir("CVS", 0755); + assertMakeFile("CVS/fileattr", 0644, ""); + assertMakeFile(".cvsignore", 0644, ""); + assertMakeDir("RCS", 0755); + assertMakeFile("RCS/somefile", 0655, ""); + assertMakeDir("SCCS", 0755); + assertMakeFile("SCCS/somefile", 0655, ""); + assertMakeDir(".svn", 0755); + assertMakeFile(".svn/format", 0655, ""); + assertMakeDir(".git", 0755); + assertMakeFile(".git/config", 0655, ""); + assertMakeFile(".gitignore", 0644, ""); + assertMakeFile(".gitattributes", 0644, ""); + assertMakeFile(".gitmodules", 0644, ""); + assertMakeDir(".arch-ids", 0755); + assertMakeFile(".arch-ids/somefile", 0644, ""); + assertMakeDir("{arch}", 0755); + assertMakeFile("{arch}/somefile", 0644, ""); + assertMakeFile("=RELEASE-ID", 0644, ""); + assertMakeFile("=meta-update", 0644, ""); + assertMakeFile("=update", 0644, ""); + assertMakeDir(".bzr", 0755); + assertMakeDir(".bzr/checkout", 0755); + assertMakeFile(".bzrignore", 0644, ""); + assertMakeFile(".bzrtags", 0644, ""); + assertMakeDir(".hg", 0755); + assertMakeFile(".hg/dirstate", 0644, ""); + assertMakeFile(".hgignore", 0644, ""); + assertMakeFile(".hgtags", 0644, ""); + assertMakeDir("_darcs", 0755); + assertMakeFile("_darcs/format", 0644, ""); + assertChdir(".."); + + assertEqualInt(0, systemf("%s -c -C in -f included.tar .", testprog)); + assertEqualInt(0, + systemf("%s -c --exclude-vcs -C in -f excluded.tar .", testprog)); + + /* No flags, archive with vcs files */ + assertMakeDir("vcs-noexclude", 0755); + assertEqualInt(0, systemf("%s -x -C vcs-noexclude -f included.tar", + testprog)); + assertChdir("vcs-noexclude"); + assertFileExists("file"); + assertIsDir("dir", 0755); + assertIsDir("CVS", 0755); + assertFileExists("CVS/fileattr"); + assertFileExists(".cvsignore"); + assertIsDir("RCS", 0755); + assertFileExists("RCS/somefile"); + assertIsDir("SCCS", 0755); + assertFileExists("SCCS/somefile"); + assertIsDir(".svn", 0755); + assertFileExists(".svn/format"); + assertIsDir(".git", 0755); + assertFileExists(".git/config"); + assertFileExists(".gitignore"); + assertFileExists(".gitattributes"); + assertFileExists(".gitmodules"); + assertIsDir(".arch-ids", 0755); + assertFileExists(".arch-ids/somefile"); + assertIsDir("{arch}", 0755); + assertFileExists("{arch}/somefile"); + assertFileExists("=RELEASE-ID"); + assertFileExists("=meta-update"); + assertFileExists("=update"); + assertIsDir(".bzr", 0755); + assertIsDir(".bzr/checkout", 0755); + assertFileExists(".bzrignore"); + assertFileExists(".bzrtags"); + assertIsDir(".hg", 0755); + assertFileExists(".hg/dirstate"); + assertFileExists(".hgignore"); + assertFileExists(".hgtags"); + assertIsDir("_darcs", 0755); + assertFileExists("_darcs/format"); + assertChdir(".."); + + /* --exclude-vcs, archive with vcs files */ + assertMakeDir("vcs-exclude", 0755); + assertEqualInt(0, + systemf("%s -x --exclude-vcs -C vcs-exclude -f included.tar", testprog)); + assertChdir("vcs-exclude"); + assertFileExists("file"); + assertIsDir("dir", 0755); + assertFileNotExists("CVS"); + assertFileNotExists("CVS/fileattr"); + assertFileNotExists(".cvsignore"); + assertFileNotExists("RCS"); + assertFileNotExists("RCS/somefile"); + assertFileNotExists("SCCS"); + assertFileNotExists("SCCS/somefile"); + assertFileNotExists(".svn"); + assertFileNotExists(".svn/format"); + assertFileNotExists(".git"); + assertFileNotExists(".git/config"); + assertFileNotExists(".gitignore"); + assertFileNotExists(".gitattributes"); + assertFileNotExists(".gitmodules"); + assertFileNotExists(".arch-ids"); + assertFileNotExists(".arch-ids/somefile"); + assertFileNotExists("{arch}"); + assertFileNotExists("{arch}/somefile"); + assertFileNotExists("=RELEASE-ID"); + assertFileNotExists("=meta-update"); + assertFileNotExists("=update"); + assertFileNotExists(".bzr"); + assertFileNotExists(".bzr/checkout"); + assertFileNotExists(".bzrignore"); + assertFileNotExists(".bzrtags"); + assertFileNotExists(".hg"); + assertFileNotExists(".hg/dirstate"); + assertFileNotExists(".hgignore"); + assertFileNotExists(".hgtags"); + assertFileNotExists("_darcs"); + assertFileNotExists("_darcs/format"); + assertChdir(".."); + + /* --exclude-vcs, archive without vcs files */ + assertMakeDir("novcs-exclude", 0755); + assertEqualInt(0, + systemf("%s -x --exclude-vcs -C novcs-exclude -f excluded.tar", + testprog)); + assertChdir("novcs-exclude"); + assertFileExists("file"); + assertIsDir("dir", 0755); + assertFileNotExists("CVS"); + assertFileNotExists("CVS/fileattr"); + assertFileNotExists(".cvsignore"); + assertFileNotExists("RCS"); + assertFileNotExists("RCS/somefile"); + assertFileNotExists("SCCS"); + assertFileNotExists("SCCS/somefile"); + assertFileNotExists(".svn"); + assertFileNotExists(".svn/format"); + assertFileNotExists(".git"); + assertFileNotExists(".git/config"); + assertFileNotExists(".gitignore"); + assertFileNotExists(".gitattributes"); + assertFileNotExists(".gitmodules"); + assertFileNotExists(".arch-ids"); + assertFileNotExists(".arch-ids/somefile"); + assertFileNotExists("{arch}"); + assertFileNotExists("{arch}/somefile"); + assertFileNotExists("=RELEASE-ID"); + assertFileNotExists("=meta-update"); + assertFileNotExists("=update"); + assertFileNotExists(".bzr"); + assertFileNotExists(".bzr/checkout"); + assertFileNotExists(".bzrignore"); + assertFileNotExists(".bzrtags"); + assertFileNotExists(".hg"); + assertFileNotExists(".hg/dirstate"); + assertFileNotExists(".hgignore"); + assertFileNotExists(".hgtags"); + assertFileNotExists("_darcs"); + assertFileNotExists("_darcs/format"); + assertChdir(".."); + + /* No flags, archive without vcs files */ + assertMakeDir("novcs-noexclude", 0755); + assertEqualInt(0, + systemf("%s -x -C novcs-noexclude -f excluded.tar", testprog)); + assertChdir("novcs-noexclude"); + assertFileExists("file"); + assertIsDir("dir", 0755); + assertFileNotExists("CVS"); + assertFileNotExists("CVS/fileattr"); + assertFileNotExists(".cvsignore"); + assertFileNotExists("RCS"); + assertFileNotExists("RCS/somefile"); + assertFileNotExists("SCCS"); + assertFileNotExists("SCCS/somefile"); + assertFileNotExists(".svn"); + assertFileNotExists(".svn/format"); + assertFileNotExists(".git"); + assertFileNotExists(".git/config"); + assertFileNotExists(".gitignore"); + assertFileNotExists(".gitattributes"); + assertFileNotExists(".gitmodules"); + assertFileNotExists(".arch-ids"); + assertFileNotExists(".arch-ids/somefile"); + assertFileNotExists("{arch}"); + assertFileNotExists("{arch}/somefile"); + assertFileNotExists("=RELEASE-ID"); + assertFileNotExists("=meta-update"); + assertFileNotExists("=update"); + assertFileNotExists(".bzr"); + assertFileNotExists(".bzr/checkout"); + assertFileNotExists(".bzrignore"); + assertFileNotExists(".bzrtags"); + assertFileNotExists(".hg"); + assertFileNotExists(".hg/dirstate"); + assertFileNotExists(".hgignore"); + assertFileNotExists(".hgtags"); + assertFileNotExists("_darcs"); + assertFileNotExists("_darcs/format"); +} |