public
Fork of Caged/gitnub
Description: A Gitk-like application written in RubyCocoa that looks like it belongs on a Mac. See the wiki for downloads and screenshots.
Homepage: http://alternateidea.com
Clone URL: git://github.com/dustin/gitnub.git
dustin (author)
Sun Apr 13 23:04:34 -0700 2008
commit  89ffdd3b835c3dc4599217b5913f873a1e86ce1f
tree    21a6c771a6d3b5f695c6a5121c3cd31e87337f18
parent  4c5b5904d9b5776d4b0b8d13ca5ad66059f2373f
gitnub / lib / rcsetta.rb
100644 128 lines (95 sloc) 2.673 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require 'grit/lib/grit'
 
module RCSetta
 
  class HGBranch
 
    attr_accessor :name
 
    def initialize(n)
      self.name=n
    end
 
    def inspect
      %Q{#<HGBranch "#{name}>}
    end
 
  end
 
  class HGCommit
 
    attr_reader :id
    attr_reader :parents
    attr_reader :tree
    attr_reader :author
    attr_reader :authored_date
    attr_reader :committer
    attr_reader :committed_date
    attr_reader :message
    attr_reader :short_message
  
    def initialize(repo, node, author, branches, parents, date, summary, msg)
      @repo=repo
      @id=node
      @author=::Grit::Actor.from_string author
      @authored_date = Time.at date.to_i
      @committer=self.author
      @committed_date = self.authored_date
      @short_message = summary
      @message = msg
 
      @parents=[]
    end
 
    def diffs
      diff = @repo.run_cmd %W(export -g #{@id})
      if diff =~ /diff --git a/
        diff = diff.sub(/.+?(diff --git a)/m, '\1')
      else
        diff = ''
      end
      ::Grit::Diff.list_from_string(@repo, diff)
    end
 
  end
 
  class HGRepo
 
    attr_accessor :path
 
    # This is a terrible hack -- I couldn't get nulls working correctly
    FSEP='892af' + '675f7'
    LSEP='7dff7' + 'f5263'
 
    FIELDS=%w(node author branches parents date desc|firstline desc)
 
    COMMIT_TEMPL=FIELDS.map{|i| "{#{i}}"}.join(FSEP) + LSEP
    COMMIT_TEMPL_Q=%{"#{COMMIT_TEMPL}"}
 
    def initialize(path)
      self.path=path
    end
 
    def head
      branches.first
    end
 
    def inspect
      %Q{#<HGRepo "#{@path}>"}
    end
 
    def branches
      [HGBranch.new('default')]
    end
 
    def commit_count(start='default')
      (run_cmd %W(id -n)).to_i
    end
 
    def commits(start = 'master', max_count = 10, skip = 0)
      start = 'default' if start.to_s == 'master'
      l=run_cmd ['log', '-l', (max_count + skip), '--template', COMMIT_TEMPL_Q]
      l.split(LSEP).last(max_count).map{|i| HGCommit.new(self, *i.split(FSEP))}
    end
 
    def run_cmd(cmd)
      c = (%W(hg -R #{self.path}) + cmd).join(' ')
      `#{c}`
    end
 
  end
 
  SCM_DRIVERS = { '.hg' => HGRepo, '.git' => ::Grit::Repo }
 
  # Detect a repo type and open it.
  def RCSetta::open(path)
    epath = File.expand_path path
    RCSetta::search_up epath.split(/\//)
  end
 
  private
 
  # Look upwards until we find something we understand, or we can't go up any
  # further.
  def RCSetta::search_up(paths)
    raise "Cannot detect repo type from #{path}" if paths.empty?
    path=paths.join '/'
    driver = SCM_DRIVERS.detect{|p, c| File.exist?(File.join(path, p))}
    if driver
      driver.last.new path
    else
      RCSetta::search_up(paths[0..-2])
    end
  end
 
 
end