@@ -26,7 +26,13 @@ class GitCommit:
2626 author_date : datetime
2727 commit_date : Optional [datetime ]
2828
29- def __init__ (self , commit_hash : str , author : str , author_date : datetime , title : str , body : str , commit_date : Optional [datetime ] = None ) -> None :
29+ def __init__ (self ,
30+ commit_hash : str ,
31+ author : str ,
32+ author_date : datetime ,
33+ title : str ,
34+ body : str ,
35+ commit_date : Optional [datetime ] = None ) -> None :
3036 self .commit_hash = commit_hash
3137 self .author = author
3238 self .author_date = author_date
@@ -139,9 +145,10 @@ def __init__(self, path, remote='upstream'):
139145 self .remote = remote
140146
141147 def _run_git_log (self , revision_range ) -> List [GitCommit ]:
142- log = _check_output (["git" , "-C" , self .repo_dir , "log" , '--format=fuller' , '--date=unix' , revision_range ]).split ("\n " )
143- rc = []
144- cur_msg = []
148+ log = _check_output (['git' , '-C' , self .repo_dir , 'log' ,
149+ '--format=fuller' , '--date=unix' , revision_range , '--' , '.' ]).split ("\n " )
150+ rc : List [GitCommit ] = []
151+ cur_msg : List [str ] = []
145152 for line in log :
146153 if line .startswith ("commit" ):
147154 if len (cur_msg ) > 0 :
@@ -304,30 +311,83 @@ def print_contributor_stats(commits, delta: Optional[timedelta] = None) -> None:
304311 print (f"{ author } : { count } " )
305312
306313
314+ def commits_missing_in_branch (repo : GitRepo , branch : str , orig_branch : str , milestone_idx : int ) -> None :
315+ def get_commits_dict (x , y ):
316+ return build_commit_dict (repo .get_commit_list (x , y ))
317+ master_commits = get_commits_dict (orig_branch , 'master' )
318+ release_commits = get_commits_dict (orig_branch , branch )
319+ print (f"len(master_commits)={ len (master_commits )} " )
320+ print (f"len(release_commits)={ len (release_commits )} " )
321+ print ("URL;Title;Status" )
322+ for issue in gh_get_milestone_issues ('pytorch' , 'pytorch' , milestone_idx , IssueState .ALL ):
323+ html_url , state = issue ["html_url" ], issue ["state" ]
324+ # Skip closed states if they were landed before merge date
325+ if state == "closed" :
326+ mentioned_after_cut = any (html_url in commit_message for commit_message in master_commits .values ())
327+ # If issue is not mentioned after cut, that it must be present in release branch
328+ if not mentioned_after_cut :
329+ continue
330+ mentioned_in_release = any (html_url in commit_message for commit_message in release_commits .values ())
331+ # if Issue is mentioned is release branch, than it was picked already
332+ if mentioned_in_release :
333+ continue
334+ print (f'{ html_url } ;{ issue ["title" ]} ;{ state } ' )
335+
336+
307337def parse_arguments ():
308338 from argparse import ArgumentParser
309339 parser = ArgumentParser (description = "Print GitHub repo stats" )
310340 parser .add_argument ("--repo-path" ,
311341 type = str ,
312342 help = "Path to PyTorch git checkout" ,
313343 default = os .path .expanduser ("~/git/pytorch/pytorch" ))
344+ parser .add_argument ("--milestone-id" , type = str )
345+ parser .add_argument ("--branch" , type = str )
346+ parser .add_argument ("--remote" ,
347+ type = str ,
348+ help = "Remote to base off of" ,
349+ default = "" )
314350 parser .add_argument ("--analyze-reverts" , action = "store_true" )
315351 parser .add_argument ("--contributor-stats" , action = "store_true" )
352+ parser .add_argument ("--missing-in-branch" , action = "store_true" )
316353 return parser .parse_args ()
317354
318355
319356def main ():
320357 import time
321358 args = parse_arguments ()
322- remotes = get_git_remotes (args .repo_path )
323- # Pick best remote
324- remote = next (iter (remotes .keys ()))
325- for key in remotes :
326- if remotes [key ] == 'https://github.com/pytorch/pytorch' :
327- remote = key
359+ remote = args .remote
360+ if not remote :
361+ remotes = get_git_remotes (args .repo_path )
362+ # Pick best remote
363+ remote = next (iter (remotes .keys ()))
364+ for key in remotes :
365+ if remotes [key ].endswith ('github.com/pytorch/pytorch' ):
366+ remote = key
328367
329368 repo = GitRepo (args .repo_path , remote )
330- print ("Parsing git history..." , end = '' , flush = True )
369+
370+ if args .missing_in_branch :
371+ # Use milestone idx or search it along milestone titles
372+ try :
373+ milestone_idx = int (args .milestone_id )
374+ except ValueError :
375+ milestone_idx = - 1
376+ milestones = gh_get_milestones ()
377+ for milestone in milestones :
378+ if milestone .get ('title' , '' ) == args .milestone_id :
379+ milestone_idx = int (milestone .get ('number' , '-2' ))
380+ if milestone_idx < 0 :
381+ print (f'Could not find milestone { args .milestone_id } ' )
382+ return
383+
384+ commits_missing_in_branch (repo ,
385+ args .branch ,
386+ f'orig/{ args .branch } ' ,
387+ milestone_idx )
388+ return
389+
390+ print (f"Parsing git history with remote { remote } ..." , end = '' , flush = True )
331391 start_time = time .time ()
332392 x = repo ._run_git_log (f"{ remote } /master" )
333393 print (f"done in { time .time ()- start_time :.1f} sec" )
0 commit comments