gitreport 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/git/log.rb ADDED
@@ -0,0 +1,117 @@
1
+ module Git
2
+
3
+ # object that holds the last X commits on given branch
4
+ class Log
5
+ include Enumerable
6
+
7
+ def initialize(base, count = 30)
8
+ dirty_log
9
+ @base = base
10
+ @count = count
11
+
12
+ @commits = nil
13
+ @author = nil
14
+ @grep = nil
15
+ @object = nil
16
+ @path = nil
17
+ @since = nil
18
+ @skip = nil
19
+ @until = nil
20
+ @between = nil
21
+ end
22
+
23
+ def object(objectish)
24
+ dirty_log
25
+ @object = objectish
26
+ return self
27
+ end
28
+
29
+ def author(regex)
30
+ dirty_log
31
+ @author = regex
32
+ return self
33
+ end
34
+
35
+ def grep(regex)
36
+ dirty_log
37
+ @grep = regex
38
+ return self
39
+ end
40
+
41
+ def path(path)
42
+ dirty_log
43
+ @path = path
44
+ return self
45
+ end
46
+
47
+ def skip(num)
48
+ dirty_log
49
+ @skip = num
50
+ return self
51
+ end
52
+
53
+ def since(date)
54
+ dirty_log
55
+ @since = date
56
+ return self
57
+ end
58
+
59
+ def until(date)
60
+ dirty_log
61
+ @until = date
62
+ return self
63
+ end
64
+
65
+ def between(sha1, sha2 = nil)
66
+ dirty_log
67
+ @between = [sha1, sha2]
68
+ return self
69
+ end
70
+
71
+ def to_s
72
+ self.map { |c| c.to_s }.join("\n")
73
+ end
74
+
75
+
76
+ # forces git log to run
77
+
78
+ def size
79
+ check_log
80
+ @commits.size rescue nil
81
+ end
82
+
83
+ def each(&block)
84
+ check_log
85
+ @commits.each(&block)
86
+ end
87
+
88
+ def first
89
+ check_log
90
+ @commits.first rescue nil
91
+ end
92
+
93
+ private
94
+
95
+ def dirty_log
96
+ @dirty_flag = true
97
+ end
98
+
99
+ def check_log
100
+ if @dirty_flag
101
+ run_log
102
+ @dirty_flag = false
103
+ end
104
+ end
105
+
106
+ # actually run the 'git log' command
107
+ def run_log
108
+ log = @base.lib.full_log_commits(:count => @count, :object => @object,
109
+ :path_limiter => @path, :since => @since,
110
+ :author => @author, :grep => @grep, :skip => @skip,
111
+ :until => @until, :between => @between)
112
+ @commits = log.map { |c| Git::Object::Commit.new(@base, c['sha'], c) }
113
+ end
114
+
115
+ end
116
+
117
+ end
data/lib/git/object.rb ADDED
@@ -0,0 +1,273 @@
1
+ module Git
2
+
3
+ class GitTagNameDoesNotExist< StandardError
4
+ end
5
+
6
+ # represents a git object
7
+ class Object
8
+
9
+ class AbstractObject
10
+ attr_accessor :objectish, :size, :type, :mode
11
+
12
+ def initialize(base, objectish)
13
+ @base = base
14
+ @objectish = objectish.to_s
15
+ @contents = nil
16
+ @trees = nil
17
+ @size = nil
18
+ @sha = nil
19
+ end
20
+
21
+ def sha
22
+ @sha ||= @base.lib.revparse(@objectish)
23
+ end
24
+
25
+ def size
26
+ @size ||= @base.lib.object_size(@objectish)
27
+ end
28
+
29
+ # Get the object's contents.
30
+ # If no block is given, the contents are cached in memory and returned as a string.
31
+ # If a block is given, it yields an IO object (via IO::popen) which could be used to
32
+ # read a large file in chunks.
33
+ #
34
+ # Use this for large files so that they are not held in memory.
35
+ def contents(&block)
36
+ if block_given?
37
+ @base.lib.object_contents(@objectish, &block)
38
+ else
39
+ @contents ||= @base.lib.object_contents(@objectish)
40
+ end
41
+ end
42
+
43
+ def contents_array
44
+ self.contents.split("\n")
45
+ end
46
+
47
+ def to_s
48
+ @objectish
49
+ end
50
+
51
+ def grep(string, path_limiter = nil, opts = {})
52
+ opts = {:object => sha, :path_limiter => path_limiter}.merge(opts)
53
+ @base.lib.grep(string, opts)
54
+ end
55
+
56
+ def diff(objectish)
57
+ Git::Diff.new(@base, @objectish, objectish)
58
+ end
59
+
60
+ def log(count = 30)
61
+ Git::Log.new(@base, count).object(@objectish)
62
+ end
63
+
64
+ # creates an archive of this object (tree)
65
+ def archive(file = nil, opts = {})
66
+ @base.lib.archive(@objectish, file, opts)
67
+ end
68
+
69
+ def tree?; false; end
70
+
71
+ def blob?; false; end
72
+
73
+ def commit?; false; end
74
+
75
+ def tag?; false; end
76
+
77
+ end
78
+
79
+
80
+ class Blob < AbstractObject
81
+
82
+ def initialize(base, sha, mode = nil)
83
+ super(base, sha)
84
+ @mode = mode
85
+ end
86
+
87
+ def blob?
88
+ true
89
+ end
90
+
91
+ end
92
+
93
+ class Tree < AbstractObject
94
+
95
+ @trees = nil
96
+ @blobs = nil
97
+
98
+ def initialize(base, sha, mode = nil)
99
+ super(base, sha)
100
+ @mode = mode
101
+ end
102
+
103
+ def children
104
+ blobs.merge(subtrees)
105
+ end
106
+
107
+ def blobs
108
+ check_tree
109
+ @blobs
110
+ end
111
+ alias_method :files, :blobs
112
+
113
+ def trees
114
+ check_tree
115
+ @trees
116
+ end
117
+ alias_method :subtrees, :trees
118
+ alias_method :subdirectories, :trees
119
+
120
+ def full_tree
121
+ @base.lib.full_tree(@objectish)
122
+ end
123
+
124
+ def depth
125
+ @base.lib.tree_depth(@objectish)
126
+ end
127
+
128
+ def tree?
129
+ true
130
+ end
131
+
132
+ private
133
+
134
+ # actually run the git command
135
+ def check_tree
136
+ unless @trees
137
+ @trees = {}
138
+ @blobs = {}
139
+ data = @base.lib.ls_tree(@objectish)
140
+ data['tree'].each { |k, d| @trees[k] = Git::Object::Tree.new(@base, d[:sha], d[:mode]) }
141
+ data['blob'].each { |k, d| @blobs[k] = Git::Object::Blob.new(@base, d[:sha], d[:mode]) }
142
+ end
143
+ end
144
+
145
+ end
146
+
147
+ class Commit < AbstractObject
148
+
149
+ def initialize(base, sha, init = nil)
150
+ super(base, sha)
151
+ @tree = nil
152
+ @parents = nil
153
+ @author = nil
154
+ @committer = nil
155
+ @message = nil
156
+ if init
157
+ set_commit(init)
158
+ end
159
+ end
160
+
161
+ def message
162
+ check_commit
163
+ @message
164
+ end
165
+
166
+ def name
167
+ @base.lib.namerev(sha)
168
+ end
169
+
170
+ def gtree
171
+ check_commit
172
+ Tree.new(@base, @tree)
173
+ end
174
+
175
+ def parent
176
+ parents.first
177
+ end
178
+
179
+ # array of all parent commits
180
+ def parents
181
+ check_commit
182
+ @parents
183
+ end
184
+
185
+ # git author
186
+ def author
187
+ check_commit
188
+ @author
189
+ end
190
+
191
+ def author_date
192
+ author.date
193
+ end
194
+
195
+ # git author
196
+ def committer
197
+ check_commit
198
+ @committer
199
+ end
200
+
201
+ def committer_date
202
+ committer.date
203
+ end
204
+ alias_method :date, :committer_date
205
+
206
+ def diff_parent
207
+ diff(parent)
208
+ end
209
+
210
+ def set_commit(data)
211
+ if data['sha']
212
+ @sha = data['sha']
213
+ end
214
+ @committer = Git::Author.new(data['committer'])
215
+ @author = Git::Author.new(data['author'])
216
+ @tree = Git::Object::Tree.new(@base, data['tree'])
217
+ @parents = data['parent'].map{ |sha| Git::Object::Commit.new(@base, sha) }
218
+ @message = data['message'].chomp
219
+ end
220
+
221
+ def commit?
222
+ true
223
+ end
224
+
225
+ private
226
+
227
+ # see if this object has been initialized and do so if not
228
+ def check_commit
229
+ unless @tree
230
+ data = @base.lib.commit_data(@objectish)
231
+ set_commit(data)
232
+ end
233
+ end
234
+
235
+ end
236
+
237
+ class Tag < AbstractObject
238
+ attr_accessor :name
239
+
240
+ def initialize(base, sha, name)
241
+ super(base, sha)
242
+ @name = name
243
+ end
244
+
245
+ def tag?
246
+ true
247
+ end
248
+
249
+ end
250
+
251
+ # if we're calling this, we don't know what type it is yet
252
+ # so this is our little factory method
253
+ def self.new(base, objectish, type = nil, is_tag = false)
254
+ if is_tag
255
+ sha = base.lib.tag_sha(objectish)
256
+ if sha == ''
257
+ raise Git::GitTagNameDoesNotExist.new(objectish)
258
+ end
259
+ return Git::Object::Tag.new(base, sha, objectish)
260
+ end
261
+
262
+ type ||= base.lib.object_type(objectish)
263
+ klass =
264
+ case type
265
+ when /blob/ then Blob
266
+ when /commit/ then Commit
267
+ when /tree/ then Tree
268
+ end
269
+ klass.new(base, objectish)
270
+ end
271
+
272
+ end
273
+ end
data/lib/git/path.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Git
2
+ class Path
3
+
4
+ attr_accessor :path
5
+
6
+ def initialize(path, check_path = true)
7
+ if !check_path || File.exists?(path)
8
+ @path = File.expand_path(path)
9
+ else
10
+ raise ArgumentError, "path does not exist", File.expand_path(path)
11
+ end
12
+ end
13
+
14
+ def readable?
15
+ File.readable?(@path)
16
+ end
17
+
18
+ def writable?
19
+ File.writable?(@path)
20
+ end
21
+
22
+ def to_s
23
+ @path
24
+ end
25
+
26
+ end
27
+ end
data/lib/git/remote.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Git
2
+ class Remote < Path
3
+
4
+ attr_accessor :name, :url, :fetch_opts
5
+
6
+ def initialize(base, name)
7
+ @base = base
8
+ config = @base.lib.config_remote(name)
9
+ @name = name
10
+ @url = config['url']
11
+ @fetch_opts = config['fetch']
12
+ end
13
+
14
+ def remove
15
+ @base.remote_remove(@name)
16
+ end
17
+
18
+ def fetch
19
+ @base.fetch(@name)
20
+ end
21
+
22
+ # merge this remote locally
23
+ def merge(branch = 'master')
24
+ @base.merge("#{@name}/#{branch}")
25
+ end
26
+
27
+ def branch(branch = 'master')
28
+ Git::Branch.new(@base, "#{@name}/#{branch}")
29
+ end
30
+
31
+ def remove
32
+ @base.lib.remote_remove(@name)
33
+ end
34
+
35
+ def to_s
36
+ @name
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ module Git
2
+ class Repository < Path
3
+ end
4
+ end
data/lib/git/stash.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Git
2
+ class Stash
3
+
4
+ def initialize(base, message, existing=false)
5
+ @base = base
6
+ @message = message
7
+ save unless existing
8
+ end
9
+
10
+ def save
11
+ @saved = @base.lib.stash_save(@message)
12
+ end
13
+
14
+ def saved?
15
+ @saved
16
+ end
17
+
18
+ def message
19
+ @message
20
+ end
21
+
22
+ def to_s
23
+ message
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ module Git
2
+
3
+ # object that holds all the available stashes
4
+ class Stashes
5
+ include Enumerable
6
+
7
+ def initialize(base)
8
+ @stashes = []
9
+
10
+ @base = base
11
+
12
+ @base.lib.stashes_all.each do |id, message|
13
+ @stashes.unshift(Git::Stash.new(@base, message, true))
14
+ end
15
+ end
16
+
17
+ def save(message)
18
+ s = Git::Stash.new(@base, message)
19
+ @stashes.unshift(s) if s.saved?
20
+ end
21
+
22
+ def apply(index=nil)
23
+ @base.lib.stash_apply(index)
24
+ end
25
+
26
+ def clear
27
+ @base.lib.stash_clear
28
+ @stashes = []
29
+ end
30
+
31
+ def size
32
+ @stashes.size
33
+ end
34
+
35
+ def each(&block)
36
+ @stashes.each(&block)
37
+ end
38
+
39
+ def [](index)
40
+ @stashes[index.to_i]
41
+ end
42
+
43
+ end
44
+ end
data/lib/git/status.rb ADDED
@@ -0,0 +1,110 @@
1
+ module Git
2
+
3
+ class Status
4
+ include Enumerable
5
+
6
+ def initialize(base)
7
+ @base = base
8
+ construct_status
9
+ end
10
+
11
+ def changed
12
+ @files.select { |k, f| f.type == 'M' }
13
+ end
14
+
15
+ def added
16
+ @files.select { |k, f| f.type == 'A' }
17
+ end
18
+
19
+ def deleted
20
+ @files.select { |k, f| f.type == 'D' }
21
+ end
22
+
23
+ def untracked
24
+ @files.select { |k, f| f.untracked }
25
+ end
26
+
27
+ def pretty
28
+ out = ''
29
+ self.each do |file|
30
+ out << file.path
31
+ out << "\n\tsha(r) " + file.sha_repo.to_s + ' ' + file.mode_repo.to_s
32
+ out << "\n\tsha(i) " + file.sha_index.to_s + ' ' + file.mode_index.to_s
33
+ out << "\n\ttype " + file.type.to_s
34
+ out << "\n\tstage " + file.stage.to_s
35
+ out << "\n\tuntrac " + file.untracked.to_s
36
+ out << "\n"
37
+ end
38
+ out << "\n"
39
+ out
40
+ end
41
+
42
+ # enumerable method
43
+
44
+ def [](file)
45
+ @files[file]
46
+ end
47
+
48
+ def each(&block)
49
+ @files.values.each(&block)
50
+ end
51
+
52
+ class StatusFile
53
+ attr_accessor :path, :type, :stage, :untracked
54
+ attr_accessor :mode_index, :mode_repo
55
+ attr_accessor :sha_index, :sha_repo
56
+
57
+ def initialize(base, hash)
58
+ @base = base
59
+ @path = hash[:path]
60
+ @type = hash[:type]
61
+ @stage = hash[:stage]
62
+ @mode_index = hash[:mode_index]
63
+ @mode_repo = hash[:mode_repo]
64
+ @sha_index = hash[:sha_index]
65
+ @sha_repo = hash[:sha_repo]
66
+ @untracked = hash[:untracked]
67
+ end
68
+
69
+ def blob(type = :index)
70
+ if type == :repo
71
+ @base.object(@sha_repo)
72
+ else
73
+ @base.object(@sha_index) rescue @base.object(@sha_repo)
74
+ end
75
+ end
76
+
77
+
78
+ end
79
+
80
+ private
81
+
82
+ def construct_status
83
+ @files = @base.lib.ls_files
84
+ ignore = @base.lib.ignored_files
85
+
86
+ # find untracked in working dir
87
+ Dir.chdir(@base.dir.path) do
88
+ Dir.glob('**/*') do |file|
89
+ @files[file] = {:path => file, :untracked => true} unless @files[file] || File.directory?(file) || ignore.include?(file)
90
+ end
91
+ end
92
+
93
+ # find modified in tree
94
+ @base.lib.diff_files.each do |path, data|
95
+ @files[path] ? @files[path].merge!(data) : @files[path] = data
96
+ end
97
+
98
+ # find added but not committed - new files
99
+ @base.lib.diff_index('HEAD').each do |path, data|
100
+ @files[path] ? @files[path].merge!(data) : @files[path] = data
101
+ end
102
+
103
+ @files.each do |k, file_hash|
104
+ @files[k] = StatusFile.new(@base, file_hash)
105
+ end
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,4 @@
1
+ module Git
2
+ class WorkingDirectory < Git::Path
3
+ end
4
+ end