[llvm-branch-commits] [clang] release/23.x: [git-clang-format] Don't format the line preceding a deletion (#215946) (PR #219855)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Aug 30 15:16:50 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-format

Author: llvmbot

<details>
<summary>Changes</summary>

Backport e89830da7f4e6656b9ff54ea7695c31435a53ee4 fe0143b1a97484e10bc11b012ceb2c1ecd8bc38c

Requested by: @<!-- -->MaskRay

---
Full diff: https://github.com/llvm/llvm-project/pull/219855.diff


1 Files Affected:

- (modified) clang/tools/clang-format/git-clang-format (+30-16) 


``````````diff
diff --git a/clang/tools/clang-format/git-clang-format b/clang/tools/clang-format/git-clang-format
index d79b57e7f6e10..d9b2d501c00e3 100755
--- a/clang/tools/clang-format/git-clang-format
+++ b/clang/tools/clang-format/git-clang-format
@@ -202,6 +202,11 @@ def main():
         default=0,
         help="print extra information",
     )
+    p.add_argument(
+        "--whole-file",
+        action="store_true",
+        help="format whole file instead of only modified lines",
+    )
     p.add_argument(
         "--diff_from_common_commit",
         action="store_true",
@@ -231,8 +236,8 @@ def main():
     # When no commits are given explicitly and the pre-commit CI framework's
     # environment variables are set, use them to define the diff range.
     if not opts.args and not dash_dash:
-        from_ref = os.environ.get('PRE_COMMIT_FROM_REF')
-        to_ref = os.environ.get('PRE_COMMIT_TO_REF')
+        from_ref = os.environ.get("PRE_COMMIT_FROM_REF")
+        to_ref = os.environ.get("PRE_COMMIT_TO_REF")
         if from_ref and to_ref:
             opts.args = [from_ref, to_ref]
             if not opts.diff and not opts.diffstat:
@@ -256,7 +261,7 @@ def main():
         opts.binary = os.path.abspath(opts.binary)
 
     changed_lines = compute_diff_and_extract_lines(
-        commits, files, opts.staged, opts.diff_from_common_commit
+        commits, files, opts.staged, opts.whole_file, opts.diff_from_common_commit
     )
     if opts.verbose >= 1:
         ignored_files = set(changed_lines)
@@ -410,10 +415,12 @@ def get_object_type(value):
     return convert_string(stdout.strip())
 
 
-def compute_diff_and_extract_lines(commits, files, staged, diff_common_commit):
+def compute_diff_and_extract_lines(
+    commits, files, staged, whole_file, diff_common_commit
+):
     """Calls compute_diff() followed by extract_lines()."""
     diff_process = compute_diff(commits, files, staged, diff_common_commit)
-    changed_lines = extract_lines(diff_process.stdout)
+    changed_lines = extract_lines(diff_process.stdout, whole_file)
     diff_process.stdout.close()
     diff_process.wait()
     if diff_process.returncode != 0:
@@ -446,7 +453,7 @@ def compute_diff(commits, files, staged, diff_common_commit):
     return p
 
 
-def extract_lines(patch_file):
+def extract_lines(patch_file, whole_file):
     """Extract the changed lines in `patch_file`.
 
     The return value is a dictionary mapping filename to a list of (start_line,
@@ -461,17 +468,24 @@ def extract_lines(patch_file):
         match = re.search(r"^\+\+\+\ [^/]+/(.*)", line)
         if match:
             filename = match.group(1).rstrip("\r\n\t")
-        match = re.search(r"^@@ -[0-9,]+ \+(\d+)(,(\d+))?", line)
-        if match:
-            start_line = int(match.group(1))
-            line_count = 1
-            if match.group(3):
-                line_count = int(match.group(3))
-            if line_count == 0:
-                line_count = 1
-            if start_line == 0:
+            if whole_file:
+                # Initialize the key for filename but ensure ranges is an empty
+                # list. This will prevent any filtering in clang_format_to_blob().
+                matches[filename] = []
                 continue
-            matches.setdefault(filename, []).append(Range(start_line, line_count))
+        if not whole_file:
+            match = re.search(r"^@@ -[0-9,]+ \+(\d+)(,(\d+))?", line)
+            if match:
+                start_line = int(match.group(1))
+                line_count = 1
+                if match.group(3):
+                    line_count = int(match.group(3))
+                # A hunk that adds no lines is a pure deletion. start_line
+                # refers to the preceding line (0 when the deletion is at the
+                # start of a file), which the deletion left alone.
+                if line_count == 0:
+                    continue
+                matches.setdefault(filename, []).append(Range(start_line, line_count))
     return matches
 
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/219855


More information about the llvm-branch-commits mailing list