11module  GitStatistics 
22 class  CommitSummary  < SimpleDelegator 
3-  def  initialize ( commit ) 
3+  def  initialize ( repo , commit ) 
44 super ( commit ) 
5+  @repo  =  repo 
6+  @diff  =  diff ( commit . parents . first ) 
7+  @patches  =  @diff . patches 
58 end 
69
710 # A Git commit is a merge if it has more than one parent 
@@ -10,13 +13,18 @@ def merge?
1013 end 
1114
1215 # How many files were removed in this commit 
13-  def  removed_files 
14-  cached_show . select  {  |diff |  diff . deleted_file  == true  } . count 
16+  def  deleted_files 
17+  file_stats . select  {  |file |  file . status  == :deleted  } . count 
1518 end 
1619
1720 # How many files were added in this commit 
18-  def  new_files 
19-  cached_show . select  {  |diff | diff . new_file  == true  } . count 
21+  def  added_files 
22+  file_stats . select  {  |file | file . status  == :added  } . count 
23+  end 
24+ 25+  # How many files were modified (not added/deleted) in this commit 
26+  def  modified_files 
27+  file_stats . select  {  |file | file . status  == :modified  } . count 
2028 end 
2129
2230 # How many total additions in this commit? 
@@ -35,18 +43,18 @@ def net
3543 end 
3644
3745 def  file_stats 
38-  @cached_file_stats  ||= diffstats . map  {  |diff | DiffSummary . new ( diff , current_tree )  } 
46+  @cached_file_stats  ||= diffstats . map  {  |diff | DiffSummary . new ( @repo , diff )  } 
3947 end 
4048
41-  LanguageSummary  =  Struct . new ( :name ,  :additions ,  :deletions ,  :net ) 
49+  LanguageSummary  =  Struct . new ( :name ,  :additions ,  :deletions ,  :net , :added_files , :deleted_files , :modified_files ) 
4250
4351 # Array of LanguageSummary objects (one for each language) for simple calculations 
4452 def  languages 
4553 grouped_language_files . collect  do  |language ,  stats |
4654 additions  =  summarize ( stats ,  :additions ) 
4755 deletions  =  summarize ( stats ,  :deletions ) 
4856 net  =  summarize ( stats ,  :net ) 
49-  LanguageSummary . new ( language ,  additions ,  deletions ,  net ) 
57+  LanguageSummary . new ( language ,  additions ,  deletions ,  net , added_files , deleted_files , modified_files ) 
5058 end 
5159 end 
5260
@@ -55,72 +63,13 @@ def grouped_language_files
5563 file_stats . group_by ( &:language ) 
5664 end 
5765
58-  FileSummary  =  Struct . new ( :name ,  :language ,  :additions ,  :deletions ,  :net ,  :filestatus ) 
59- 60-  # Array of FileSummary objects (one for each file) for simple calculations 
61-  def  files 
62-  file_stats . collect {  |stats | determine_file_summary ( stats )  } 
63-  end 
64- 65-  def  cached_show 
66-  @cached_commit_show  ||= show 
67-  end 
68- 6966 # Files touched in this commit 
70-  def  file_names 
71-  diffstats . map ( &:filename ) 
72-  end 
73- 74-  # Fetch the current Grit::Repo tree from this commit 
75-  def  current_tree 
76-  @current_tree  ||= repo . tree ( sha ) 
67+  def  filenames 
68+  file_stats . map ( &:filename ) 
7769 end 
7870
7971 private 
8072
81-  def  determine_file_summary ( stats ) 
82-  filestatus  =  :modified 
83-  language  =  stats . language 
84- 85-  # Determine if this file could be a new or deleted file 
86-  if  ( stats . additions  > 0  && stats . deletions  == 0 )  || ( stats . additions  == 0  && stats . deletions  > 0 ) 
87-  # Extract file status from commit's diff object 
88-  cached_show . each  do  |diff |
89-  if  stats . filename  == diff . b_path 
90-  filestatus  =  :create  if  diff . new_file 
91-  filestatus  =  :delete  if  diff . deleted_file 
92-  break 
93-  end 
94-  end 
95-  end 
96- 97-  # Determine language of blob 
98-  if  stats . tree? 
99-  # Trees have no language (the tree's blobs are still processed via the remainder diffstats) 
100-  language  =  "Unknown" 
101-  elsif  stats . submodule? 
102-  language  =  "Submodule" 
103-  elsif  stats . blob . nil? 
104-  # If blob is nil (i.e., deleted file) grab the previous version of this blob using the parents of the current commit 
105-  blob  =  BlobFinder . get_blob ( self . parents . first ,  stats . filename ) 
106-  blob  =  BlobFinder . get_blob ( self . parents . last ,  stats . filename )  if  blob . nil? 
107- 108-  # Determine language of newly found blob 
109-  if  blob . kind_of?  Grit ::Tree 
110-  language  =  "Unknown" 
111-  elsif  blob . kind_of?  Grit ::Submodule 
112-  language  =  "Submodule" 
113-  elsif  blob . nil?  || blob . language . nil? 
114-  language  =  "Unknown" 
115-  else 
116-  language  =  blob . language . to_s 
117-  end 
118-  end 
119- 120-  # TODO Converts file summary into hash to keep json compatibility (for now) 
121-  Hash [ FileSummary . new ( stats . filename ,  language ,  stats . additions ,  stats . deletions ,  stats . net ,  filestatus ) . each_pair . to_a ] 
122-  end 
123- 12473 def  summarize ( stats ,  what ) 
12574 stats . map ( &what ) . inject ( 0 ,  :+ ) 
12675 end 
@@ -130,19 +79,7 @@ def commit_summary(what)
13079 end 
13180
13281 def  diffstats 
133-  if  merge? 
134-  merge_diffstats 
135-  else 
136-  stats . to_diffstat 
137-  end 
138-  end 
139- 140-  # Hackery coming... 
141-  DIFFSTAT_REGEX  =  /([-|\d ]+)\s +([-|\d ]+)\s +(.+)/i 
142-  def  merge_diffstats 
143-  native_diff  =  repo . git . native ( :diff ,  { numstat : true } ,  parents . join ( "..." ) ) 
144-  per_file_info  =  native_diff . scan ( DIFFSTAT_REGEX ) 
145-  per_file_info . map  {  |add ,  del ,  file | Grit ::DiffStat . new ( file ,  add . to_i ,  del . to_i )  } 
82+  @patches 
14683 end 
14784
14885 end 
0 commit comments