Class: Git::Author

Inherits:
Object
  • Object
show all
Defined in:
lib/git/author.rb

Overview

Author class - represents a git contributor with their statistics

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, emails: '', commits: 0) ⇒ Author

Returns a new instance of Author.



18
19
20
21
22
23
24
25
26
# File 'lib/git/author.rb', line 18

def initialize(name:, emails: '', commits: 0)
  @name = name
  @emails = Set.new Array(emails)
  @commits = commits.to_i
  @loc = 0
  @loc_added = 0
  @loc_deleted = 0
  @files = 0
end

Instance Attribute Details

#commitsObject (readonly)

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def commits
  @commits
end

#emailsObject (readonly)

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def emails
  @emails
end

#filesObject

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def files
  @files
end

#locObject

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def loc
  @loc
end

#loc_addedObject (readonly)

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def loc_added
  @loc_added
end

#loc_deletedObject (readonly)

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def loc_deleted
  @loc_deleted
end

#nameObject (readonly)

name: String - the name of the author emails: Set<String> - a list of email addresses commits: Fixnum - number of commits by this author loc_added: Fixnum - number of lines this author added over time loc_deleted: Fixnum - number of lines this author deleted over time loc: Fixnum - number of lines in the current codebase this author added files: Fixnum - number of files



15
16
17
# File 'lib/git/author.rb', line 15

def name
  @name
end

Instance Method Details

#mergable?(other) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/git/author.rb', line 35

def mergable?(other)
  name == other.name
end

#merge(other) ⇒ Object



28
29
30
31
32
33
# File 'lib/git/author.rb', line 28

def merge(other)
  return unless mergable?(other)
  @emails.merge other.emails
  @commits += other.commits
  self
end

#retrieve_loc_statsObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/git/author.rb', line 39

def retrieve_loc_stats
  # Run one git log per email in parallel, returning [added, deleted] per
  # email. The instance-variable accumulation happens afterwards on this
  # single thread, so the parallel blocks never race on @loc_added/@loc_deleted.
  Git::Parallel.pmap(emails) do |email|
    # Escape email to prevent command injection
    escaped_email = Shellwords.escape(email)
    numstat = `git log --author=#{escaped_email} \
      --pretty=tformat: --numstat --no-merges`

    # Skip if no commits found for this email
    next if numstat.empty?

    loc = numstat.split(/\n/).map do |numstat_line|
      parts = numstat_line.scan(/\A(.*)\t(.*)\t/)[0]
      parts ? parts.map(&:to_i) : nil
    end.compact

    # Skip if no valid data
    next if loc.empty?

    loc.transpose.map { |add_del_loc| add_del_loc.inject(&:+) }
  end.each do |added_deleted|
    next unless added_deleted
    added, deleted = added_deleted
    @loc_added += added if added
    @loc_deleted += deleted if deleted
  end
end