33import sys , os , re , argparse , json , subprocess
44import urllib .request , urllib .parse
55from typing import Generator , Dict , Any
6+ from pathlib import Path
67
78DEBUG = False
89DEBUG_PROMPT = False
@@ -143,18 +144,24 @@ def gemini_stream (api_key: str, model: str, prompt: str) -> Generator[str, None
143144def generate_commit_message (commit_hash , max_count = 99 ):
144145 """Generate a commit message for the given commit hash"""
145146 llm_stream , llm_name = configure_model_stream ()
147+ use_jj = locate_dominating_file ("." , ".jj" ) != None
146148 if DEBUG :
147- print ("EXEC: Running `git log ...`" , file = sys .stderr )
149+ print (f "EXEC: Running `{ 'jj' if use_jj else ' git' } log ...`" , file = sys .stderr )
148150 try :
149- git_log = "git -P log --no-color --format='%n========%nAuthor: %an <%ae>%n%n%B' --stat"
150-
151+ # Commands to list example history and diff
152+ if use_jj :
153+ vcs_log = """jj log --no-pager --no-graph --color=never --stat """
154+ vcs_log += """-T '"\n ========\n Author: "++coalesce(self.author().name(),self.author().email())++"\n \n "++description++"\n "' """
155+ vcs_diff = vcs_log + f"""--git -r '{ commit_hash } ' """
156+ vcs_log += f"""-n { max_count } -r '..{ commit_hash } ' --reversed """
157+ else :
158+ vcs_log = """git -P log --no-color --stat --format='%n========%nAuthor: %an%n%n%B' """
159+ vcs_diff = vcs_log + f"""-p '{ commit_hash } ^!' """
160+ vcs_log += f"""-n { max_count } '{ commit_hash } ' --reverse """
151161 # Get the diff for the specific commit
152- diff_cmd = f"{ git_log } -p '{ commit_hash } ^!'"
153- diff = subprocess .check_output (diff_cmd , shell = True , text = True )
154-
155- # Get examples from recent commits
156- examples_cmd = f"{ git_log } --reverse -n{ max_count } "
157- examples = subprocess .check_output (examples_cmd , shell = True , text = True )
162+ diff = subprocess .check_output (vcs_diff , shell = True , text = True )
163+ # Get example messages from recent commits
164+ examples = subprocess .check_output (vcs_log , shell = True , text = True )
158165 except subprocess .CalledProcessError as e :
159166 print (f"{ sys .argv [0 ]} : Failed to execute git command: { e } " , file = sys .stderr )
160167 sys .exit (2 )
@@ -174,13 +181,15 @@ def generate_commit_message (commit_hash, max_count=99):
174181 if DEBUG_PROMPT :
175182 print ("PROMPT:" , file = sys .stderr )
176183 print (constructed_prompt , file = sys .stderr )
184+ # Path('/tmp/prompt.txt').write_text (constructed_prompt) # 'a'
177185 iterable = llm_stream (constructed_prompt )
178186 if DEBUG :
179187 print ("HTTP: Starting LLM request" , file = sys .stderr )
180188 tidy_print (iterable )
181189
182190def output (text_to_print : str ):
183191 """Writes the given text to standard output and flushes."""
192+ text_to_print = re .sub (r' +(?=\n)' , '' , text_to_print )
184193 sys .stdout .write (text_to_print )
185194 sys .stdout .flush ()
186195 if DUP_OUTPUT :
@@ -213,6 +222,14 @@ def tidy_print (iterable):
213222 if not buffer .endswith ('\n ' ):
214223 output ('\n ' )
215224
225+ def locate_dominating_file (start , name ):
226+ p = Path (start ).resolve ()
227+ while p != p .parent :
228+ if (p / name ).exists ():
229+ return str (p )
230+ p = p .parent
231+ return None
232+
216233def main ():
217234 if '--llm-help' in sys .argv :
218235 print (LLM_HELP .strip ())
0 commit comments