1
1
import argparse
2
- import json
3
2
import math
4
3
import os
4
+ import subprocess
5
5
from typing import Optional
6
6
from typing import Sequence
7
7
from typing import Set
8
8
9
9
from 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
12
11
13
12
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
20
17
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 )
22
31
23
32
24
33
def find_large_added_files (
@@ -30,7 +39,9 @@ def find_large_added_files(
30
39
# Find all added files that are also in the list of files pre-commit tells
31
40
# us about
32
41
retv = 0
33
- filenames_filtered = set (filenames ) - lfs_files ()
42
+ filenames_filtered = set (filenames )
43
+ filter_lfs_files (filenames_filtered )
44
+
34
45
if not enforce_all :
35
46
filenames_filtered &= added_files ()
36
47
0 commit comments