11import argparse
2- import json
32import math
43import os
4+ import subprocess
55from typing import Optional
66from typing import Sequence
77from typing import Set
88
99from pre_commit_hooks .util import added_files
10- from pre_commit_hooks .util import CalledProcessError
11- from pre_commit_hooks .util import cmd_output
10+ from pre_commit_hooks .util import zsplit
1211
1312
14- def lfs_files () -> Set [str ]:
15- try :
16- # Introduced in git-lfs 2.2.0, first working in 2.2.1
17- lfs_ret = cmd_output ('git' , 'lfs' , 'status' , '--json' )
18- except CalledProcessError : # pragma: no cover (with git-lfs)
19- lfs_ret = '{"files":{}}'
13+ def filter_lfs_files (filenames : Set [str ]) -> None : # pragma: no cover (lfs)
14+ """Remove files tracked by git-lfs from the set."""
15+ if not filenames :
16+ return
2017
21- return set (json .loads (lfs_ret )['files' ])
18+ check_attr = subprocess .run (
19+ ('git' , 'check-attr' , 'filter' , '-z' , '--stdin' ),
20+ stdout = subprocess .PIPE ,
21+ stderr = subprocess .DEVNULL ,
22+ encoding = 'utf-8' ,
23+ check = True ,
24+ input = '\0 ' .join (filenames ),
25+ )
26+ stdout = zsplit (check_attr .stdout )
27+ for i in range (0 , len (stdout ), 3 ):
28+ filename , filter_tag = stdout [i ], stdout [i + 2 ]
29+ if filter_tag == 'lfs' :
30+ filenames .remove (filename )
2231
2332
2433def find_large_added_files (
@@ -30,7 +39,9 @@ def find_large_added_files(
3039 # Find all added files that are also in the list of files pre-commit tells
3140 # us about
3241 retv = 0
33- filenames_filtered = set (filenames ) - lfs_files ()
42+ filenames_filtered = set (filenames )
43+ filter_lfs_files (filenames_filtered )
44+
3445 if not enforce_all :
3546 filenames_filtered &= added_files ()
3647
0 commit comments