From b56014f295a23f314aa8fc902d599644cdc0fc39 Mon Sep 17 00:00:00 2001
From: Ankit Meel <ankitm>
Date: Thu, 24 Sep 2020 17:21:44 +1000
Subject: [PATCH] make format: add option to format only edited files

Ref D8991
---
 utils_maintenance/clang_format_paths.py | 33 ++++++++++++++++++-------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/utils_maintenance/clang_format_paths.py b/utils_maintenance/clang_format_paths.py
index 0f8f16d..3380d9c 100755
--- a/utils_maintenance/clang_format_paths.py
+++ b/utils_maintenance/clang_format_paths.py
@@ -31,9 +31,9 @@ ignore_files = {
 }
 
 
-def compute_paths(paths):
+def compute_paths(paths, use_default_paths):
     # Optionally pass in files to operate on.
-    if not paths:
+    if use_default_paths:
         paths = (
             "intern/atomic",
             "intern/audaspace",
@@ -64,8 +64,11 @@ def compute_paths(paths):
     return paths
 
 
-def source_files_from_git(paths):
-    cmd = ("git", "ls-tree", "-r", "HEAD", *paths, "--name-only", "-z")
+def source_files_from_git(paths, changed_only):
+    if changed_only:
+        cmd = ("git", "diff", "HEAD", "--name-only", "-z", "--", *paths)
+    else:
+        cmd = ("git", "ls-tree", "-r", "HEAD", *paths, "--name-only", "-z")
     files = subprocess.check_output(cmd).split(b'\0')
     return [f.decode('ascii') for f in files]
 
@@ -159,6 +162,18 @@ def argparse_create():
         "(default=False)",
         required=False,
     )
+    parser.add_argument(
+        "--changed-only",
+        dest="changed_only",
+        default=False,
+        action='store_true',
+        help=(
+            "Format only edited files, including the staged ones. "
+            "Using this with \"paths\" will pick the edited files lying on those paths. "
+            "(default=False)"
+        ),
+        required=False,
+    )
     parser.add_argument(
         "paths",
         nargs=argparse.REMAINDER,
@@ -189,22 +204,22 @@ def main():
 
     args = argparse_create().parse_args()
 
-    use_default_paths = not bool(args.paths)
+    use_default_paths = not (bool(args.paths) or bool(args.changed_only))
 
-    paths = compute_paths(args.paths)
-    print("Operating on:")
+    paths = compute_paths(args.paths, use_default_paths)
+    print("Operating on:" + (" (%d changed paths)" % len(paths) if args.changed_only else ""))
     for p in paths:
         print(" ", p)
 
     files = [
-        f for f in source_files_from_git(paths)
+        f for f in source_files_from_git(paths, args.changed_only)
         if f.endswith(extensions)
         if f not in ignore_files
     ]
 
     # Always operate on all cmake files (when expanding tabs and no paths given).
     files_retab = [
-        f for f in source_files_from_git((".",) if use_default_paths else paths)
+        f for f in source_files_from_git((".",) if use_default_paths else paths, args.changed_only)
         if f.endswith(extensions_only_retab)
         if f not in ignore_files
     ]
-- 
GitLab