Re: [PATCH v3 01/11] Add new git-cc-cmd helper to contrib

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 19, 2013 at 2:30 PM, Felipe Contreras
<felipe.contreras@xxxxxxxxx> wrote:
> This script find people that might be interesting in a patch, by going
> back through the history for each single hunk modified, and finding
> people that reviewed, acknowledge, signed, or authored the code the
> patch is modifying.
>
> It does this by running 'git blame' incrementally on each hunk, and then
> parsing the commit message. After gathering all the relevant people, it
> groups them to show what exactly was their role when the participated in
> the development of the relevant commit, and on how many relevant commits
> they participated. They are only displayed if they pass a minimum
> threshold of participation.
>
> For example:
>
>   % git cc-cmd 0001-remote-hg-trivial-cleanups.patch
>   Felipe Contreras <felipe.contreras@xxxxxxxxx> (author: 100%)
>   Jeff King <peff@xxxxxxxx> (signer: 83%)
>   Max Horn <max@xxxxxxxxx> (signer: 16%)
>   Junio C Hamano <gitster@xxxxxxxxx> (signer: 16%)
>
> Thus it can be used for 'git send-email' as a cc-cmd.

Here's the interdiff with the previous one:

diff --git a/contrib/cc-cmd/git-cc-cmd b/contrib/cc-cmd/git-cc-cmd
index c7ecf79..aa83a1a 100755
--- a/contrib/cc-cmd/git-cc-cmd
+++ b/contrib/cc-cmd/git-cc-cmd
@@ -5,40 +5,35 @@ $min_percent = 5

 class Commit

-  attr_reader :id
-  attr_accessor :roles
+  attr_reader :id, :roles

   def initialize(id)
     @id = id
     @roles = []
   end

-  def self.parse(data)
-    id = author = msg = nil
+  def parse(data)
+    author = msg = nil
     roles = {}
     data.each_line do |line|
       if not msg
         case line
-        when /^commit (.+)$/
-          id = $1
         when /^author ([^<>]+) <(\S+)>$/
           author = $1, $2
-          roles[author] = 'author'
+          roles[author] = :author
         when /^$/
           msg = true
         end
       else
         if line =~ /^(Signed-off|Reviewed|Acked)-by: ([^<>]+) <(\S+?)>$/
           person = $2, $3
-          roles[person] = 'signer' if person != author
+          roles[person] = :signer if person != author
         end
       end
     end
-    roles = roles.map do |person, role|
-      address = "%s <%s>" % person
+    @roles = roles.map do |person, role|
       [person, role]
     end
-    [id, roles]
   end

 end
@@ -57,22 +52,15 @@ class Commits

   def import
     return if @items.empty?
-    format = [ 'commit %H', 'author %an <%ae>', '', '%B' ].join('%n')
-    File.popen(['git', 'show', '-z', '-s', '--format=format:' +
format] + @items.keys) do |p|
-      p.each("\0") do |data|
-        next if data == "\0" # bug in git show?
-        id, roles = Commit.parse(data)
-        commit = @items[id]
-        commit.roles = roles
-      end
-    end
-  end
-
-  def each_person_role
-    commit_roles = @items.values.map { |commit| commit.roles }.flatten(1)
-    commit_roles.group_by { |person, role| person }.each do |person,
commit_roles|
-      commit_roles.group_by { |person, role| role }.each do |role,
commit_roles|
-        yield person, role, commit_roles.size
+    File.popen(%w[git cat-file --batch], 'r+') do |p|
+      p.write(@items.keys.join("\n"))
+      p.close_write
+      p.each do |l|
+        if l =~ /^(\h{40}) commit (\d+)/
+          id, len = $1, $2
+          data = p.read($2.to_i)
+          @items[id].parse(data)
+        end
       end
     end
   end
@@ -107,34 +95,37 @@ class Commits
         end
       end
     end
-    import
   end

 end

 exit 1 if ARGV.size != 1

-commits = Commits.new()
+commits = Commits.new
 commits.from_patch(ARGV[0])
+commits.import

 # hash of hashes
 persons = Hash.new { |hash, key| hash[key] = {} }

-commits.each_person_role do |person, role, count|
-  persons[person][role] = count
+commits.items.values.each do |commit|
+  commit.roles.each do |person, role|
+    persons[person][role] ||= 0
+    persons[person][role] += 1
+  end
 end

 persons.each do |person, roles|
   roles = roles.map do |role, count|
     percent = count.to_f * 100 / commits.size
     next if percent < $min_percent
-    "%s: %u%%" % [role, percent]
+    '%s: %u%%' % [role, percent]
   end.compact
   next if roles.empty?

   name, email = person
   # must quote chars?
   name = '"%s"' % name if name =~ /[^\w \-]/i
-  person = name ? "%s <%s>" % [name, email] : email
-  puts "%s (%s)" % [person, roles.join(', ')]
+  person = name ? '%s <%s>' % [name, email] : email
+  puts '%s (%s)' % [person, roles.join(', ')]
 end

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]