2424
2525REVIEWER_AGENT_TYPES = frozenset ({"review" , "code-reviewer" , "security-reviewer" })
2626MAX_REVIEW_REF_CHARS = 1024
27+ _FULL_OID_LENGTHS = frozenset ({40 , 64 })
2728
2829
2930class ReviewTarget (BaseModel ):
30- model_config = ConfigDict (frozen = True )
31+ model_config = ConfigDict (
32+ frozen = True ,
33+ extra = "allow" ,
34+ json_schema_extra = {"additionalProperties" : False },
35+ )
3136
3237 kind : ReviewTargetKind = Field (
3338 default = "auto" ,
@@ -96,6 +101,12 @@ def __init__(self, code: ReviewTargetErrorCode, brief: str, message: str) -> Non
96101
97102
98103def validate_review_target (target : ReviewTarget ) -> None :
104+ if target .model_extra :
105+ raise ReviewTargetResolutionError (
106+ ReviewTargetErrorCode .invalid_target ,
107+ "Invalid review target" ,
108+ "review_target contains unsupported fields." ,
109+ )
99110 ref = target .ref
100111 if target .kind == "commit" and ref is None :
101112 raise ReviewTargetResolutionError (
@@ -158,6 +169,7 @@ def _require_oid(result: GitCommandResult, *, message: str) -> str:
158169 or not value
159170 or "\n " in value
160171 or "\r " in value
172+ or len (value ) not in _FULL_OID_LENGTHS
161173 or any (char not in string .hexdigits for char in value )
162174 ):
163175 raise ReviewTargetResolutionError (
@@ -168,26 +180,48 @@ def _require_oid(result: GitCommandResult, *, message: str) -> str:
168180 return value .lower ()
169181
170182
183+ def _quiet_verification_is_missing (result : GitCommandResult ) -> bool :
184+ return (
185+ result .returncode == 1
186+ and not result .stdout
187+ and not result .stderr
188+ and not result .stdout_truncated
189+ and not result .stderr_truncated
190+ )
191+
192+
193+ def _raise_commit_verification_failed () -> None :
194+ raise ReviewTargetResolutionError (
195+ ReviewTargetErrorCode .git_failed ,
196+ "Review target unavailable" ,
197+ "Git could not verify the requested commit." ,
198+ )
199+
200+
171201async def _try_resolve_commit (cwd : str , ref : str ) -> str | None :
172202 result = await _run_resolver_git (
173- ["rev-parse" , "--verify" , "--end-of-options" , f"{ ref } ^{{commit}}" ],
203+ ["rev-parse" , "--verify" , "--quiet" , "-- end-of-options" , f"{ ref } ^{{commit}}" ],
174204 cwd ,
175205 )
176- if result . returncode != 0 :
206+ if _quiet_verification_is_missing ( result ) :
177207 return None
208+ if result .returncode != 0 :
209+ _raise_commit_verification_failed ()
178210 return _require_oid (result , message = "Git returned an invalid commit identifier." )
179211
180212
181213async def _resolve_commit (cwd : str , ref : str ) -> str :
182214 result = await _run_resolver_git (
183- ["rev-parse" , "--verify" , "--end-of-options" , f"{ ref } ^{{commit}}" ], cwd
215+ ["rev-parse" , "--verify" , "--quiet" , "-- end-of-options" , f"{ ref } ^{{commit}}" ], cwd
184216 )
185- if result . returncode != 0 :
217+ if _quiet_verification_is_missing ( result ) :
186218 raise ReviewTargetResolutionError (
187219 ReviewTargetErrorCode .missing_ref ,
188220 "Review target unavailable" ,
189221 "The requested Git ref does not resolve to a commit." ,
190222 )
223+ if result .returncode != 0 :
224+ _raise_commit_verification_failed ()
191225 return _require_oid (result , message = "Git returned an invalid commit identifier." )
192226
193227
@@ -293,14 +327,19 @@ async def _commit_details(cwd: str, target_sha: str) -> tuple[tuple[str, ...], s
293327 if parents_text .endswith ("\r " ):
294328 parents_text = parents_text [:- 1 ]
295329 tokens = parents_text .split ()
330+ oid_length = len (target_sha )
296331 if (
297332 parents_result .returncode != 0
298333 or parents_result .stdout_truncated
299334 or not tokens
300335 or "\n " in parents_text
301336 or "\r " in parents_text
302- or tokens [0 ].lower () != target_sha
303- or any (any (char not in string .hexdigits for char in token ) for token in tokens )
337+ or oid_length not in _FULL_OID_LENGTHS
338+ or tokens [0 ].lower () != target_sha .lower ()
339+ or any (
340+ len (token ) != oid_length or any (char not in string .hexdigits for char in token )
341+ for token in tokens
342+ )
304343 ):
305344 raise ReviewTargetResolutionError (
306345 ReviewTargetErrorCode .git_failed ,
0 commit comments