schacon-git 1.0.6

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