class GITRepo
Public Class Methods
new(topdir)
click to toggle source
# File lib/vcs-ann/git.rb, line 2 def initialize(topdir) @topdir = topdir end
Public Instance Methods
format_commit(list)
click to toggle source
# File lib/vcs-ann/git.rb, line 74 def format_commit(list) rev = list[0] rev log_out, log_status = Open3.capture2({'LC_ALL'=>'C'}, 'git', '-C', @topdir.to_s, 'log', '-1', '--parents', rev) log_out.force_encoding('locale').scrub! if !log_status.success? raise "git log failed." end if /^commit ([0-9a-f]+)(.*)\n/ !~ log_out raise "git log doesn't produce 'commit' line." end commit_rev = $1 parent_revs = $2.strip.split(/\s+/) result = '<pre>' log_out.each_line {|line| result << "#{h line.chomp}\n" } result << '</pre>' parent_revs.each {|parent_rev| diff_out, diff_status = Open3.capture2({'LC_ALL'=>'C'}, 'git', '-C', @topdir.to_s, 'diff', parent_rev, commit_rev) diff_out.force_encoding('locale').scrub! if !diff_status.success? raise "git diff failed." end rev1 = parent_rev rev2 = commit_rev filename1 = filename2 = '?' result << '<pre>' scan_udiff(diff_out) {|tag, *rest| case tag when :filename1 line, filename1 = rest filename1.sub!(%r{\Aa/}, '') result << " " result << (h line.chomp.expand_tab) << "\n" when :filename2 line, filename2 = rest filename2.sub!(%r{\Ab/}, '') result << " " result << (h line.chomp.expand_tab) << "\n" when :hunk_header line, ln_cur1, ln_num1, ln_cur2, ln_num2 = rest result << " " result << (h line.chomp.expand_tab) << "\n" when :del line, content_line, ln_cur1 = rest content_line = content_line.chomp.expand_tab rev1_url = "/file/#{rev1}/#{filename1}\##{ln_cur1}" result << %{<a name="#{h(u(rev1.to_s+"/"+filename1+":"+ln_cur1.to_s))}"></a>} result << %{<a href="#{h rev1_url}"> -</a>} result << (h content_line) << "\n" when :add line, content_line, ln_cur2 = rest content_line = content_line.chomp.expand_tab rev2_url = "/file/#{rev2}/#{filename2}\##{ln_cur2}" result << %{<a name="#{h(u(rev2.to_s+"/"+filename2+":"+ln_cur2.to_s))}"></a>} result << %{<a href="#{h rev2_url}"> +</a>} result << (h content_line) << "\n" when :com line, content_line, ln_cur1, ln_cur2 = rest content_line = content_line.chomp.expand_tab rev1_url = "/file/#{rev1}/#{filename1}\##{ln_cur1}" rev2_url = "/file/#{rev2}/#{filename2}\##{ln_cur2}" result << %{<a name="#{h(u(rev1.to_s+"/"+filename1+":"+ln_cur1.to_s))}"></a>} result << %{<a name="#{h(u(rev2.to_s+"/"+filename2+":"+ln_cur2.to_s))}"></a>} result << %{<a href="#{h rev1_url}"> </a>} result << %{<a href="#{h rev2_url}"> </a>} result << (h content_line) << "\n" when :other line, = rest result << " " result << (h line.chomp.expand_tab) << "\n" else raise "unexpected udiff line tag" end } result << '</pre>' } result end
format_file(list)
click to toggle source
# File lib/vcs-ann/git.rb, line 39 def format_file(list) rev = list[0] relpath = list[1..-1].join('/') result = '<pre>' data = [] author_name_width = 0 git_blame_each(@topdir.to_s, relpath, rev) {|rev, original_file_line_number, final_file_line_number, numlines, header, content_line| author_time = Time.at(header['author-time'].to_i).strftime("%Y-%m-%d") author_name = header['author'] content_line = content_line.chomp.expand_tab author_name_width = author_name.length if author_name_width < author_name.length data << [rev, author_time, author_name, content_line, header['filename'], original_file_line_number] } prev_rev = nil ln = 1 data.each {|rev, author_time, author_name, content_line, filename, original_file_line_number| formatted_author_time = prev_rev == rev ? ' ' * 10 : author_time formatted_author_name = "%-#{author_name_width}s" % author_name commit_url = "/commit/#{rev}\##{u(rev+"/"+filename.to_s+":"+original_file_line_number.to_s)}" result << %{<a name="#{h ln.to_s}"></a>} result << %{<a href="#{h commit_url}">#{h formatted_author_time}</a> } result << %{#{h formatted_author_name} } result << %{#{h content_line}\n} prev_rev = rev ln += 1 } result << '</pre>' result end
git_blame_each(topdir, relpath, rev) { |rev, original_file_line_number, final_file_line_number, numlines, header, content_line| ... }
click to toggle source
# File lib/vcs-ann/git.rb, line 6 def git_blame_each(topdir, relpath, rev) out, status = Open3.capture2('git', '-C', topdir, 'blame', '--porcelain', rev, '--', relpath) out.force_encoding('locale').scrub! if !status.success? raise "git blame failed" end header_hash = {} prev_header = {} block = [] out.each_line {|line| line.force_encoding('locale').scrub! if /\A\t/ !~ line block << line else content_line = line.sub(/\A\t/, '') rev, original_file_line_number, final_file_line_number, numlines = block.shift.split(/\s+/) if !block.empty? header = {} block.each {|header_line| if / / =~ header_line.chomp header[$`] = $' end } header_hash[rev] = header end header = header_hash[rev] yield rev, original_file_line_number, final_file_line_number, numlines, header, content_line block = [] end } end