I would like this feature too. I've attached a patch that I think should
work and then a very basic test case.
Also the following files should be added from GNU tar:
/* Arch. */
".arch-ids",
"{arch}",
"=RELEASE-ID",
"=meta-update",
"=update",
/* Bazaar. */
".bzr",
".bzrignore",
".bzrtags",
But I haven't used those version control systems so I am unsure which
ones are directories or not.
Thanks,
Collin
>From 9462055c1692934c02d39c9962268094b3e03113 Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sat, 6 Jul 2024 01:36:49 -0700
Subject: [PATCH 1/2] grep: add new --exclude-vcs option
* src/grep.c (struct vcs_file): New structure.
(vcs_file_table): New variable.
(EXCLUDE_VCS_OPTION, long_options, main): Add the --exclude-vcs
option.
* src/system.h (ARRAY_CARDINALITY): New definition.
---
src/grep.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/system.h | 4 ++++
2 files changed, 56 insertions(+)
diff --git a/src/grep.c b/src/grep.c
index 669238b..4c24e55 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -479,6 +479,36 @@ fflush_errno (void)
stdout_errno = errno;
}
+struct vcs_file
+{
+ const char *name;
+ bool directory;
+};
+
+static struct vcs_file const vcs_file_table[] =
+{
+ /* CVS. */
+ {"CVS", true},
+ {".cvsignore", false},
+ /* RCS. */
+ {"RCS", true},
+ /* SCCS. */
+ {"SCCS", true},
+ /* Subversion. */
+ {".svn", true},
+ /* Git. */
+ {".git", true},
+ {".gitignore", false},
+ {".gitattributes", false},
+ {".gitmodules", false},
+ /* Mercurial. */
+ {".hg", true},
+ {".hgignore", false},
+ {".hgtags", false},
+ /* Darcs. */
+ {"_darcs", true},
+};
+
static struct exclude *excluded_patterns[2];
static struct exclude *excluded_directory_patterns[2];
/* Short options. */
@@ -493,6 +523,7 @@ enum
EXCLUDE_DIRECTORY_OPTION,
EXCLUDE_OPTION,
EXCLUDE_FROM_OPTION,
+ EXCLUDE_VCS_OPTION,
GROUP_SEPARATOR_OPTION,
INCLUDE_OPTION,
LINE_BUFFERED_OPTION,
@@ -521,6 +552,7 @@ static struct option const long_options[] =
{"exclude", required_argument, nullptr, EXCLUDE_OPTION},
{"exclude-from", required_argument, nullptr, EXCLUDE_FROM_OPTION},
{"exclude-dir", required_argument, nullptr, EXCLUDE_DIRECTORY_OPTION},
+ {"exclude-vcs", no_argument, nullptr, EXCLUDE_VCS_OPTION},
{"file", required_argument, nullptr, 'f'},
{"files-with-matches", no_argument, nullptr, 'l'},
{"files-without-match", no_argument, nullptr, 'L'},
@@ -2806,6 +2838,26 @@ main (int argc, char **argv)
}
break;
+ case EXCLUDE_VCS_OPTION:
+ for (int cmd = 0; cmd < 2; ++cmd)
+ {
+ if (!excluded_patterns[cmd])
+ excluded_patterns[cmd] = new_exclude ();
+ if (!excluded_directory_patterns[cmd])
+ excluded_directory_patterns[cmd] = new_exclude ();
+ for (idx_t i = 0; i < ARRAY_CARDINALITY (vcs_file_table); ++i)
+ {
+ struct vcs_file file = vcs_file_table[i];
+ if (file.directory)
+ add_exclude (excluded_directory_patterns[cmd], file.name,
+ exclude_options (cmd));
+ else
+ add_exclude (excluded_patterns[cmd], file.name,
+ exclude_options (cmd));
+ }
+ }
+ break;
+
case GROUP_SEPARATOR_OPTION:
group_separator = optarg;
break;
diff --git a/src/system.h b/src/system.h
index 2a6611e..2266b96 100644
--- a/src/system.h
+++ b/src/system.h
@@ -129,4 +129,8 @@ __asan_unpoison_memory_region (void const volatile *addr, size_t size) { }
# define IGNORE_DUPLICATE_BRANCH_WARNING(exp) exp
#endif
+#ifndef ARRAY_CARDINALITY
+# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+#endif
+
#endif
--
2.45.2
>From 94caab87b280b56fb84ac6a495a12616db3124d4 Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sat, 6 Jul 2024 02:03:54 -0700
Subject: [PATCH 2/2] tests: add test for --exclude-vcs
* tests/exclude-vcs: New file.
* tests/Makefile.am (TESTS): Add exclude-vcs.
---
tests/Makefile.am | 1 +
tests/exclude-vcs | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100755 tests/exclude-vcs
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9b647c4..3ea34c0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -109,6 +109,7 @@ TESTS = \
equiv-classes \
ere \
euc-mb \
+ exclude-vcs \
false-match-mb-non-utf8 \
fedora \
fgrep-infloop \
diff --git a/tests/exclude-vcs b/tests/exclude-vcs
new file mode 100755
index 0000000..8b00533
--- /dev/null
+++ b/tests/exclude-vcs
@@ -0,0 +1,41 @@
+#!/bin/sh
+# Check --exclude-vcs works as expected.
+
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+fail=0
+
+# Create VCS directories in the current directory and a child directory.
+for directory in CVS RCS .svn .git .hg _darcs; do
+ mkdir -p "$directory" || framework_failure_
+ mkdir -p "x/$directory" || framework_failure_
+ echo "abc" > "$directory/file" || framework_failure_
+ echo "abc" > "x/$directory/file" || framework_failure_
+done
+
+grep -r --exclude-vcs 'abc' && fail=1
+
+# Create VCS files in the current directory and a child directory.
+for file in .gitignore .cvsignore .hgignore; do
+ echo "abc" > "$file" || framework_failure_
+ echo "abc" > "x/$file" || framework_failure_
+done
+
+grep -r --exclude-vcs 'abc' && fail=1
+
+Exit $fail
--
2.45.2