birkirb-git 1.1.1

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/README ADDED
@@ -0,0 +1,244 @@
1
+ == Git Library for Ruby
2
+
3
+ Library for using Git in Ruby. Test.
4
+
5
+ = Homepage
6
+
7
+ The Ruby/Git homepage is currently at :
8
+
9
+ http://jointheconversation.org/rubygit
10
+
11
+ Git public hosting of the project source code is at:
12
+
13
+ http://github/schacon/ruby-git
14
+
15
+ = Install
16
+
17
+ You can install Ruby/Git like this:
18
+
19
+ $ sudo gem install schacon-git --source=http://gems.github.com
20
+
21
+ = Major Objects
22
+
23
+ Git::Base - this is the object returned from a Git.open or Git.clone.
24
+ Most major actions are called from this object.
25
+
26
+ Git::Object - this is the base object for your tree, blob and commit objects,
27
+ returned from @git.gtree or @git.object calls. the Git::AbstractObject will
28
+ have most of the calls in common for all those objects.
29
+
30
+ Git::Diff - returns from a @git.diff command. It is an Enumerable that returns
31
+ Git::Diff:DiffFile objects from which you can get per file patches and insertion/deletion
32
+ statistics. You can also get total statistics from the Git::Diff object directly.
33
+
34
+ Git::Status - returns from a @git.status command. It is an Enumerable that returns
35
+ Git:Status::StatusFile objects for each object in git, which includes files in the working
36
+ directory, in the index and in the repository. Similar to running 'git status' on the command
37
+ line to determine untracked and changed files.
38
+
39
+ Git::Branches - Enumerable object that holds Git::Branch objects. You can call .local or .remote
40
+ on it to filter to just your local or remote branches.
41
+
42
+ Git::Remote - A reference to a remote repository that is tracked by this repository.
43
+
44
+ Git::Log - An Enumerable object that references all the Git::Object::Commit objects that encompass
45
+ your log query, which can be constructed through methods on the Git::Log object, like:
46
+
47
+ @git.log(20).object("some_file").since("2 weeks ago").between('v2.6', 'v2.7').each { |commit| [block] }
48
+
49
+ = Examples
50
+
51
+ Here are a bunch of examples of how to use the Ruby/Git package.
52
+
53
+ First you have to remember to require rubygems if it's not. Then include the 'git' gem.
54
+
55
+ require 'rubygems'
56
+ require 'git'
57
+
58
+ Here are the operations that need read permission only.
59
+
60
+ g = Git.open (working_dir, :log => Logger.new(STDOUT))
61
+
62
+ g.index
63
+ g.index.readable?
64
+ g.index.writable?
65
+ g.repo
66
+ g.dir
67
+
68
+ g.log # returns array of Git::Commit objects
69
+ g.log.since('2 weeks ago')
70
+ g.log.between('v2.5', 'v2.6')
71
+ g.log.each {|l| puts l.sha }
72
+ g.gblob('v2.5:Makefile').log.since('2 weeks ago')
73
+
74
+ g.object('HEAD^').to_s # git show / git rev-parse
75
+ g.object('HEAD^').contents
76
+ g.object('v2.5:Makefile').size
77
+ g.object('v2.5:Makefile').sha
78
+
79
+ g.gtree(treeish)
80
+ g.gblob(treeish)
81
+ g.gcommit(treeish)
82
+
83
+
84
+ commit = g.gcommit('1cc8667014381')
85
+ commit.gtree
86
+ commit.parent.sha
87
+ commit.parents.size
88
+ commit.author.name
89
+ commit.author.email
90
+ commit.author.date.strftime("%m-%d-%y")
91
+ commit.committer.name
92
+ commit.date.strftime("%m-%d-%y")
93
+ commit.message
94
+
95
+ tree = g.gtree("HEAD^{tree}")
96
+ tree.blobs
97
+ tree.subtrees
98
+ tree.children # blobs and subtrees
99
+
100
+ g.revparse('v2.5:Makefile')
101
+
102
+ g.branches # returns Git::Branch objects
103
+ g.branches.local
104
+ g.branches.remote
105
+ g.branches[:master].gcommit
106
+ g.branches['origin/master'].gcommit
107
+
108
+ g.grep('hello') # implies HEAD
109
+ g.blob('v2.5:Makefile').grep('hello')
110
+ g.tag('v2.5').grep('hello', 'docs/')
111
+
112
+ g.diff(commit1, commit2).size
113
+ g.diff(commit1, commit2).stats
114
+ g.gtree('v2.5').diff('v2.6').insertions
115
+ g.diff('gitsearch1', 'v2.5').path('lib/')
116
+ g.diff('gitsearch1', @git.gtree('v2.5'))
117
+ g.diff('gitsearch1', 'v2.5').path('docs/').patch
118
+ g.gtree('v2.5').diff('v2.6').patch
119
+
120
+ g.gtree('v2.5').diff('v2.6').each do |file_diff|
121
+ puts file_diff.path
122
+ puts file_diff.patch
123
+ puts file_diff.blob(:src).contents
124
+ end
125
+
126
+ g.config('user.name') # returns 'Scott Chacon'
127
+ g.config # returns whole config hash
128
+
129
+ g.tag # returns array of Git::Tag objects
130
+
131
+
132
+
133
+ And here are the operations that will need to write to your git repository.
134
+
135
+
136
+ g = Git.init
137
+ Git.init('project')
138
+ Git.init('/home/schacon/proj',
139
+ { :git_dir => '/opt/git/proj.git',
140
+ :index_file => '/tmp/index'} )
141
+
142
+ g = Git.clone(URI, 'name', :path => '/tmp/checkout')
143
+ g.config('user.name', 'Scott Chacon')
144
+ g.config('user.email', 'email@email.com')
145
+
146
+ g.add('.')
147
+ g.add([file1, file2])
148
+
149
+ g.remove('file.txt')
150
+ g.remove(['file.txt', 'file2.txt'])
151
+
152
+ g.commit('message')
153
+ g.commit_all('message')
154
+
155
+ g = Git.clone(repo, 'myrepo')
156
+ g.chdir do
157
+ new_file('test-file', 'blahblahblah')
158
+ g.status.changed.each do |file|
159
+ puts file.blob(:index).contents
160
+ end
161
+ end
162
+
163
+ g.reset # defaults to HEAD
164
+ g.reset_hard(Git::Commit)
165
+
166
+ g.branch('new_branch') # creates new or fetches existing
167
+ g.branch('new_branch').checkout
168
+ g.branch('new_branch').delete
169
+ g.branch('existing_branch').checkout
170
+
171
+ g.checkout('new_branch')
172
+ g.checkout(g.branch('new_branch'))
173
+
174
+ g.branch(name).merge(branch2)
175
+ g.branch(branch2).merge # merges HEAD with branch2
176
+
177
+ g.branch(name).in_branch(message) { # add files } # auto-commits
178
+ g.merge('new_branch')
179
+ g.merge('origin/remote_branch')
180
+ g.merge(b.branch('master'))
181
+ g.merge([branch1, branch2])
182
+
183
+ r = g.add_remote(name, uri) # Git::Remote
184
+ r = g.add_remote(name, Git::Base) # Git::Remote
185
+
186
+ g.remotes # array of Git::Remotes
187
+ g.remote(name).fetch
188
+ g.remote(name).remove
189
+ g.remote(name).merge
190
+ g.remote(name).merge(branch)
191
+
192
+ g.fetch
193
+ g.fetch(g.remotes.first)
194
+
195
+ g.pull
196
+ g.pull(Git::Repo, Git::Branch) # fetch and a merge
197
+
198
+ g.add_tag('tag_name') # returns Git::Tag
199
+
200
+ g.repack
201
+
202
+ g.push
203
+ g.push(g.remote('name'))
204
+
205
+
206
+ Some examples of more low-level index and tree operations
207
+
208
+ g.with_temp_index do
209
+
210
+ g.read_tree(tree3) # calls self.index.read_tree
211
+ g.read_tree(tree1, :prefix => 'hi/')
212
+
213
+ c = g.commit_tree('message')
214
+ # or #
215
+ t = g.write_tree
216
+ c = g.commit_tree(t, :message => 'message', :parents => [sha1, sha2])
217
+
218
+ g.branch('branch_name').update_ref(c)
219
+ g.update_ref(branch, c)
220
+
221
+ g.with_temp_working do # new blank working directory
222
+ g.checkout
223
+ g.checkout(another_index)
224
+ g.commit # commits to temp_index
225
+ end
226
+ end
227
+
228
+ g.set_index('/path/to/index')
229
+
230
+
231
+ g.with_index(path) do
232
+ # calls set_index, then switches back after
233
+ end
234
+
235
+ g.with_working(dir) do
236
+ # calls set_working, then switches back after
237
+ end
238
+
239
+ g.with_temp_working(dir) do
240
+ g.checkout_index(:prefix => dir, :path_limiter => path)
241
+ # do file work
242
+ g.commit # commits to index
243
+ end
244
+
data/lib/git.rb ADDED
@@ -0,0 +1,112 @@
1
+
2
+ # Add the directory containing this file to the start of the load path if it
3
+ # isn't there already.
4
+ $:.unshift(File.dirname(__FILE__)) unless
5
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
6
+
7
+ require 'git/base'
8
+ require 'git/path'
9
+ require 'git/lib'
10
+
11
+ require 'git/repository'
12
+ require 'git/index'
13
+ require 'git/working_directory'
14
+
15
+ require 'git/log'
16
+ require 'git/object'
17
+
18
+ require 'git/branches'
19
+ require 'git/branch'
20
+ require 'git/submodules'
21
+ require 'git/submodule'
22
+ require 'git/remote'
23
+
24
+ require 'git/diff'
25
+ require 'git/status'
26
+ require 'git/author'
27
+
28
+ require 'git/stashes'
29
+ require 'git/stash'
30
+
31
+
32
+ # Git/Ruby Library
33
+ #
34
+ # This provides bindings for working with git in complex
35
+ # interactions, including branching and merging, object
36
+ # inspection and manipulation, history, patch generation
37
+ # and more. You should be able to do most fundamental git
38
+ # operations with this library.
39
+ #
40
+ # This module provides the basic functions to open a git
41
+ # reference to work with. You can open a working directory,
42
+ # open a bare repository, initialize a new repo or clone an
43
+ # existing remote repository.
44
+ #
45
+ # Author:: Scott Chacon (mailto:schacon@gmail.com)
46
+ # License:: MIT License
47
+ module Git
48
+
49
+ VERSION = '1.0.4'
50
+
51
+ # open a bare repository
52
+ #
53
+ # this takes the path to a bare git repo
54
+ # it expects not to be able to use a working directory
55
+ # so you can't checkout stuff, commit things, etc.
56
+ # but you can do most read operations
57
+ def self.bare(git_dir, options = {})
58
+ Base.bare(git_dir, options)
59
+ end
60
+
61
+ # open an existing git working directory
62
+ #
63
+ # this will most likely be the most common way to create
64
+ # a git reference, referring to a working directory.
65
+ # if not provided in the options, the library will assume
66
+ # your git_dir and index are in the default place (.git/, .git/index)
67
+ #
68
+ # options
69
+ # :repository => '/path/to/alt_git_dir'
70
+ # :index => '/path/to/alt_index_file'
71
+ def self.open(working_dir, options = {})
72
+ Base.open(working_dir, options)
73
+ end
74
+
75
+ # initialize a new git repository, defaults to the current working directory
76
+ #
77
+ # options
78
+ # :repository => '/path/to/alt_git_dir'
79
+ # :index => '/path/to/alt_index_file'
80
+ def self.init(working_dir = '.', options = {})
81
+ Base.init(working_dir, options)
82
+ end
83
+
84
+ # clones a remote repository
85
+ #
86
+ # options
87
+ # :bare => true (does a bare clone)
88
+ # :repository => '/path/to/alt_git_dir'
89
+ # :index => '/path/to/alt_index_file'
90
+ #
91
+ # example
92
+ # Git.clone('git://repo.or.cz/rubygit.git', 'clone.git', :bare => true)
93
+ #
94
+ def self.clone(repository, name, options = {})
95
+ Base.clone(repository, name, options)
96
+ end
97
+
98
+ # Export the current HEAD (or a branch, if <tt>options[:branch]</tt>
99
+ # is specified) into the +name+ directory, then remove all traces of git from the
100
+ # directory.
101
+ #
102
+ # See +clone+ for options. Does not obey the <tt>:remote</tt> option,
103
+ # since the .git info will be deleted anyway; always uses the default
104
+ # remote, 'origin.'
105
+ def self.export(repository, name, options = {})
106
+ options.delete(:remote)
107
+ repo = clone(repository, name, {:depth => 1}.merge(options))
108
+ repo.checkout("origin/#{options[:branch]}") if options[:branch]
109
+ Dir.chdir(repo.dir.to_s) { FileUtils.rm_r '.git' }
110
+ end
111
+
112
+ end
data/lib/git/author.rb ADDED
@@ -0,0 +1,14 @@
1
+ module Git
2
+ class Author
3
+ attr_accessor :name, :email, :date
4
+
5
+ def initialize(author_string)
6
+ if m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string)
7
+ @name = m[1]
8
+ @email = m[2]
9
+ @date = Time.at(m[3].to_i)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
data/lib/git/base.rb ADDED
@@ -0,0 +1,496 @@
1
+ module Git
2
+
3
+ class Base
4
+
5
+ # opens a bare Git Repository - no working directory options
6
+ def self.bare(git_dir, opts = {})
7
+ self.new({:repository => git_dir}.merge(opts))
8
+ end
9
+
10
+ # opens a new Git Project from a working directory
11
+ # you can specify non-standard git_dir and index file in the options
12
+ def self.open(working_dir, opts={})
13
+ self.new({:working_directory => working_dir}.merge(opts))
14
+ end
15
+
16
+ # initializes a git repository
17
+ #
18
+ # options:
19
+ # :repository
20
+ # :index_file
21
+ #
22
+ def self.init(working_dir, opts = {})
23
+ opts = {
24
+ :working_directory => working_dir,
25
+ :repository => File.join(working_dir, '.git')
26
+ }.merge(opts)
27
+
28
+ FileUtils.mkdir_p(opts[:working_directory]) if opts[:working_directory] && !File.directory?(opts[:working_directory])
29
+
30
+ # run git_init there
31
+ Git::Lib.new(opts).init
32
+
33
+ self.new(opts)
34
+ end
35
+
36
+ # clones a git repository locally
37
+ #
38
+ # repository - http://repo.or.cz/w/sinatra.git
39
+ # name - sinatra
40
+ #
41
+ # options:
42
+ # :repository
43
+ #
44
+ # :bare
45
+ # or
46
+ # :working_directory
47
+ # :index_file
48
+ #
49
+ def self.clone(repository, name, opts = {})
50
+ # run git-clone
51
+ self.new(Git::Lib.new.clone(repository, name, opts))
52
+ end
53
+
54
+ def initialize(options = {})
55
+ if working_dir = options[:working_directory]
56
+ options[:repository] ||= File.join(working_dir, '.git')
57
+ options[:index] ||= File.join(working_dir, '.git', 'index')
58
+ end
59
+ if options[:log]
60
+ @logger = options[:log]
61
+ @logger.info("Starting Git")
62
+ else
63
+ @logger = nil
64
+ end
65
+
66
+ @working_directory = options[:working_directory] ? Git::WorkingDirectory.new(options[:working_directory]) : nil
67
+ @repository = options[:repository] ? Git::Repository.new(options[:repository]) : nil
68
+ @index = options[:index] ? Git::Index.new(options[:index], false) : nil
69
+ end
70
+
71
+
72
+ # returns a reference to the working directory
73
+ # @git.dir.path
74
+ # @git.dir.writeable?
75
+ def dir
76
+ @working_directory
77
+ end
78
+
79
+ # returns reference to the git repository directory
80
+ # @git.dir.path
81
+ def repo
82
+ @repository
83
+ end
84
+
85
+ # returns reference to the git index file
86
+ def index
87
+ @index
88
+ end
89
+
90
+
91
+ def set_working(work_dir, check = true)
92
+ @lib = nil
93
+ @working_directory = Git::WorkingDirectory.new(work_dir.to_s, check)
94
+ end
95
+
96
+ def set_index(index_file, check = true)
97
+ @lib = nil
98
+ @index = Git::Index.new(index_file.to_s, check)
99
+ end
100
+
101
+ # changes current working directory for a block
102
+ # to the git working directory
103
+ #
104
+ # example
105
+ # @git.chdir do
106
+ # # write files
107
+ # @git.add
108
+ # @git.commit('message')
109
+ # end
110
+ def chdir # :yields: the Git::Path
111
+ Dir.chdir(dir.path) do
112
+ yield dir.path
113
+ end
114
+ end
115
+
116
+ # returns the repository size in bytes
117
+ def repo_size
118
+ size = 0
119
+ Dir.chdir(repo.path) do
120
+ (size, dot) = `du -s`.chomp.split
121
+ end
122
+ size.to_i
123
+ end
124
+
125
+ #g.config('user.name', 'Scott Chacon') # sets value
126
+ #g.config('user.email', 'email@email.com') # sets value
127
+ #g.config('user.name') # returns 'Scott Chacon'
128
+ #g.config # returns whole config hash
129
+ def config(name = nil, value = nil)
130
+ if(name && value)
131
+ # set value
132
+ lib.config_set(name, value)
133
+ elsif (name)
134
+ # return value
135
+ lib.config_get(name)
136
+ else
137
+ # return hash
138
+ lib.config_list
139
+ end
140
+ end
141
+
142
+ # factory methods
143
+
144
+ # returns a Git::Object of the appropriate type
145
+ # you can also call @git.gtree('tree'), but that's
146
+ # just for readability. If you call @git.gtree('HEAD') it will
147
+ # still return a Git::Object::Commit object.
148
+ #
149
+ # @git.object calls a factory method that will run a rev-parse
150
+ # on the objectish and determine the type of the object and return
151
+ # an appropriate object for that type
152
+ def object(objectish)
153
+ Git::Object.new(self, objectish)
154
+ end
155
+
156
+ def gtree(objectish)
157
+ Git::Object.new(self, objectish, 'tree')
158
+ end
159
+
160
+ def gcommit(objectish)
161
+ Git::Object.new(self, objectish, 'commit')
162
+ end
163
+
164
+ def gblob(objectish)
165
+ Git::Object.new(self, objectish, 'blob')
166
+ end
167
+
168
+ # returns a Git::Log object with count commits
169
+ def log(count = 30)
170
+ Git::Log.new(self, count)
171
+ end
172
+
173
+ # returns a Git::Status object
174
+ def status
175
+ Git::Status.new(self)
176
+ end
177
+
178
+ # returns a Git::Branches object of all the Git::Branch objects for this repo
179
+ def branches
180
+ Git::Branches.new(self)
181
+ end
182
+
183
+ # returns a Git::Branch object for branch_name
184
+ def branch(branch_name = 'master')
185
+ Git::Branch.new(self, branch_name)
186
+ end
187
+
188
+ # returns a Git::Submodules object of all the Git::Submodule objects for this repo
189
+ def submodules
190
+ Git::Submodules.new(self)
191
+ end
192
+
193
+ # returns a Git::Submodule object for a specific submodule path
194
+ def submodule(path)
195
+ Git::Submodule.new(path)
196
+ end
197
+
198
+ # Add a submodule to a repository.
199
+ # To specify a path use option:
200
+ #
201
+ # :path => 'path/to/submodule'
202
+ #
203
+ def add_submodule(url, opts = {})
204
+ self.lib.submodule_add(url, opts)
205
+ end
206
+
207
+ # returns +true+ if the branch exists locally
208
+ def is_local_branch?(branch)
209
+ branch_names = self.branches.local.map {|b| b.name}
210
+ branch_names.include?(branch)
211
+ end
212
+
213
+ # returns +true+ if the branch exists remotely
214
+ def is_remote_branch?(branch)
215
+ branch_names = self.branches.local.map {|b| b.name}
216
+ branch_names.include?(branch)
217
+ end
218
+
219
+ # returns +true+ if the branch exists
220
+ def is_branch?(branch)
221
+ branch_names = self.branches.map {|b| b.name}
222
+ branch_names.include?(branch)
223
+ end
224
+
225
+ # returns a Git::Remote object
226
+ def remote(remote_name = 'origin')
227
+ Git::Remote.new(self, remote_name)
228
+ end
229
+
230
+ # this is a convenience method for accessing the class that wraps all the
231
+ # actual 'git' forked system calls. At some point I hope to replace the Git::Lib
232
+ # class with one that uses native methods or libgit C bindings
233
+ def lib
234
+ @lib ||= Git::Lib.new(self, @logger)
235
+ end
236
+
237
+ # will run a grep for 'string' on the HEAD of the git repository
238
+ #
239
+ # to be more surgical in your grep, you can call grep() off a specific
240
+ # git object. for example:
241
+ #
242
+ # @git.object("v2.3").grep('TODO')
243
+ #
244
+ # in any case, it returns a hash of arrays of the type:
245
+ # hsh[tree-ish] = [[line_no, match], [line_no, match2]]
246
+ # hsh[tree-ish] = [[line_no, match], [line_no, match2]]
247
+ #
248
+ # so you might use it like this:
249
+ #
250
+ # @git.grep("TODO").each do |sha, arr|
251
+ # puts "in blob #{sha}:"
252
+ # arr.each do |match|
253
+ # puts "\t line #{match[0]}: '#{match[1]}'"
254
+ # end
255
+ # end
256
+ def grep(string, path_limiter = nil, opts = {})
257
+ self.object('HEAD').grep(string, path_limiter, opts)
258
+ end
259
+
260
+ # returns a Git::Diff object
261
+ def diff(objectish = 'HEAD', obj2 = nil)
262
+ Git::Diff.new(self, objectish, obj2)
263
+ end
264
+
265
+ # adds files from the working directory to the git repository
266
+ def add(path = '.')
267
+ self.lib.add(path)
268
+ end
269
+
270
+ # removes file(s) from the git repository
271
+ def remove(path = '.', opts = {})
272
+ self.lib.remove(path, opts)
273
+ end
274
+
275
+ # resets the working directory to the provided commitish
276
+ def reset(commitish = nil, opts = {})
277
+ self.lib.reset(commitish, opts)
278
+ end
279
+
280
+ # resets the working directory to the commitish with '--hard'
281
+ def reset_hard(commitish = nil, opts = {})
282
+ opts = {:hard => true}.merge(opts)
283
+ self.lib.reset(commitish, opts)
284
+ end
285
+
286
+ # commits all pending changes in the index file to the git repository
287
+ #
288
+ # options:
289
+ # :add_all
290
+ # :allow_empty
291
+ # :author
292
+ def commit(message, opts = {})
293
+ self.lib.commit(message, opts)
294
+ end
295
+
296
+ # commits all pending changes in the index file to the git repository,
297
+ # but automatically adds all modified files without having to explicitly
298
+ # calling @git.add() on them.
299
+ def commit_all(message, opts = {})
300
+ opts = {:add_all => true}.merge(opts)
301
+ self.lib.commit(message, opts)
302
+ end
303
+
304
+ # checks out a branch as the new git working directory
305
+ def checkout(branch = 'master', opts = {})
306
+ self.lib.checkout(branch, opts)
307
+ end
308
+
309
+ # checks out an old version of a file
310
+ def checkout_file(version, file)
311
+ self.lib.checkout_file(version,file)
312
+ end
313
+
314
+ # fetches changes from a remote branch - this does not modify the working directory,
315
+ # it just gets the changes from the remote if there are any
316
+ def fetch(remote = 'origin')
317
+ self.lib.fetch(remote)
318
+ end
319
+
320
+ # pushes changes to a remote repository - easiest if this is a cloned repository,
321
+ # otherwise you may have to run something like this first to setup the push parameters:
322
+ #
323
+ # @git.config('remote.remote-name.push', 'refs/heads/master:refs/heads/master')
324
+ #
325
+ def push(remote = 'origin', branch = 'master', tags = false)
326
+ self.lib.push(remote, branch, tags)
327
+ end
328
+
329
+ # merges one or more branches into the current working branch
330
+ #
331
+ # you can specify more than one branch to merge by passing an array of branches
332
+ def merge(branch, message = 'merge')
333
+ self.lib.merge(branch, message)
334
+ end
335
+
336
+ # iterates over the files which are unmerged
337
+ def each_conflict(&block) # :yields: file, your_version, their_version
338
+ self.lib.conflicts(&block)
339
+ end
340
+
341
+ # fetches a branch from a remote and merges it into the current working branch
342
+ def pull(remote = 'origin', branch = 'master', message = 'origin pull')
343
+ fetch(remote)
344
+ merge(branch, message)
345
+ end
346
+
347
+ # returns an array of Git:Remote objects
348
+ def remotes
349
+ self.lib.remotes.map { |r| Git::Remote.new(self, r) }
350
+ end
351
+
352
+ # adds a new remote to this repository
353
+ # url can be a git url or a Git::Base object if it's a local reference
354
+ #
355
+ # @git.add_remote('scotts_git', 'git://repo.or.cz/rubygit.git')
356
+ # @git.fetch('scotts_git')
357
+ # @git.merge('scotts_git/master')
358
+ #
359
+ def add_remote(name, url, opts = {})
360
+ url = url.repo.path if url.is_a?(Git::Base)
361
+ self.lib.remote_add(name, url, opts)
362
+ Git::Remote.new(self, name)
363
+ end
364
+
365
+ # returns an array of all Git::Tag objects for this repository
366
+ def tags
367
+ self.lib.tags.map { |r| tag(r) }
368
+ end
369
+
370
+ # returns a Git::Tag object
371
+ def tag(tag_name)
372
+ Git::Object.new(self, tag_name, 'tag', true)
373
+ end
374
+
375
+ # creates a new git tag (Git::Tag)
376
+ def add_tag(tag_name)
377
+ self.lib.tag(tag_name)
378
+ tag(tag_name)
379
+ end
380
+
381
+ # creates an archive file of the given tree-ish
382
+ def archive(treeish, file = nil, opts = {})
383
+ self.object(treeish).archive(file, opts)
384
+ end
385
+
386
+ # repacks the repository
387
+ def repack
388
+ self.lib.repack
389
+ end
390
+
391
+ def gc
392
+ self.lib.gc
393
+ end
394
+
395
+ def apply(file)
396
+ if File.exists?(file)
397
+ self.lib.apply(file)
398
+ end
399
+ end
400
+
401
+ def apply_mail(file)
402
+ self.lib.apply_mail(file) if File.exists?(file)
403
+ end
404
+
405
+ ## LOWER LEVEL INDEX OPERATIONS ##
406
+
407
+ def with_index(new_index) # :yields: new_index
408
+ old_index = @index
409
+ set_index(new_index, false)
410
+ return_value = yield @index
411
+ set_index(old_index)
412
+ return_value
413
+ end
414
+
415
+ def with_temp_index &blk
416
+ tempfile = Tempfile.new('temp-index')
417
+ temp_path = tempfile.path
418
+ tempfile.unlink
419
+ with_index(temp_path, &blk)
420
+ end
421
+
422
+ def checkout_index(opts = {})
423
+ self.lib.checkout_index(opts)
424
+ end
425
+
426
+ def read_tree(treeish, opts = {})
427
+ self.lib.read_tree(treeish, opts)
428
+ end
429
+
430
+ def write_tree
431
+ self.lib.write_tree
432
+ end
433
+
434
+ def commit_tree(tree = nil, opts = {})
435
+ Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
436
+ end
437
+
438
+ def write_and_commit_tree(opts = {})
439
+ tree = write_tree
440
+ commit_tree(tree, opts)
441
+ end
442
+
443
+ def update_ref(branch, commit)
444
+ branch(branch).update_ref(commit)
445
+ end
446
+
447
+
448
+ def ls_files
449
+ self.lib.ls_files
450
+ end
451
+
452
+ def with_working(work_dir) # :yields: the Git::WorkingDirectory
453
+ return_value = false
454
+ old_working = @working_directory
455
+ set_working(work_dir)
456
+ Dir.chdir work_dir do
457
+ return_value = yield @working_directory
458
+ end
459
+ set_working(old_working)
460
+ return_value
461
+ end
462
+
463
+ def with_temp_working &blk
464
+ tempfile = Tempfile.new("temp-workdir")
465
+ temp_dir = tempfile.path
466
+ tempfile.unlink
467
+ Dir.mkdir(temp_dir, 0700)
468
+ with_working(temp_dir, &blk)
469
+ end
470
+
471
+
472
+ # runs git rev-parse to convert the objectish to a full sha
473
+ #
474
+ # @git.revparse("HEAD^^")
475
+ # @git.revparse('v2.4^{tree}')
476
+ # @git.revparse('v2.4:/doc/index.html')
477
+ #
478
+ def revparse(objectish)
479
+ self.lib.revparse(objectish)
480
+ end
481
+
482
+ def ls_tree(objectish)
483
+ self.lib.ls_tree(objectish)
484
+ end
485
+
486
+ def cat_file(objectish)
487
+ self.lib.object_contents(objectish)
488
+ end
489
+
490
+ # returns the name of the branch the working directory is currently on
491
+ def current_branch
492
+ self.lib.branch_current
493
+ end
494
+
495
+ end
496
+ end