git clone works
[repobrowse.git] / lib / repobrowse / git_commit.rb
blob3a17fbe9a8b3819949be7858e9155bfd92cfaf50
1 # -*- encoding: binary -*-
2 # Copyright (C) 2017 all contributors <repobrowse@80x24.org>
3 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 # frozen_string_literal: true
5 module Repobrowse::GitCommit
6   CMT_FIELDS = { # ordered hash
7     commit: '%H',
8     subject: '%s',
9     author_name: '%an',
10     author_email: '<%ae>',
11     author_date: '<%ai>',
12     committer_name: '%cn',
13     committer_email: '<%ce>',
14     committer_date: '<%ci>',
15     tree: '%T',
16     parents: '%P',
17     refnames: '%D',
18     body: '%b'
19   }.freeze
20   PRETTY = -"--pretty=format:#{CMT_FIELDS.values.join('%x00')}%x00"
21   CC_EMPTY = " This is a merge, and the combined diff is empty.\n"
22   CC_MERGE = " This is a merge, showing combined diff:\n\n"
24   def commit(env, info, objid = tip, limit: 160)
25     _, type, size = check(env, objid)
26     return if type != 'commit'
27     info[:type] = type
28     info[:size] = size
30     cmd = %W(git --git-dir=#@git_dir show -z --numstat -p --encoding=UTF-8
31             --no-notes --no-color -c --no-abbrev #{PRETTY} #{objid} --)
32     IO.popen(cmd) do |io|
33       io.binmode
34       read_info(info, io)
35       io.each_line("\n", limit) do |line|
36         yield line
37         line.clear
38       end
39     end
40     info
41   end
43   def read_info(info, io)
44     fields = CMT_FIELDS.keys
45     while field = fields.shift
46       val = io.gets("\0")
47       case field # dedupe common values
48       when :author_name, :author_email, :committer_name, :committer_email,
49            :refnames
50         val = -val
51       end
52       info[field] = val
53     end
54   end
55 end