1
1
import os
2
2
import tempfile
3
+ from collections .abc import Generator
4
+ from contextlib import contextmanager
3
5
4
6
from git import Repo
5
7
6
8
from cycode .cli import consts
7
9
from cycode .cli .files_collector .commit_range_documents import get_safe_head_reference_for_diff
8
10
9
11
12
+ @contextmanager
13
+ def git_repository (path : str ) -> Generator [Repo , None , None ]:
14
+ """Context manager for Git repositories that ensures proper cleanup on Windows."""
15
+ repo = Repo .init (path )
16
+ try :
17
+ yield repo
18
+ finally :
19
+ # Properly close the repository to release file handles
20
+ repo .close ()
21
+
22
+
23
+ @contextmanager
24
+ def temporary_git_repository () -> Generator [tuple [str , Repo ], None , None ]:
25
+ """Combined context manager for temporary directory with Git repository."""
26
+ with tempfile .TemporaryDirectory () as temp_dir , git_repository (temp_dir ) as repo :
27
+ yield temp_dir , repo
28
+
29
+
10
30
class TestGetSafeHeadReferenceForDiff :
11
31
"""Test the safe HEAD reference functionality for git diff operations."""
12
32
13
33
def test_returns_head_when_repository_has_commits (self ) -> None :
14
34
"""Test that HEAD is returned when the repository has existing commits."""
15
- with tempfile .TemporaryDirectory () as temp_dir :
16
- repo = Repo .init (temp_dir )
17
-
35
+ with temporary_git_repository () as (temp_dir , repo ):
18
36
test_file = os .path .join (temp_dir , 'test.py' )
19
37
with open (test_file , 'w' ) as f :
20
38
f .write ("print('test')" )
@@ -27,9 +45,7 @@ def test_returns_head_when_repository_has_commits(self) -> None:
27
45
28
46
def test_returns_empty_tree_hash_when_repository_has_no_commits (self ) -> None :
29
47
"""Test that an empty tree hash is returned when the repository has no commits."""
30
- with tempfile .TemporaryDirectory () as temp_dir :
31
- repo = Repo .init (temp_dir )
32
-
48
+ with temporary_git_repository () as (temp_dir , repo ):
33
49
result = get_safe_head_reference_for_diff (repo )
34
50
expected_empty_tree_hash = consts .GIT_EMPTY_TREE_OBJECT
35
51
assert result == expected_empty_tree_hash
@@ -40,9 +56,7 @@ class TestIndexDiffWithSafeHeadReference:
40
56
41
57
def test_index_diff_works_on_bare_repository (self ) -> None :
42
58
"""Test that index.diff works on repositories with no commits."""
43
- with tempfile .TemporaryDirectory () as temp_dir :
44
- repo = Repo .init (temp_dir )
45
-
59
+ with temporary_git_repository () as (temp_dir , repo ):
46
60
test_file = os .path .join (temp_dir , 'staged_file.py' )
47
61
with open (test_file , 'w' ) as f :
48
62
f .write ("print('staged content')" )
@@ -58,9 +72,7 @@ def test_index_diff_works_on_bare_repository(self) -> None:
58
72
59
73
def test_index_diff_works_on_repository_with_commits (self ) -> None :
60
74
"""Test that index.diff continues to work on repositories with existing commits."""
61
- with tempfile .TemporaryDirectory () as temp_dir :
62
- repo = Repo .init (temp_dir )
63
-
75
+ with temporary_git_repository () as (temp_dir , repo ):
64
76
initial_file = os .path .join (temp_dir , 'initial.py' )
65
77
with open (initial_file , 'w' ) as f :
66
78
f .write ("print('initial')" )
@@ -88,9 +100,7 @@ def test_index_diff_works_on_repository_with_commits(self) -> None:
88
100
89
101
def test_sequential_operations_on_same_repository (self ) -> None :
90
102
"""Test behavior when transitioning from bare to committed repository."""
91
- with tempfile .TemporaryDirectory () as temp_dir :
92
- repo = Repo .init (temp_dir )
93
-
103
+ with temporary_git_repository () as (temp_dir , repo ):
94
104
test_file = os .path .join (temp_dir , 'test.py' )
95
105
with open (test_file , 'w' ) as f :
96
106
f .write ("print('test')" )
0 commit comments