git-trip 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.txt +21 -0
  3. data/Manifest.txt +89 -0
  4. data/README.txt +60 -0
  5. data/Rakefile +31 -0
  6. data/bin/git-trip +0 -0
  7. data/doc/USAGE.txt +54 -0
  8. data/lib/core_ext/hash.rb +15 -0
  9. data/lib/git-trip.rb +23 -0
  10. data/lib/git-trip/errors.rb +22 -0
  11. data/lib/git-trip/gitter.rb +10 -0
  12. data/lib/git-trip/gitter/base.rb +18 -0
  13. data/lib/git-trip/gitter/dir.rb +32 -0
  14. data/lib/git-trip/gitter/uri.rb +40 -0
  15. data/lib/git-trip/paint_mode.rb +52 -0
  16. data/lib/git-trip/painter.rb +167 -0
  17. data/spec/core_ext/hash_spec.rb +25 -0
  18. data/spec/git-trip/errors_spec.rb +43 -0
  19. data/spec/git-trip/gitter/base_spec.rb +15 -0
  20. data/spec/git-trip/gitter/dir_spec.rb +37 -0
  21. data/spec/git-trip/gitter/uri_spec.rb +25 -0
  22. data/spec/git-trip/gitter_spec.rb +11 -0
  23. data/spec/git-trip/paint_mode_spec.rb +56 -0
  24. data/spec/git-trip/painter_spec.rb +173 -0
  25. data/spec/git_trip_spec.rb +23 -0
  26. data/spec/rcov.opts +1 -0
  27. data/spec/spec.opts +4 -0
  28. data/spec/spec_helper.rb +15 -0
  29. data/tasks/ditz.rake +42 -0
  30. data/tasks/docs.rake +68 -0
  31. data/tasks/gittrip.rake +63 -0
  32. data/tasks/rspec.rake +22 -0
  33. data/tasks/site.rake +48 -0
  34. data/tasks/util.rake +44 -0
  35. data/vendor/grit/History.txt +6 -0
  36. data/vendor/grit/Manifest.txt +53 -0
  37. data/vendor/grit/README.txt +213 -0
  38. data/vendor/grit/Rakefile +29 -0
  39. data/vendor/grit/grit.gemspec +16 -0
  40. data/vendor/grit/lib/grit.rb +37 -0
  41. data/vendor/grit/lib/grit/actor.rb +36 -0
  42. data/vendor/grit/lib/grit/blob.rb +117 -0
  43. data/vendor/grit/lib/grit/commit.rb +208 -0
  44. data/vendor/grit/lib/grit/config.rb +44 -0
  45. data/vendor/grit/lib/grit/diff.rb +70 -0
  46. data/vendor/grit/lib/grit/errors.rb +7 -0
  47. data/vendor/grit/lib/grit/git.rb +116 -0
  48. data/vendor/grit/lib/grit/index.rb +77 -0
  49. data/vendor/grit/lib/grit/lazy.rb +31 -0
  50. data/vendor/grit/lib/grit/ref.rb +110 -0
  51. data/vendor/grit/lib/grit/repo.rb +318 -0
  52. data/vendor/grit/lib/grit/tree.rb +99 -0
  53. data/vendor/grit/test/fixtures/blame +131 -0
  54. data/vendor/grit/test/fixtures/cat_file_blob +1 -0
  55. data/vendor/grit/test/fixtures/cat_file_blob_size +1 -0
  56. data/vendor/grit/test/fixtures/diff_2 +54 -0
  57. data/vendor/grit/test/fixtures/diff_2f +19 -0
  58. data/vendor/grit/test/fixtures/diff_f +15 -0
  59. data/vendor/grit/test/fixtures/diff_i +201 -0
  60. data/vendor/grit/test/fixtures/diff_mode_only +1152 -0
  61. data/vendor/grit/test/fixtures/diff_new_mode +17 -0
  62. data/vendor/grit/test/fixtures/diff_p +610 -0
  63. data/vendor/grit/test/fixtures/for_each_ref +0 -0
  64. data/vendor/grit/test/fixtures/for_each_ref_remotes +0 -0
  65. data/vendor/grit/test/fixtures/for_each_ref_tags +0 -0
  66. data/vendor/grit/test/fixtures/ls_tree_a +7 -0
  67. data/vendor/grit/test/fixtures/ls_tree_b +2 -0
  68. data/vendor/grit/test/fixtures/ls_tree_commit +3 -0
  69. data/vendor/grit/test/fixtures/rev_list +26 -0
  70. data/vendor/grit/test/fixtures/rev_list_count +655 -0
  71. data/vendor/grit/test/fixtures/rev_list_single +7 -0
  72. data/vendor/grit/test/fixtures/rev_parse +1 -0
  73. data/vendor/grit/test/fixtures/show_empty_commit +6 -0
  74. data/vendor/grit/test/fixtures/simple_config +2 -0
  75. data/vendor/grit/test/helper.rb +17 -0
  76. data/vendor/grit/test/profile.rb +21 -0
  77. data/vendor/grit/test/suite.rb +6 -0
  78. data/vendor/grit/test/test_actor.rb +35 -0
  79. data/vendor/grit/test/test_blob.rb +74 -0
  80. data/vendor/grit/test/test_commit.rb +182 -0
  81. data/vendor/grit/test/test_config.rb +58 -0
  82. data/vendor/grit/test/test_diff.rb +18 -0
  83. data/vendor/grit/test/test_git.rb +52 -0
  84. data/vendor/grit/test/test_head.rb +22 -0
  85. data/vendor/grit/test/test_real.rb +19 -0
  86. data/vendor/grit/test/test_reality.rb +17 -0
  87. data/vendor/grit/test/test_remote.rb +15 -0
  88. data/vendor/grit/test/test_repo.rb +278 -0
  89. data/vendor/grit/test/test_tag.rb +29 -0
  90. data/vendor/grit/test/test_tree.rb +91 -0
  91. metadata +179 -0
  92. metadata.gz.sig +0 -0
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require './lib/grit.rb'
4
+
5
+ Hoe.new('grit', Grit::VERSION) do |p|
6
+ p.author = 'Tom Preston-Werner'
7
+ p.email = 'tom@rubyisawesome.com'
8
+ p.summary = 'Object model interface to a git repo'
9
+ p.description = p.paragraphs_of('README.txt', 2..2).join("\n\n")
10
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[2..-1].map { |u| u.strip }
11
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
12
+ p.extra_deps << ['mime-types']
13
+ end
14
+
15
+ desc "Open an irb session preloaded with this library"
16
+ task :console do
17
+ sh "irb -rubygems -r ./lib/grit.rb"
18
+ end
19
+
20
+ task :coverage do
21
+ system("rm -fr coverage")
22
+ system("rcov test/test_*.rb")
23
+ system("open coverage/index.html")
24
+ end
25
+
26
+ desc "Upload site to Rubyforge"
27
+ task :site do
28
+ sh "scp -r doc/* mojombo@grit.rubyforge.org:/var/www/gforge-projects/grit"
29
+ end
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "grit"
3
+ s.version = "0.8.1"
4
+ s.date = "2008-04-24"
5
+ s.summary = "Object model interface to a git repo"
6
+ s.email = "tom@rubyisawesome.com"
7
+ s.homepage = "http://github.com/mojombo/grit"
8
+ s.description = "Grit is a Ruby library for extracting information from a git repository in and object oriented manner."
9
+ s.has_rdoc = true
10
+ s.authors = ["Tom Preston-Werner"]
11
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "grit.gemspec", "lib/grit.rb", "lib/grit/actor.rb", "lib/grit/blob.rb", "lib/grit/commit.rb", "lib/grit/config.rb", "lib/grit/diff.rb", "lib/grit/errors.rb", "lib/grit/git.rb", "lib/grit/head.rb", "lib/grit/lazy.rb", "lib/grit/repo.rb", "lib/grit/tag.rb", "lib/grit/tree.rb", "test/fixtures/blame", "test/fixtures/cat_file_blob", "test/fixtures/cat_file_blob_size", "test/fixtures/diff_2", "test/fixtures/diff_2f", "test/fixtures/diff_f", "test/fixtures/diff_i", "test/fixtures/diff_mode_only", "test/fixtures/diff_new_mode", "test/fixtures/diff_p", "test/fixtures/for_each_ref", "test/fixtures/for_each_ref_tags", "test/fixtures/ls_tree_a", "test/fixtures/ls_tree_b", "test/fixtures/ls_tree_commit", "test/fixtures/rev_list", "test/fixtures/rev_list_count", "test/fixtures/rev_list_single", "test/fixtures/rev_parse", "test/fixtures/show_empty_commit", "test/fixtures/simple_config", "test/helper.rb", "test/profile.rb", "test/suite.rb", "test/test_actor.rb", "test/test_blob.rb", "test/test_commit.rb", "test/test_config.rb", "test/test_diff.rb", "test/test_git.rb", "test/test_head.rb", "test/test_reality.rb", "test/test_repo.rb", "test/test_tag.rb", "test/test_tree.rb", "test/test_real.rb"]
12
+ s.test_files = ["test/test_actor.rb", "test/test_blob.rb", "test/test_commit.rb", "test/test_config.rb", "test/test_diff.rb", "test/test_git.rb", "test/test_head.rb", "test/test_real.rb", "test/test_reality.rb", "test/test_repo.rb", "test/test_tag.rb", "test/test_tree.rb"]
13
+ s.rdoc_options = ["--main", "README.txt"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
15
+ s.add_dependency("mime-types", ["> 0.0.0"])
16
+ end
@@ -0,0 +1,37 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+
3
+ # core
4
+ require 'fileutils'
5
+ require 'time'
6
+
7
+ # stdlib
8
+ require 'timeout'
9
+
10
+ # third party
11
+ require 'rubygems'
12
+ require 'mime/types'
13
+ require 'open4'
14
+
15
+ # internal requires
16
+ require 'grit/lazy'
17
+ require 'grit/errors'
18
+ require 'grit/git'
19
+ require 'grit/ref'
20
+ require 'grit/commit'
21
+ require 'grit/tree'
22
+ require 'grit/blob'
23
+ require 'grit/actor'
24
+ require 'grit/diff'
25
+ require 'grit/config'
26
+ require 'grit/repo'
27
+ require 'grit/index'
28
+
29
+ module Grit
30
+ class << self
31
+ attr_accessor :debug
32
+ end
33
+
34
+ self.debug = false
35
+
36
+ VERSION = '0.8.1'
37
+ end
@@ -0,0 +1,36 @@
1
+ module Grit
2
+
3
+ class Actor
4
+ attr_reader :name
5
+ attr_reader :email
6
+
7
+ def initialize(name, email)
8
+ @name = name
9
+ @email = email
10
+ end
11
+ alias_method :to_s, :name
12
+
13
+ # Create an Actor from a string.
14
+ # +str+ is the string, which is expected to be in regular git format
15
+ #
16
+ # Format
17
+ # John Doe <jdoe@example.com>
18
+ #
19
+ # Returns Actor
20
+ def self.from_string(str)
21
+ case str
22
+ when /<.+>/
23
+ m, name, email = *str.match(/(.*) <(.+?)>/)
24
+ return self.new(name, email)
25
+ else
26
+ return self.new(str, nil)
27
+ end
28
+ end
29
+
30
+ # Pretty object inspection
31
+ def inspect
32
+ %Q{#<Grit::Actor "#{@name} <#{@email}>">}
33
+ end
34
+ end # Actor
35
+
36
+ end # Grit
@@ -0,0 +1,117 @@
1
+ module Grit
2
+
3
+ class Blob
4
+ DEFAULT_MIME_TYPE = "text/plain"
5
+
6
+ attr_reader :id
7
+ attr_reader :mode
8
+ attr_reader :name
9
+
10
+ # Create an unbaked Blob containing just the specified attributes
11
+ # +repo+ is the Repo
12
+ # +atts+ is a Hash of instance variable data
13
+ #
14
+ # Returns Grit::Blob (unbaked)
15
+ def self.create(repo, atts)
16
+ self.allocate.create_initialize(repo, atts)
17
+ end
18
+
19
+ # Initializer for Blob.create
20
+ # +repo+ is the Repo
21
+ # +atts+ is a Hash of instance variable data
22
+ #
23
+ # Returns Grit::Blob (unbaked)
24
+ def create_initialize(repo, atts)
25
+ @repo = repo
26
+ atts.each do |k, v|
27
+ instance_variable_set("@#{k}".to_sym, v)
28
+ end
29
+ self
30
+ end
31
+
32
+ # The size of this blob in bytes
33
+ #
34
+ # Returns Integer
35
+ def size
36
+ @size ||= @repo.git.cat_file({:s => true}, id).chomp.to_i
37
+ end
38
+
39
+ # The binary contents of this blob.
40
+ #
41
+ # Returns String
42
+ def data
43
+ @data ||= @repo.git.cat_file({:p => true}, id)
44
+ end
45
+
46
+ # The mime type of this file (based on the filename)
47
+ #
48
+ # Returns String
49
+ def mime_type
50
+ guesses = MIME::Types.type_for(self.name) rescue []
51
+ guesses.first ? guesses.first.simplified : DEFAULT_MIME_TYPE
52
+ end
53
+
54
+ # The blame information for the given file at the given commit
55
+ #
56
+ # Returns Array: [Grit::Commit, Array: [<line>]]
57
+ def self.blame(repo, commit, file)
58
+ data = repo.git.blame({:p => true}, commit, '--', file)
59
+
60
+ commits = {}
61
+ blames = []
62
+ info = nil
63
+
64
+ data.split("\n").each do |line|
65
+ parts = line.split(/\s+/, 2)
66
+ case parts.first
67
+ when /^[0-9A-Fa-f]{40}$/
68
+ case line
69
+ when /^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/
70
+ _, id, origin_line, final_line, group_lines = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/)
71
+ info = {:id => id}
72
+ blames << [nil, []]
73
+ when /^([0-9A-Fa-f]{40}) (\d+) (\d+)$/
74
+ _, id, origin_line, final_line = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+)$/)
75
+ info = {:id => id}
76
+ end
77
+ when /^(author|committer)/
78
+ case parts.first
79
+ when /^(.+)-mail$/
80
+ info["#{$1}_email".intern] = parts.last
81
+ when /^(.+)-time$/
82
+ info["#{$1}_date".intern] = Time.at(parts.last.to_i)
83
+ when /^(author|committer)$/
84
+ info[$1.intern] = parts.last
85
+ end
86
+ when /^filename/
87
+ info[:filename] = parts.last
88
+ when /^summary/
89
+ info[:summary] = parts.last
90
+ when ''
91
+ c = commits[info[:id]]
92
+ unless c
93
+ c = Commit.create(repo, :id => info[:id],
94
+ :author => Actor.from_string(info[:author] + ' ' + info[:author_email]),
95
+ :authored_date => info[:author_date],
96
+ :committer => Actor.from_string(info[:committer] + ' ' + info[:committer_email]),
97
+ :committed_date => info[:committer_date],
98
+ :message => info[:summary])
99
+ commits[info[:id]] = c
100
+ end
101
+ _, text = *line.match(/^\t(.*)$/)
102
+ blames.last[0] = c
103
+ blames.last[1] << text
104
+ info = nil
105
+ end
106
+ end
107
+
108
+ blames
109
+ end
110
+
111
+ # Pretty object inspection
112
+ def inspect
113
+ %Q{#<Grit::Blob "#{@id}">}
114
+ end
115
+ end # Blob
116
+
117
+ end # Grit
@@ -0,0 +1,208 @@
1
+ module Grit
2
+
3
+ class Commit
4
+ attr_reader :id
5
+ lazy_reader :parents
6
+ lazy_reader :tree
7
+ lazy_reader :author
8
+ lazy_reader :authored_date
9
+ lazy_reader :committer
10
+ lazy_reader :committed_date
11
+ lazy_reader :message
12
+ lazy_reader :short_message
13
+
14
+ # Instantiate a new Commit
15
+ # +id+ is the id of the commit
16
+ # +parents+ is an array of commit ids (will be converted into Commit instances)
17
+ # +tree+ is the correspdonding tree id (will be converted into a Tree object)
18
+ # +author+ is the author string
19
+ # +authored_date+ is the authored Time
20
+ # +committer+ is the committer string
21
+ # +committed_date+ is the committed Time
22
+ # +message+ is an array of commit message lines
23
+ #
24
+ # Returns Grit::Commit (baked)
25
+ def initialize(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
26
+ @repo = repo
27
+ @id = id
28
+ @parents = parents.map { |p| Commit.create(repo, :id => p) }
29
+ @tree = Tree.create(repo, :id => tree)
30
+ @author = author
31
+ @authored_date = authored_date
32
+ @committer = committer
33
+ @committed_date = committed_date
34
+ @message = message.join("\n")
35
+ @short_message = message[0] || ''
36
+ end
37
+
38
+ def id_abbrev
39
+ @id_abbrev ||= @repo.git.rev_parse({:short => true}, self.id).chomp
40
+ end
41
+
42
+ # Create an unbaked Commit containing just the specified attributes
43
+ # +repo+ is the Repo
44
+ # +atts+ is a Hash of instance variable data
45
+ #
46
+ # Returns Grit::Commit (unbaked)
47
+ def self.create(repo, atts)
48
+ self.allocate.create_initialize(repo, atts)
49
+ end
50
+
51
+ # Initializer for Commit.create
52
+ # +repo+ is the Repo
53
+ # +atts+ is a Hash of instance variable data
54
+ #
55
+ # Returns Grit::Commit (unbaked)
56
+ def create_initialize(repo, atts)
57
+ @repo = repo
58
+ atts.each do |k, v|
59
+ instance_variable_set("@#{k}", v)
60
+ end
61
+ self
62
+ end
63
+
64
+ def lazy_source
65
+ self.class.find_all(@repo, @id, {:max_count => 1}).first
66
+ end
67
+
68
+ # Count the number of commits reachable from this ref
69
+ # +repo+ is the Repo
70
+ # +ref+ is the ref from which to begin (SHA1 or name)
71
+ #
72
+ # Returns Integer
73
+ def self.count(repo, ref)
74
+ repo.git.rev_list({}, ref).strip.split("\n").size
75
+ end
76
+
77
+ # Find all commits matching the given criteria.
78
+ # +repo+ is the Repo
79
+ # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
80
+ # +options+ is a Hash of optional arguments to git
81
+ # :max_count is the maximum number of commits to fetch
82
+ # :skip is the number of commits to skip
83
+ #
84
+ # Returns Grit::Commit[] (baked)
85
+ def self.find_all(repo, ref, options = {})
86
+ allowed_options = [:max_count, :skip, :since]
87
+
88
+ default_options = {:pretty => "raw"}
89
+ actual_options = default_options.merge(options)
90
+
91
+ if ref
92
+ output = repo.git.rev_list(actual_options, ref)
93
+ else
94
+ output = repo.git.rev_list(actual_options.merge(:all => true))
95
+ end
96
+
97
+ self.list_from_string(repo, output)
98
+ end
99
+
100
+ # Parse out commit information into an array of baked Commit objects
101
+ # +repo+ is the Repo
102
+ # +text+ is the text output from the git command (raw format)
103
+ #
104
+ # Returns Grit::Commit[] (baked)
105
+ def self.list_from_string(repo, text)
106
+ lines = text.split("\n")
107
+
108
+ commits = []
109
+
110
+ while !lines.empty?
111
+ id = lines.shift.split.last
112
+ tree = lines.shift.split.last
113
+
114
+ parents = []
115
+ parents << lines.shift.split.last while lines.first =~ /^parent/
116
+
117
+ author, authored_date = self.actor(lines.shift)
118
+ committer, committed_date = self.actor(lines.shift)
119
+
120
+ lines.shift
121
+
122
+ message_lines = []
123
+ message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
124
+
125
+ lines.shift while lines.first && lines.first.empty?
126
+
127
+ commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
128
+ end
129
+
130
+ commits
131
+ end
132
+
133
+ # Show diffs between two trees:
134
+ # +repo+ is the Repo
135
+ # +a+ is a named commit
136
+ # +b+ is an optional named commit. Passing an array assumes you
137
+ # wish to omit the second named commit and limit the diff to the
138
+ # given paths.
139
+ # +paths* is an array of paths to limit the diff.
140
+ #
141
+ # Returns Grit::Diff[] (baked)
142
+ def self.diff(repo, a, b = nil, paths = [])
143
+ if b.is_a?(Array)
144
+ paths = b
145
+ b = nil
146
+ end
147
+ paths.unshift("--") unless paths.empty?
148
+ paths.unshift(b) unless b.nil?
149
+ paths.unshift(a)
150
+ text = repo.git.diff({:full_index => true}, *paths)
151
+ Diff.list_from_string(repo, text)
152
+ end
153
+
154
+ def diffs
155
+ if parents.empty?
156
+ diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
157
+ if diff =~ /diff --git a/
158
+ diff = diff.sub(/.+?(diff --git a)/m, '\1')
159
+ else
160
+ diff = ''
161
+ end
162
+ Diff.list_from_string(@repo, diff)
163
+ else
164
+ self.class.diff(@repo, parents.first.id, @id)
165
+ end
166
+ end
167
+
168
+ # Convert this Commit to a String which is just the SHA1 id
169
+ def to_s
170
+ @id
171
+ end
172
+
173
+ # Pretty object inspection
174
+ def inspect
175
+ %Q{#<Grit::Commit "#{@id}">}
176
+ end
177
+
178
+ # private
179
+
180
+ # Parse out the actor (author or committer) info
181
+ #
182
+ # Returns [String (actor name and email), Time (acted at time)]
183
+ def self.actor(line)
184
+ m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
185
+ [Actor.from_string(actor), Time.at(epoch.to_i)]
186
+ end
187
+
188
+ def to_hash
189
+ {
190
+ 'id' => id,
191
+ 'parents' => parents.map { |p| { 'id' => p.id } },
192
+ 'tree' => tree.id,
193
+ 'message' => message,
194
+ 'author' => {
195
+ 'name' => author.name,
196
+ 'email' => author.email
197
+ },
198
+ 'committer' => {
199
+ 'name' => committer.name,
200
+ 'email' => committer.email
201
+ },
202
+ 'authored_date' => authored_date.xmlschema,
203
+ 'committed_date' => committed_date.xmlschema,
204
+ }
205
+ end
206
+ end # Commit
207
+
208
+ end # Grit