diff --git a/CMakeLists.txt b/CMakeLists.txt
index 924b690d26dff384f847c857a2d6c08e08d100f2..b45eae93b3e971674d12d97b0b72a439dc21459e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,8 +114,8 @@ endif ()
 # add call to ./do-copyright.py to run as unit-test-case
 add_test (NAME copyright_notices COMMAND ./do-copyright.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
-# add call to do-clang-format.sh checking to run as unit-test-case
-add_test (NAME clang_format COMMAND ./do-clang-format.sh check WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+# add call to do-clang-format.py checking to run as unit-test-case
+add_test (NAME clang_format COMMAND ./do-clang-format.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 if (WITH_PYTHIA)
   find_package (Pythia8) # optional
diff --git a/do-clang-format.py b/do-clang-format.py
new file mode 100755
index 0000000000000000000000000000000000000000..a0611fa637b82e3e0a61e581200067c317f48fff
--- /dev/null
+++ b/do-clang-format.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+"""
+Run clang-format with the style file in the CORSIKA repository.
+
+By default it finds new files and files with modifications with respect to the current master and prints the filenames which need clang-formatting. Returns 1 if there are files which need modifications and 0 otherwise, so it can be used as a test.
+"""
+import argparse
+import subprocess as subp
+import os
+import sys
+
+parser = argparse.ArgumentParser(description=__doc__)
+parser.add_argument('--apply', action="store_true",
+    help="Apply clang-format to files which need changes.")
+parser.add_argument("--all", action="store_true",
+    help="Check all files below current path instead of new/modified.")
+
+args = parser.parse_args()
+
+filelist = []
+if args.all:
+    for dirpath, dirnames, filenames in os.walk("."):
+        if "ThirdParty" in dirpath:
+            continue
+        for f in filenames:
+            if f.endswith(".h") or f.endswith(".cc"):
+                filename = os.path.join(dirpath, f)
+                if not os.path.islink(filename):
+                    filelist.append(filename)
+    if not filelist:
+        raise SystemExit("Error: You specified --all, but file list is empty. "
+                         "Did you run from the build directory?")
+else:
+    cmd = "git diff master --name-status"
+    for line in subp.check_output(cmd, shell=True).decode("utf8").strip().split("\n"):
+        if line.startswith("D"): continue
+        filelist.append(line[1:].lstrip())
+
+    cmd = "git ls-files --exclude-standard --others"
+    filelist += subp.check_output(cmd, shell=True).decode("utf8").strip().split("\n")
+    filelist = [x for x in filelist
+                if "ThirdParty" not in x and (x.endswith(".h") or x.endswith(".cc"))]
+
+cmd = "clang-format -style=file"
+if args.apply:
+    for filename in filelist:
+        subp.check_call(cmd.split() + ["-i", filename])
+else:
+    # only print files which need formatting
+    files_need_formatting = 0
+    for filename in filelist:
+        a = open(filename, "rb").read()
+        b = subp.check_output(cmd.split() + [filename])
+        if a != b:
+            files_need_formatting += 1
+            print(filename)
+    sys.exit(1 if files_need_formatting > 0 else 0)
diff --git a/do-clang-format.sh b/do-clang-format.sh
deleted file mode 100755
index 4141a193d64b0cbc25c12261b440b8c0cd1f84ca..0000000000000000000000000000000000000000
--- a/do-clang-format.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-command="clang-format -style=file `find . -iregex '^.*\.\(cc\|h\)$' -not -path './ThirdParty/*'`"
-
-if [ "$1" == "check" ];
-then
-    `! ${command}  -output-replacements-xml | grep -qc "<replacement "` || \
-        { echo "format-check FAILED!"; exit 1; }
-    echo "Congratulations: format-check succeeded"
-elif [ "$1" == "apply" ];
-then
-    ${command} -i
-else
-    echo "please use: ./do-clang-format.sh [check] or [apply]"
-fi