@@ -155,3 +155,184 @@ def test_git_mv_pre_commit_scan() -> None:
155
155
for diff in diff_index :
156
156
file_path = get_path_by_os (get_diff_file_path (diff , repo = repo ))
157
157
assert file_path == renamed_path
158
+
159
+
160
+ class TestGetDiffFilePath :
161
+ """Test the get_diff_file_path function with various diff scenarios."""
162
+
163
+ def test_diff_with_b_blob_and_working_tree (self ) -> None :
164
+ """Test that blob.abspath is returned when b_blob is available and repo has a working tree."""
165
+ with temporary_git_repository () as (temp_dir , repo ):
166
+ test_file = os .path .join (temp_dir , 'test_file.py' )
167
+ with open (test_file , 'w' ) as f :
168
+ f .write ("print('original content')" )
169
+
170
+ repo .index .add (['test_file.py' ])
171
+ repo .index .commit ('Initial commit' )
172
+
173
+ with open (test_file , 'w' ) as f :
174
+ f .write ("print('modified content')" )
175
+
176
+ repo .index .add (['test_file.py' ])
177
+
178
+ # Get diff of staged changes
179
+ head_ref = get_safe_head_reference_for_diff (repo )
180
+ diff_index = repo .index .diff (head_ref )
181
+
182
+ assert len (diff_index ) == 1
183
+
184
+ result = get_diff_file_path (diff_index [0 ], repo = repo )
185
+
186
+ assert result == test_file
187
+ assert os .path .isabs (result )
188
+
189
+ def test_diff_with_a_blob_only_and_working_tree (self ) -> None :
190
+ """Test that a_blob.abspath is used when b_blob is None but a_blob exists."""
191
+ with temporary_git_repository () as (temp_dir , repo ):
192
+ test_file = os .path .join (temp_dir , 'to_delete.py' )
193
+ with open (test_file , 'w' ) as f :
194
+ f .write ("print('will be deleted')" )
195
+
196
+ repo .index .add (['to_delete.py' ])
197
+ repo .index .commit ('Initial commit' )
198
+
199
+ os .remove (test_file )
200
+ repo .index .remove (['to_delete.py' ])
201
+
202
+ # Get diff of staged changes
203
+ head_ref = get_safe_head_reference_for_diff (repo )
204
+ diff_index = repo .index .diff (head_ref )
205
+
206
+ assert len (diff_index ) == 1
207
+
208
+ result = get_diff_file_path (diff_index [0 ], repo = repo )
209
+
210
+ assert result == test_file
211
+ assert os .path .isabs (result )
212
+
213
+ def test_diff_with_b_path_fallback (self ) -> None :
214
+ """Test that b_path is used with working_tree_dir when blob is not available."""
215
+ with temporary_git_repository () as (temp_dir , repo ):
216
+ test_file = os .path .join (temp_dir , 'new_file.py' )
217
+ with open (test_file , 'w' ) as f :
218
+ f .write ("print('new file')" )
219
+
220
+ repo .index .add (['new_file.py' ])
221
+
222
+ # for new files, there's no a_blob
223
+ head_ref = get_safe_head_reference_for_diff (repo )
224
+ diff_index = repo .index .diff (head_ref )
225
+ diff = diff_index [0 ]
226
+
227
+ assert len (diff_index ) == 1
228
+
229
+ result = get_diff_file_path (diff , repo = repo )
230
+ assert result == test_file
231
+ assert os .path .isabs (result )
232
+
233
+ result = get_diff_file_path (diff , relative = True , repo = repo )
234
+ assert test_file .endswith (result )
235
+ assert not os .path .isabs (result )
236
+
237
+ def test_diff_with_a_path_fallback (self ) -> None :
238
+ """Test that a_path is used when b_path is None."""
239
+ with temporary_git_repository () as (temp_dir , repo ):
240
+ test_file = os .path .join (temp_dir , 'deleted_file.py' )
241
+ with open (test_file , 'w' ) as f :
242
+ f .write ("print('will be deleted')" )
243
+
244
+ repo .index .add (['deleted_file.py' ])
245
+ repo .index .commit ('Initial commit' )
246
+
247
+ # for deleted files, b_path might be None, so a_path should be used
248
+ os .remove (test_file )
249
+ repo .index .remove (['deleted_file.py' ])
250
+
251
+ head_ref = get_safe_head_reference_for_diff (repo )
252
+ diff_index = repo .index .diff (head_ref )
253
+
254
+ assert len (diff_index ) == 1
255
+ diff = diff_index [0 ]
256
+
257
+ result = get_diff_file_path (diff , repo = repo )
258
+ assert result == test_file
259
+ assert os .path .isabs (result )
260
+
261
+ result = get_diff_file_path (diff , relative = True , repo = repo )
262
+ assert test_file .endswith (result )
263
+ assert not os .path .isabs (result )
264
+
265
+ def test_diff_without_repo (self ) -> None :
266
+ """Test behavior when repo is None."""
267
+ with temporary_git_repository () as (temp_dir , repo ):
268
+ test_file = os .path .join (temp_dir , 'test.py' )
269
+ with open (test_file , 'w' ) as f :
270
+ f .write ("print('test')" )
271
+
272
+ repo .index .add (['test.py' ])
273
+ head_ref = get_safe_head_reference_for_diff (repo )
274
+ diff_index = repo .index .diff (head_ref )
275
+
276
+ assert len (diff_index ) == 1
277
+ diff = diff_index [0 ]
278
+
279
+ result = get_diff_file_path (diff , repo = None )
280
+
281
+ expected_path = diff .b_path or diff .a_path
282
+ assert result == expected_path
283
+ assert not os .path .isabs (result )
284
+
285
+ def test_diff_with_bare_repository (self ) -> None :
286
+ """Test behavior when the repository has no working tree directory."""
287
+ with tempfile .TemporaryDirectory () as temp_dir :
288
+ bare_repo = Repo .init (temp_dir , bare = True )
289
+
290
+ try :
291
+ # Create a regular repo to push to the bare repo
292
+ with tempfile .TemporaryDirectory () as work_dir :
293
+ work_repo = Repo .init (work_dir , b = 'main' )
294
+ try :
295
+ test_file = os .path .join (work_dir , 'test.py' )
296
+ with open (test_file , 'w' ) as f :
297
+ f .write ("print('test')" )
298
+
299
+ work_repo .index .add (['test.py' ])
300
+ work_repo .index .commit ('Initial commit' )
301
+
302
+ work_repo .create_remote ('origin' , temp_dir )
303
+ work_repo .remotes .origin .push ('main:main' )
304
+
305
+ with open (test_file , 'w' ) as f :
306
+ f .write ("print('modified')" )
307
+ work_repo .index .add (['test.py' ])
308
+
309
+ # Get diff
310
+ diff_index = work_repo .index .diff ('HEAD' )
311
+ assert len (diff_index ) == 1
312
+ diff = diff_index [0 ]
313
+
314
+ # Test with bare repo (no working_tree_dir)
315
+ result = get_diff_file_path (diff , repo = bare_repo )
316
+
317
+ # Should return a relative path since bare repo has no working tree
318
+ expected_path = diff .b_path or diff .a_path
319
+ assert result == expected_path
320
+ assert not os .path .isabs (result )
321
+ finally :
322
+ work_repo .close ()
323
+ finally :
324
+ bare_repo .close ()
325
+
326
+ def test_diff_with_no_paths (self ) -> None :
327
+ """Test behavior when the diff has neither a_path nor b_path."""
328
+ with temporary_git_repository () as (temp_dir , repo ):
329
+
330
+ class MockDiff :
331
+ def __init__ (self ) -> None :
332
+ self .a_path = None
333
+ self .b_path = None
334
+ self .a_blob = None
335
+ self .b_blob = None
336
+
337
+ result = get_diff_file_path (MockDiff (), repo = repo )
338
+ assert result is None
0 commit comments