@@ -113,7 +113,7 @@ def cook(self):
113113 # Check conditions (union mode vs intersection mode)
114114 # Default is union mode (match any condition)
115115 # Search mode explanation:
116- # 1. Union Mode: Include commit if it matches ANY filter condition (email, username or keyword )
116+ # 1. Union Mode: Include commit if it matches ANY filter condition (email, username, keyword or commit hash )
117117 # Example: If email A and keyword B specified, include commits with email A OR containing keyword B
118118 # 2. Intersection Mode: Include commit only if it matches ALL specified filter conditions
119119 # Example: If email A and keyword B specified, include commits only with email A AND containing keyword B
@@ -123,16 +123,18 @@ def cook(self):
123123 union_mode = self .args .mode == "union" # Check mode based on args.mode
124124 if union_mode :
125125 self .logger .info ("[Search Mode] Using Union Mode - Match any condition" )
126- self .logger .info (" Union mode: commit included if it matches any email, username or keyword condition" )
126+ self .logger .info (" Union mode: commit included if it matches any email, username, keyword or commit hash condition" )
127127 self .logger .info (f" - Email conditions: { ', ' .join (self .args .email ) if self .args .email else 'none' } " )
128128 self .logger .info (f" - User conditions: { ', ' .join (self .args .user ) if self .args .user else 'none' } " )
129129 self .logger .info (f" - Keyword conditions: { ', ' .join (self .args .keyword ) if self .args .keyword else 'none' } " )
130+ self .logger .info (f" - Commit hash conditions: { ', ' .join (self .args .commit ) if self .args .commit else 'none' } " )
130131 else :
131132 self .logger .info ("[Search Mode] Using Intersection Mode - Must match all conditions" )
132133 self .logger .info (" Intersection mode: commit included only if it matches all specified conditions" )
133134 self .logger .info (f" - Email conditions: { ', ' .join (self .args .email ) if self .args .email else 'none' } (must match if specified)" )
134135 self .logger .info (f" - User conditions: { ', ' .join (self .args .user ) if self .args .user else 'none' } (must match if specified)" )
135136 self .logger .info (f" - Keyword conditions: { ', ' .join (self .args .keyword ) if self .args .keyword else 'none' } (must match if specified)" )
137+ self .logger .info (f" - Commit hash conditions: { ', ' .join (self .args .commit ) if self .args .commit else 'none' } (must match if specified)" )
136138
137139
138140 # Iterate through commits in all repos
@@ -144,7 +146,8 @@ def cook(self):
144146 # Include all commits if no filters specified
145147 if (not self .args .email or len (self .args .email ) == 0 ) and \
146148 (not self .args .user or len (self .args .user ) == 0 ) and \
147- (not self .args .keyword or len (self .args .keyword ) == 0 ):
149+ (not self .args .keyword or len (self .args .keyword ) == 0 ) and \
150+ (not self .args .commit or len (self .args .commit ) == 0 ):
148151 self .cooked_commits [repo_name ][commit_hash ] = commit_data
149152 continue
150153
@@ -171,6 +174,16 @@ def cook(self):
171174 should_include = True
172175 break
173176
177+ # Filter by commit hash (match any hash - support partial matching)
178+ if not should_include and self .args .commit and len (self .args .commit ) > 0 :
179+ # Check if any provided hash matches (partial or full)
180+ for provided_hash in self .args .commit :
181+ # support partial hash matching - check if provided hash is prefix of actual hash
182+ if commit_hash .lower ().startswith (provided_hash .lower ()) or \
183+ commit_data .get ("commit_hash" , "" ).lower ().startswith (provided_hash .lower ()):
184+ should_include = True
185+ break
186+
174187 # Add to processed data if matches any condition
175188 if should_include :
176189 self .cooked_commits [repo_name ][commit_hash ] = commit_data
@@ -183,6 +196,7 @@ def cook(self):
183196 has_email_filter = self .args .email and len (self .args .email ) > 0
184197 has_user_filter = self .args .user and len (self .args .user ) > 0
185198 has_keyword_filter = self .args .keyword and len (self .args .keyword ) > 0
199+ has_commit_filter = self .args .commit and len (self .args .commit ) > 0
186200
187201 # Filter by author email (must match all emails)
188202 if has_email_filter :
@@ -207,6 +221,15 @@ def cook(self):
207221 should_include = False
208222 break
209223
224+ # Filter by commit hash (must match all provided hashes - support partial matching)
225+ if has_commit_filter and should_include :
226+ for provided_hash in self .args .commit :
227+ # support partial hash matching - check if provided hash is prefix of actual hash
228+ if not (commit_hash .lower ().startswith (provided_hash .lower ()) or \
229+ commit_data .get ("commit_hash" , "" ).lower ().startswith (provided_hash .lower ())):
230+ should_include = False
231+ break
232+
210233 # Add to processed data if matches all conditions
211234 if should_include :
212235 self .cooked_commits [repo_name ][commit_hash ] = commit_data
0 commit comments