@@ -59,6 +59,15 @@ class GitShow(BaseModel):
5959class GitInit (BaseModel ):
6060 repo_path : str
6161
62+ class GitLogDateRange (BaseModel ):
63+ repo_path : str
64+ start_date : str
65+ end_date : str
66+
67+ class GitLogByDate (BaseModel ):
68+ repo_path : str
69+ date : str
70+
6271class GitTools (str , Enum ):
6372 STATUS = "git_status"
6473 DIFF_UNSTAGED = "git_diff_unstaged"
@@ -72,6 +81,8 @@ class GitTools(str, Enum):
7281 CHECKOUT = "git_checkout"
7382 SHOW = "git_show"
7483 INIT = "git_init"
84+ LOG_DATE_RANGE = "git_log_date_range"
85+ LOG_BY_DATE = "git_log_by_date"
7586
7687def git_status (repo : git .Repo ) -> str :
7788 return repo .git .status ()
@@ -147,6 +158,46 @@ def git_show(repo: git.Repo, revision: str) -> str:
147158 output .append (d .diff .decode ('utf-8' ))
148159 return "" .join (output )
149160
161+ def git_log_date_range (repo : git .Repo , start_date : str , end_date : str ) -> list [str ]:
162+ log_output = repo .git .log (
163+ '--since' , f"{ start_date } " ,
164+ '--until' , f"{ end_date } " ,
165+ '--format=%H%n%an%n%ad%n%s%n'
166+ ).split ('\n ' )
167+
168+ log = []
169+ # Process commits in groups of 4 (hash, author, date, message)
170+ for i in range (0 , len (log_output ), 4 ):
171+ if i + 3 < len (log_output ):
172+ log .append (
173+ f"Commit: { log_output [i ]} \n "
174+ f"Author: { log_output [i + 1 ]} \n "
175+ f"Date: { log_output [i + 2 ]} \n "
176+ f"Message: { log_output [i + 3 ]} \n "
177+ )
178+ return log
179+
180+ def git_log_by_date (repo : git .Repo , date : str ) -> list [str ]:
181+ log_output = repo .git .log (
182+ '--since' , f"{ date } 00:00:00" ,
183+ '--until' , f"{ date } 23:59:59" ,
184+ '--format=%H%n%an%n%ad%n%s%n'
185+ ).split ('\n ' )
186+
187+ log = []
188+ # Process commits in groups of 4 (hash, author, date, message)
189+ for i in range (0 , len (log_output ), 4 ):
190+ if i + 3 < len (log_output ):
191+ log .append (
192+ f"Commit: { log_output [i ]} \n "
193+ f"Author: { log_output [i + 1 ]} \n "
194+ f"Date: { log_output [i + 2 ]} \n "
195+ f"Message: { log_output [i + 3 ]} \n "
196+ )
197+ return log
198+
199+
200+
150201async def serve (repository : Path | None ) -> None :
151202 logger = logging .getLogger (__name__ )
152203
@@ -222,6 +273,16 @@ async def list_tools() -> list[Tool]:
222273 name = GitTools .INIT ,
223274 description = "Initialize a new Git repository" ,
224275 inputSchema = GitInit .schema (),
276+ ),
277+ Tool (
278+ name = GitTools .LOG_DATE_RANGE ,
279+ description = "Retrieve git commits within a specified date range" ,
280+ inputSchema = GitLogDateRange .schema (),
281+ ),
282+ Tool (
283+ name = GitTools .LOG_BY_DATE ,
284+ description = "Retrieve git commits for a specific date" ,
285+ inputSchema = GitLogByDate .schema (),
225286 )
226287 ]
227288
@@ -351,6 +412,27 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
351412 text = result
352413 )]
353414
415+ case GitTools .LOG_DATE_RANGE :
416+ log = git_log_date_range (
417+ repo ,
418+ arguments ["start_date" ],
419+ arguments ["end_date" ]
420+ )
421+ return [TextContent (
422+ type = "text" ,
423+ text = "Commit history:\n " + "\n " .join (log )
424+ )]
425+
426+ case GitTools .LOG_BY_DATE :
427+ log = git_log_by_date (
428+ repo ,
429+ arguments ["date" ]
430+ )
431+ return [TextContent (
432+ type = "text" ,
433+ text = "Commit history:\n " + "\n " .join (log )
434+ )]
435+
354436 case _:
355437 raise ValueError (f"Unknown tool: { name } " )
356438
0 commit comments