diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 34d2cba40b9..6d60f81c483 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -123,14 +123,14 @@ repos:
         entry: gdb/check-include-guards.py
         # All gdb header files, but not headers in the test suite.
         files: '^(gdb(support|server)?)/.*\.h$'
-        exclude: '.*/testsuite/.*'
+        exclude: &testsuite_files '.*/testsuite/.*'
       - id: &id1 check-gnu-style
         name: *id1
         language: python
         additional_dependencies: ['termcolor', 'unidiff']
         entry: gdb/contrib/check-gnu-style-pre-commit.sh
         files: '^(gdb(support|server)?)/.*\.(c|h|cc)$'
-        exclude: '.*/testsuite/.*'
+        exclude: *testsuite_files
         verbose: true
       - id: &id2 check-whitespace
         name: *id2
@@ -173,6 +173,13 @@ repos:
         args: [--config-check]
         additional_dependencies: ["pyyaml"]
         files: *pre_commit_config_file
+      - id: &id7 check-copies
+        name: *id7
+        language: unsupported_script
+        entry: gdb/contrib/check-copies.py
+        files: *gdb_files
+        exclude: *testsuite_files
+        require_serial: true
 
 # Local Variables:
 # indent-tabs-mode: nil
diff --git a/gdb/contrib/check-copies.py b/gdb/contrib/check-copies.py
new file mode 100755
index 00000000000..11c226bb9d2
--- /dev/null
+++ b/gdb/contrib/check-copies.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python3
+
+import subprocess
+import sys
+from itertools import chain
+
+# These files are required to be identical.
+required_list = [
+    ["gdb/.dir-locals.el", "gdbserver/.dir-locals.el", "gdbsupport/.dir-locals.el"],
+    ["gdb/.shellcheckrc", "gdbserver/.shellcheckrc", "gdbsupport/.shellcheckrc"],
+]
+
+
+def run_cmd(cmd, **kwargs):
+    res = subprocess.run(cmd, **kwargs)
+    if res.returncode != 0:
+        raise RuntimeError(
+            "command %s failed with exit status %s" % (cmd, res.returncode)
+        )
+    return res
+
+
+files = sys.argv[1:]
+always_check_files = list(chain.from_iterable(required_list))
+cmd = ["git", "ls-files", "--stage"] + files + always_check_files
+res = run_cmd(cmd, capture_output=True, text=True)
+
+hash_dict = {}
+for line in res.stdout.splitlines():
+    parts = line.split(maxsplit=3)
+    hash = parts[1]
+    file = parts[3]
+    hash_dict.setdefault(hash, []).append(file)
+
+copies = []
+for hash in hash_dict:
+    files = hash_dict[hash]
+    if len(files) == 1:
+        continue
+    copies.append(set(files))
+
+required_set = [set(r) for r in required_list]
+
+for required in required_set:
+    if required in copies:
+        continue
+    print("No longer copies: %s" % required)
+    sys.exit(1)
+
+for copy in copies:
+    if copy in required_set:
+        continue
+    print("Accidental copies found: %s" % copy)
+    sys.exit(1)
