1
+ import asyncio
1
2
import subprocess
2
3
import sys
3
- from ollama import chat
4
- from ollama import ChatResponse
4
+ from ollama import AsyncClient
5
5
6
6
model = "gemma3:4b"
7
7
prompt = f"""
19
19
2. Summarize all changes into a single logical commit.
20
20
3. Write a concise commit message (max 72 characters) in the conventional commit style
21
21
"""
22
+ client = AsyncClient ()
22
23
23
- def get_changed_files ():
24
- # Git add all
24
+
25
+ async def get_changed_files ():
26
+ # Git add all
25
27
subprocess .run (
26
28
["git" , "add" , "." ],
27
29
capture_output = True , text = True
@@ -40,7 +42,8 @@ def get_changed_files():
40
42
# Union of both sets
41
43
return sorted (unstaged | staged )
42
44
43
- def get_diff_for_file (filename , staged = False ):
45
+
46
+ async def get_diff_for_file (filename , staged = False ):
44
47
cmd = ["git" , "diff" ]
45
48
if staged :
46
49
cmd .append ("--staged" )
@@ -49,34 +52,38 @@ def get_diff_for_file(filename, staged=False):
49
52
result = subprocess .run (cmd , capture_output = True , text = True )
50
53
return result .stdout
51
54
52
- def get_commit_messages (diff , files ):
55
+
56
+ async def get_commit_messages (diff , files ):
53
57
# Use the Ollama chat model to get commit messages
54
58
if len (diff ) == 0 or len (files ) == 0 :
55
59
return ""
56
60
try :
57
- response : ChatResponse = chat (model = model , messages = [
58
- {
59
- 'role' : 'user' ,
60
- 'content' : prompt .replace ("[Git Diff]" , diff ).replace ("[Changed Files and Types]" , files ),
61
- },
62
- ])
61
+ messages = [
62
+ {
63
+ 'role' : 'user' ,
64
+ 'content' : prompt .replace ("[Git Diff]" , diff ).replace ("[Changed Files and Types]" , files ),
65
+ },
66
+ ]
67
+ response = await client .chat (model = model , messages = messages )
63
68
return response ['message' ]['content' ]
64
69
except Exception :
65
70
return ""
66
-
67
- def diff_single_file (file ):
71
+
72
+
73
+ async def diff_single_file (file ):
68
74
commit_messages = []
69
- unstaged_diff = get_diff_for_file (file , staged = False ).strip ()
70
- staged_diff = get_diff_for_file (file , staged = True ).strip ()
71
- messages_staged_diff = get_commit_messages (staged_diff , file ).strip ()
72
- messages_unstaged_diff = get_commit_messages (unstaged_diff , file ).strip ()
75
+ unstaged_diff = ( await get_diff_for_file (file , staged = False ) ).strip ()
76
+ staged_diff = ( await get_diff_for_file (file , staged = True ) ).strip ()
77
+ messages_staged_diff = ( await get_commit_messages (staged_diff , file ) ).strip ()
78
+ messages_unstaged_diff = ( await get_commit_messages (unstaged_diff , file ) ).strip ()
73
79
if messages_staged_diff :
74
80
commit_messages .append (messages_staged_diff )
75
81
if messages_unstaged_diff :
76
82
commit_messages .append (messages_unstaged_diff )
77
83
return commit_messages
78
- ""
79
- def git_commit_everything (message ):
84
+
85
+
86
+ async def git_commit_everything (message ):
80
87
"""
81
88
Stages all changes (including new, modified, deleted files), commits with the given message,
82
89
and pushes the commit to the current branch on the default remote ('origin').
@@ -87,26 +94,28 @@ def git_commit_everything(message):
87
94
subprocess .run (['git' , 'add' , '-A' ], check = True )
88
95
# Commit with the provided message
89
96
subprocess .run (['git' , 'commit' , '-m' , message ], check = True )
90
-
91
- def main ():
92
- commit_single_file = True if (len (sys .argv ) > 1 and sys .argv [1 ] == "single_file" ) else False
93
- files = get_changed_files ()
97
+
98
+
99
+ async def main ():
100
+ commit_single_file = True if (
101
+ len (sys .argv ) > 1 and sys .argv [1 ] == "single_file" ) else False
102
+ files = await get_changed_files ()
94
103
if not files :
95
104
print ("No changes detected." )
96
105
return
97
106
98
107
all_commit_messages = []
99
108
for file in files :
100
109
print (f"{ file } " )
101
- commit_messages = diff_single_file (file )
110
+ commit_messages = await diff_single_file (file )
102
111
commit_messages_text = "\n " .join (commit_messages )
103
112
print (f"{ commit_messages_text } " )
104
113
if commit_single_file :
105
- git_commit_everything (commit_messages_text )
106
- else :
114
+ await git_commit_everything (commit_messages_text )
115
+ else :
107
116
all_commit_messages .extend (commit_messages )
108
117
if all_commit_messages and not commit_single_file :
109
- git_commit_everything ("\n " .join (all_commit_messages ))
118
+ await git_commit_everything ("\n " .join (all_commit_messages ))
110
119
111
120
if __name__ == "__main__" :
112
- main ()
121
+ asyncio . run ( main () )
0 commit comments