@@ -76,13 +76,19 @@ def _convert_to_pair_objects(pairs):
7676
7777
7878def _annotate_file_pair (d , a_dir , b_dir ):
79+ a_path = os .path .join (a_dir , d ['a' ]) if d ['a' ] else None
80+ b_path = os .path .join (b_dir , d ['b' ]) if d ['b' ] else None
81+
7982 # Attach image metadata if applicable.
8083 if is_image_diff (d ):
8184 d ['is_image_diff' ] = True
82- if d ['a' ]: d ['image_a' ] = _image_metadata (os . path . join ( a_dir , d [ 'a' ]) )
83- if d ['b' ]: d ['image_b' ] = _image_metadata (os . path . join ( b_dir , d [ 'b' ]) )
85+ if d ['a' ]: d ['image_a' ] = _image_metadata (a_path )
86+ if d ['b' ]: d ['image_b' ] = _image_metadata (b_path )
8487
85- # TODO: diffstats
88+ if a_path and b_path :
89+ d ['no_changes' ] = _are_files_identical (a_path , b_path )
90+ else :
91+ d ['no_changes' ] = False
8692
8793
8894def annotate_file_pairs (file_pairs , a_dir , b_dir ):
@@ -97,7 +103,7 @@ def annotate_file_pairs(file_pairs, a_dir, b_dir):
97103
98104def find_moves (diff , a_dir , b_dir ):
99105 def hash (d , path ):
100- return hashlib . sha512 ( open ( os .path .join (d , path )). read ()). digest ( )
106+ return _contentHash ( os .path .join (d , path ))
101107
102108 out = copy .deepcopy (diff )
103109 add_delete_pairs = defaultdict (lambda : [None ,None ])
@@ -144,6 +150,24 @@ def is_image(path):
144150 return False
145151
146152
153+ hash_cache = {}
154+ def _contentHash (path ):
155+ global hash_cache
156+ if path in hash_cache :
157+ return hash_cache [path ]
158+ sha = hashlib .sha512 (open (path ).read ()).digest ()
159+ hash_cache [path ] = sha
160+ return sha
161+
162+
163+ def _are_files_identical (path1 , path2 ):
164+ # Check if anything has changed.
165+ # Compare lengths & then checksums.
166+ if os .path .getsize (path1 ) != os .path .getsize (path2 ):
167+ return False
168+ return _contentHash (path1 ) == _contentHash (path2 )
169+
170+
147171def _image_metadata (path ):
148172 md = { 'num_bytes' : os .path .getsize (path ) }
149173 try :
0 commit comments