]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
tar: add option --exclude-vcs
authorMartin Matuska <martin@matuska.org>
Sat, 13 Apr 2019 22:02:31 +0000 (00:02 +0200)
committerMartin Matuska <martin@matuska.org>
Sat, 13 Apr 2019 22:04:12 +0000 (00:04 +0200)
Fixes #999

Makefile.am
tar/bsdtar.1
tar/bsdtar.c
tar/bsdtar.h
tar/cmdline.c
tar/test/CMakeLists.txt
tar/test/test_option_exclude_vcs.c [new file with mode: 0644]

index 186126bec2802ee058ac0457932ecb3188f45331..5cded0e8eec37debd1ad4274bf824a00e12f97ce 100644 (file)
@@ -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 \
index 132e1145794c898bc9898c34d7cd08e230d6cf01..4c0fe818f26215b78e50a216a3469a65b43c2ac9 100644 (file)
@@ -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
index e70b3929dea47208f659f32b568f4524020c1d1b..280a0a1607c55a793dcdc5490fd12a739888f806 100644 (file)
@@ -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;
index 543a228c907234682342f99eb1b2d38abd67104e..c61d568fd7483488331eafd00c67d600c6a8d5d5 100644 (file)
@@ -135,6 +135,7 @@ enum {
        OPTION_CHROOT,
        OPTION_CLEAR_NOCHANGE_FFLAGS,
        OPTION_EXCLUDE,
+       OPTION_EXCLUDE_VCS,
        OPTION_FFLAGS,
        OPTION_FORMAT,
        OPTION_GID,
index 66cf4c2d196f8ab5051a29ac2f54ed21bcefd791..21558e12df42d509f6978745b113f5553a06837f 100644 (file)
@@ -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 },
index d7de42d6ab62dae4a7fe79aa183ee698895946c5..459d9dcb1eff210b0baeae9c9f26eb145eb99aa5 100644 (file)
@@ -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 (file)
index 0000000..2021511
--- /dev/null
@@ -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");
+}