ruby-git-yz 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1bc4cd37c73a1a0de02f66af9e26a5f461da4a92
4
+ data.tar.gz: 9d18f38cfaa1b43c78d72159a4ffbb52cd1d09a4
5
+ SHA512:
6
+ metadata.gz: 953a988118f8f471ade0d628ec2612b4de804a0627590859499b20ba6a1a211d64ebed3c2b2696c3aa814a779d0d1f58cd2c43bb5dc21e2d0c91fb37f390ed2a
7
+ data.tar.gz: 635260465a710f273317698071dd3ef53b68f2f703db8d8b4ff125b7354d1a1a7b9311a441746383ae244c1a214b32fca2743352379afd3dbbecbb1a186625d8
@@ -0,0 +1,84 @@
1
+ == 1.3.0
2
+
3
+ * Dropping Ruby 1.8.x support
4
+
5
+ == 1.2.10
6
+
7
+ * Adding Git::Diff.name_status
8
+ * Checking and fixing encoding on commands output to prevent encoding errors afterwards
9
+
10
+ == 1.2.9
11
+
12
+ * Adding Git.configure (to configure the git env)
13
+ * Adding Git.ls_remote [Git.ls_remote(repo_path_or_url='.')]
14
+ * Adding Git.describe [repo.describe(objectish, opts)]
15
+ * Adding Git.show [repo.show(objectish=nil, path=nil)]
16
+ * Fixing Git::Diff to support default references (implicit references)
17
+ * Fixing Git::Diff to support diff over git .patch files
18
+ * Fixing Git.checkout when using :new_branch opt
19
+ * Fixing Git::Object::Commit to preserve its sha after fetching metadata
20
+ * Fixing Git.is_remote_branch? to actually check against remote branches
21
+ * Improvements over how ENV variables are modified
22
+ * Improving thrade safety (using --git-dir and --work-tree git opts)
23
+ * Improving Git::Object::Tag. Adding annotated?, tagger and message
24
+ * Supporting a submodule path as a valid repo
25
+ * Git.checkout - supporting -f and -b
26
+ * Git.clone - supporting --branch
27
+ * Git.fetch - supporting --prune
28
+ * Git.tag - supporting
29
+
30
+ == 1.2.8
31
+
32
+ * Keeping the old escape format for windows users
33
+ * revparse: Supporting ref names containing SHA like substrings (40-hex strings)
34
+ * Fix warnings on Ruby 2.1.2
35
+
36
+ == 1.2.7
37
+
38
+ * Fixing mesages encoding
39
+ * Fixing -f flag in git push
40
+ * Fixing log parser for multiline messages
41
+ * Supporting object references on Git.add_tag
42
+ * Including dotfiles on Git.status
43
+ * Git.fetch - supporting --tags
44
+ * Git.clean - supporting -x
45
+ * Git.add_tag options - supporting -a, -m and -s
46
+ * Added Git.delete_tag
47
+
48
+ == 1.2.6
49
+
50
+ * Ruby 1.9.X/2.0 fully supported
51
+ * JRuby 1.8/1.9 support
52
+ * Rubinius support
53
+ * Git.clone - supporting --recursive and --config
54
+ * Git.log - supporting last and [] over the results
55
+ * Git.add_remote - supporting -f and -t
56
+ * Git.add - supporting --fore
57
+ * Git.init - supporting --bare
58
+ * Git.commit - supporting --all and --amend
59
+ * Added Git.remote_remote, Git.revert and Git.clean
60
+ * Added Bundler to the formula
61
+ * Travis configuration
62
+ * Licence included with the gem
63
+
64
+ == 1.0.4
65
+
66
+ * added camping/gitweb.rb frontend
67
+ * added a number of speed-ups
68
+
69
+ == 1.0.3
70
+
71
+ * Sped up most of the operations
72
+ * Added some predicate functions (commit?, tree?, etc)
73
+ * Added a number of lower level operations (read-tree, write-tree, checkout-index, etc)
74
+ * Fixed a bug with using bare repositories
75
+ * Updated a good amount of the documentation
76
+
77
+ == 1.0.2
78
+
79
+ * Added methods to the git objects that might be helpful
80
+
81
+ == 1.0.1
82
+
83
+ * Initial version
84
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008 Scott Chacon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,297 @@
1
+ # Git Library for Ruby
2
+
3
+ Library for using Git in Ruby.
4
+
5
+ ## Homepage
6
+
7
+ Git public hosting of the project source code is at:
8
+
9
+ http://github.com/schacon/ruby-git
10
+
11
+ ## Install
12
+
13
+ You can install Ruby/Git like this:
14
+
15
+ $ sudo gem install git
16
+
17
+ ## Code Status
18
+
19
+ * [![Build Status](https://api.travis-ci.org/schacon/ruby-git.png)](https://travis-ci.org/schacon/ruby-git)
20
+ * [![Code Climate](https://codeclimate.com/github/schacon/ruby-git.png)](https://codeclimate.com/github/schacon/ruby-git)
21
+ * [![Gem Version](https://badge.fury.io/rb/git.png)](http://badge.fury.io/rb/git)
22
+ * [![Dependencies](https://gemnasium.com/schacon/ruby-git.png?travis)](https://gemnasium.com/schacon/ruby-git)
23
+
24
+ ## Major Objects
25
+
26
+ **Git::Base** - The object returned from a `Git.open` or `Git.clone`. Most major actions are called from this object.
27
+
28
+ **Git::Object** - The base object for your tree, blob and commit objects, returned from `@git.gtree` or `@git.object` calls. the `Git::AbstractObject` will 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 `Git::Diff:DiffFile` objects from which you can get per file patches and insertion/deletion statistics. You can also get total statistics from the Git::Diff object directly.
31
+
32
+ **Git::Status** - returns from a `@git.status` command. It is an Enumerable that returns
33
+ `Git:Status::StatusFile` objects for each object in git, which includes files in the working
34
+ directory, in the index and in the repository. Similar to running 'git status' on the command line to determine untracked and changed files.
35
+
36
+ **Git::Branches** - Enumerable object that holds `Git::Branch objects`. You can call .local or .remote on it to filter to just your local or remote branches.
37
+
38
+ **Git::Remote**- A reference to a remote repository that is tracked by this repository.
39
+
40
+ **Git::Log** - An Enumerable object that references all the `Git::Object::Commit` objects that encompass your log query, which can be constructed through methods on the `Git::Log object`,
41
+ like:
42
+
43
+ `@git.log(20).object("some_file").since("2 weeks ago").between('v2.6', 'v2.7').each { |commit| [block] }`
44
+
45
+ ## Examples
46
+
47
+ Here are a bunch of examples of how to use the Ruby/Git package.
48
+
49
+ Ruby < 1.9 will require rubygems to be loaded.
50
+
51
+ ```ruby
52
+ require 'rubygems'
53
+ ```
54
+
55
+ Require the 'git' gem.
56
+ ```ruby
57
+ require 'git'
58
+ ```
59
+
60
+ Git env config
61
+
62
+ ```ruby
63
+ Git.configure do |config|
64
+ # If you want to use a custom git binary
65
+ config.binary_path = '/git/bin/path'
66
+
67
+ # If you need to use a custom SSH script
68
+ config.git_ssh = '/path/to/ssh/script'
69
+ end
70
+
71
+ ```
72
+
73
+
74
+ Here are the operations that need read permission only.
75
+
76
+ ```ruby
77
+ g = Git.open(working_dir, :log => Logger.new(STDOUT))
78
+
79
+ g.index
80
+ g.index.readable?
81
+ g.index.writable?
82
+ g.repo
83
+ g.dir
84
+
85
+ g.log # returns array of Git::Commit objects
86
+ g.log.since('2 weeks ago')
87
+ g.log.between('v2.5', 'v2.6')
88
+ g.log.each {|l| puts l.sha }
89
+ g.gblob('v2.5:Makefile').log.since('2 weeks ago')
90
+
91
+ g.object('HEAD^').to_s # git show / git rev-parse
92
+ g.object('HEAD^').contents
93
+ g.object('v2.5:Makefile').size
94
+ g.object('v2.5:Makefile').sha
95
+
96
+ g.gtree(treeish)
97
+ g.gblob(treeish)
98
+ g.gcommit(treeish)
99
+
100
+
101
+ commit = g.gcommit('1cc8667014381')
102
+
103
+ commit.gtree
104
+ commit.parent.sha
105
+ commit.parents.size
106
+ commit.author.name
107
+ commit.author.email
108
+ commit.author.date.strftime("%m-%d-%y")
109
+ commit.committer.name
110
+ commit.date.strftime("%m-%d-%y")
111
+ commit.message
112
+
113
+ tree = g.gtree("HEAD^{tree}")
114
+
115
+ tree.blobs
116
+ tree.subtrees
117
+ tree.children # blobs and subtrees
118
+
119
+ g.revparse('v2.5:Makefile')
120
+
121
+ g.branches # returns Git::Branch objects
122
+ g.branches.local
123
+ g.branches.remote
124
+ g.branches[:master].gcommit
125
+ g.branches['origin/master'].gcommit
126
+
127
+ g.grep('hello') # implies HEAD
128
+ g.blob('v2.5:Makefile').grep('hello')
129
+ g.tag('v2.5').grep('hello', 'docs/')
130
+ g.describe()
131
+ g.describe('0djf2aa')
132
+ g.describe('HEAD', {:all => true, :tags => true})
133
+
134
+ g.diff(commit1, commit2).size
135
+ g.diff(commit1, commit2).stats
136
+ g.diff(commit1, commit2).name_status
137
+ g.gtree('v2.5').diff('v2.6').insertions
138
+ g.diff('gitsearch1', 'v2.5').path('lib/')
139
+ g.diff('gitsearch1', @git.gtree('v2.5'))
140
+ g.diff('gitsearch1', 'v2.5').path('docs/').patch
141
+ g.gtree('v2.5').diff('v2.6').patch
142
+
143
+ g.gtree('v2.5').diff('v2.6').each do |file_diff|
144
+ puts file_diff.path
145
+ puts file_diff.patch
146
+ puts file_diff.blob(:src).contents
147
+ end
148
+
149
+ g.config('user.name') # returns 'Scott Chacon'
150
+ g.config # returns whole config hash
151
+
152
+ g.tags # returns array of Git::Tag objects
153
+
154
+ g.show()
155
+ g.show('HEAD')
156
+ g.show('v2.8', 'README.md')
157
+
158
+ Git.ls_remote('https://github.com/schacon/ruby-git.git') # returns a hash containing the available references of the repo.
159
+ Git.ls_remote('/path/to/local/repo')
160
+ Git.ls_remote() # same as Git.ls_remote('.')
161
+
162
+ ```
163
+
164
+ And here are the operations that will need to write to your git repository.
165
+
166
+ ```ruby
167
+ g = Git.init
168
+ Git.init('project')
169
+ Git.init('/home/schacon/proj',
170
+ { :repository => '/opt/git/proj.git',
171
+ :index => '/tmp/index'} )
172
+
173
+ g = Git.clone(URI, NAME, :path => '/tmp/checkout')
174
+ g.config('user.name', 'Scott Chacon')
175
+ g.config('user.email', 'email@email.com')
176
+
177
+ g.add # git add -- "."
178
+ g.add(:all=>true) # git add --all -- "."
179
+ g.add('file_path') # git add -- "file_path"
180
+ g.add(['file_path_1', 'file_path_2']) # git add -- "file_path_1" "file_path_2"
181
+
182
+ g.remove() # git rm -f -- "."
183
+ g.remove('file.txt') # git rm -f -- "file.txt"
184
+ g.remove(['file.txt', 'file2.txt']) # git rm -f -- "file.txt" "file2.txt"
185
+ g.remove('file.txt', :recursive => true) # git rm -f -r -- "file.txt"
186
+ g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"
187
+
188
+ g.commit('message')
189
+ g.commit_all('message')
190
+
191
+ g = Git.clone(repo, 'myrepo')
192
+ g.chdir do
193
+ new_file('test-file', 'blahblahblah')
194
+ g.status.changed.each do |file|
195
+ puts file.blob(:index).contents
196
+ end
197
+ end
198
+
199
+ g.reset # defaults to HEAD
200
+ g.reset_hard(Git::Commit)
201
+
202
+ g.branch('new_branch') # creates new or fetches existing
203
+ g.branch('new_branch').checkout
204
+ g.branch('new_branch').delete
205
+ g.branch('existing_branch').checkout
206
+
207
+ g.checkout('new_branch')
208
+ g.checkout(g.branch('new_branch'))
209
+
210
+ g.branch(name).merge(branch2)
211
+ g.branch(branch2).merge # merges HEAD with branch2
212
+
213
+ g.branch(name).in_branch(message) { # add files } # auto-commits
214
+ g.merge('new_branch')
215
+ g.merge('origin/remote_branch')
216
+ g.merge(g.branch('master'))
217
+ g.merge([branch1, branch2])
218
+
219
+ r = g.add_remote(name, uri) # Git::Remote
220
+ r = g.add_remote(name, Git::Base) # Git::Remote
221
+
222
+ g.remotes # array of Git::Remotes
223
+ g.remote(name).fetch
224
+ g.remote(name).remove
225
+ g.remote(name).merge
226
+ g.remote(name).merge(branch)
227
+
228
+ g.fetch
229
+ g.fetch(g.remotes.first)
230
+
231
+ g.pull
232
+ g.pull(Git::Repo, Git::Branch) # fetch and a merge
233
+
234
+ g.add_tag('tag_name') # returns Git::Tag
235
+ g.add_tag('tag_name', 'object_reference')
236
+ g.add_tag('tag_name', 'object_reference', {:options => 'here'})
237
+ g.add_tag('tag_name', {:options => 'here'})
238
+
239
+ Options:
240
+ :a | :annotate
241
+ :d
242
+ :f
243
+ :m | :message
244
+ :s
245
+
246
+ g.delete_tag('tag_name')
247
+
248
+ g.repack
249
+
250
+ g.push
251
+ g.push(g.remote('name'))
252
+ ```
253
+
254
+ Some examples of more low-level index and tree operations
255
+
256
+ ```ruby
257
+ g.with_temp_index do
258
+
259
+ g.read_tree(tree3) # calls self.index.read_tree
260
+ g.read_tree(tree1, :prefix => 'hi/')
261
+
262
+ c = g.commit_tree('message')
263
+ # or #
264
+ t = g.write_tree
265
+ c = g.commit_tree(t, :message => 'message', :parents => [sha1, sha2])
266
+
267
+ g.branch('branch_name').update_ref(c)
268
+ g.update_ref(branch, c)
269
+
270
+ g.with_temp_working do # new blank working directory
271
+ g.checkout
272
+ g.checkout(another_index)
273
+ g.commit # commits to temp_index
274
+ end
275
+ end
276
+
277
+ g.set_index('/path/to/index')
278
+
279
+
280
+ g.with_index(path) do
281
+ # calls set_index, then switches back after
282
+ end
283
+
284
+ g.with_working(dir) do
285
+ # calls set_working, then switches back after
286
+ end
287
+
288
+ g.with_temp_working(dir) do
289
+ g.checkout_index(:prefix => dir, :path_limiter => path)
290
+ # do file work
291
+ g.commit # commits to index
292
+ end
293
+ ```
294
+
295
+ ## License
296
+
297
+ licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further details.
data/VERSION ADDED
@@ -0,0 +1,2 @@
1
+ 1.3.0
2
+
@@ -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
@@ -0,0 +1,540 @@
1
+ require 'git/base/factory'
2
+
3
+ module Git
4
+
5
+ class Base
6
+
7
+ include Git::Base::Factory
8
+
9
+ # opens a bare Git Repository - no working directory options
10
+ def self.bare(git_dir, opts = {})
11
+ self.new({:repository => git_dir}.merge(opts))
12
+ end
13
+
14
+ # clones a git repository locally
15
+ #
16
+ # repository - http://repo.or.cz/w/sinatra.git
17
+ # name - sinatra
18
+ #
19
+ # options:
20
+ # :repository
21
+ #
22
+ # :bare
23
+ # or
24
+ # :working_directory
25
+ # :index_file
26
+ #
27
+ def self.clone(repository, name, opts = {})
28
+ # run git-clone
29
+ self.new(Git::Lib.new.clone(repository, name, opts))
30
+ end
31
+
32
+ # Returns (and initialize if needed) a Git::Config instance
33
+ #
34
+ # @return [Git::Config] the current config instance.
35
+ def self.config
36
+ return @@config ||= Config.new
37
+ end
38
+
39
+ # initializes a git repository
40
+ #
41
+ # options:
42
+ # :bare
43
+ # :index
44
+ # :repository
45
+ #
46
+ def self.init(working_dir, opts = {})
47
+ opts[:working_directory] ||= working_dir
48
+ opts[:repository] ||= File.join(opts[:working_directory], '.git')
49
+
50
+ FileUtils.mkdir_p(opts[:working_directory]) if opts[:working_directory] && !File.directory?(opts[:working_directory])
51
+
52
+ init_opts = {
53
+ :bare => opts[:bare]
54
+ }
55
+
56
+ opts.delete(:working_directory) if opts[:bare]
57
+
58
+ # Submodules have a .git *file* not a .git folder.
59
+ # This file's contents point to the location of
60
+ # where the git refs are held (In the parent repo)
61
+ if File.file?('.git')
62
+ git_file = File.open('.git').read[8..-1].strip
63
+ opts[:repository] = git_file
64
+ opts[:index] = git_file + '/index'
65
+ end
66
+
67
+ Git::Lib.new(opts).init(init_opts)
68
+
69
+ self.new(opts)
70
+ end
71
+
72
+ # opens a new Git Project from a working directory
73
+ # you can specify non-standard git_dir and index file in the options
74
+ def self.open(working_dir, opts={})
75
+ self.new({:working_directory => working_dir}.merge(opts))
76
+ end
77
+
78
+ def initialize(options = {})
79
+ if working_dir = options[:working_directory]
80
+ options[:repository] ||= File.join(working_dir, '.git')
81
+ options[:index] ||= File.join(working_dir, '.git', 'index')
82
+ end
83
+ if options[:log]
84
+ @logger = options[:log]
85
+ @logger.info("Starting Git")
86
+ else
87
+ @logger = nil
88
+ end
89
+
90
+ @working_directory = options[:working_directory] ? Git::WorkingDirectory.new(options[:working_directory]) : nil
91
+ @repository = options[:repository] ? Git::Repository.new(options[:repository]) : nil
92
+ @index = options[:index] ? Git::Index.new(options[:index], false) : nil
93
+ end
94
+
95
+ # changes current working directory for a block
96
+ # to the git working directory
97
+ #
98
+ # example
99
+ # @git.chdir do
100
+ # # write files
101
+ # @git.add
102
+ # @git.commit('message')
103
+ # end
104
+ def chdir # :yields: the Git::Path
105
+ Dir.chdir(dir.path) do
106
+ yield dir.path
107
+ end
108
+ end
109
+
110
+ #g.config('user.name', 'Scott Chacon') # sets value
111
+ #g.config('user.email', 'email@email.com') # sets value
112
+ #g.config('user.name') # returns 'Scott Chacon'
113
+ #g.config # returns whole config hash
114
+ def config(name = nil, value = nil)
115
+ if(name && value)
116
+ # set value
117
+ lib.config_set(name, value)
118
+ elsif (name)
119
+ # return value
120
+ lib.config_get(name)
121
+ else
122
+ # return hash
123
+ lib.config_list
124
+ end
125
+ end
126
+
127
+ # returns a reference to the working directory
128
+ # @git.dir.path
129
+ # @git.dir.writeable?
130
+ def dir
131
+ @working_directory
132
+ end
133
+
134
+ # returns reference to the git index file
135
+ def index
136
+ @index
137
+ end
138
+
139
+ # returns reference to the git repository directory
140
+ # @git.dir.path
141
+ def repo
142
+ @repository
143
+ end
144
+
145
+ # returns the repository size in bytes
146
+ def repo_size
147
+ Dir.chdir(repo.path) do
148
+ return `du -s`.chomp.split.first.to_i
149
+ end
150
+ end
151
+
152
+ def set_index(index_file, check = true)
153
+ @lib = nil
154
+ @index = Git::Index.new(index_file.to_s, check)
155
+ end
156
+
157
+ def set_working(work_dir, check = true)
158
+ @lib = nil
159
+ @working_directory = Git::WorkingDirectory.new(work_dir.to_s, check)
160
+ end
161
+
162
+ # returns +true+ if the branch exists locally
163
+ def is_local_branch?(branch)
164
+ branch_names = self.branches.local.map {|b| b.name}
165
+ branch_names.include?(branch)
166
+ end
167
+
168
+ # returns +true+ if the branch exists remotely
169
+ def is_remote_branch?(branch)
170
+ branch_names = self.branches.remote.map {|b| b.name}
171
+ branch_names.include?(branch)
172
+ end
173
+
174
+ # returns +true+ if the branch exists
175
+ def is_branch?(branch)
176
+ branch_names = self.branches.map {|b| b.name}
177
+ branch_names.include?(branch)
178
+ end
179
+
180
+ # this is a convenience method for accessing the class that wraps all the
181
+ # actual 'git' forked system calls. At some point I hope to replace the Git::Lib
182
+ # class with one that uses native methods or libgit C bindings
183
+ def lib
184
+ @lib ||= Git::Lib.new(self, @logger)
185
+ end
186
+
187
+ # will run a grep for 'string' on the HEAD of the git repository
188
+ #
189
+ # to be more surgical in your grep, you can call grep() off a specific
190
+ # git object. for example:
191
+ #
192
+ # @git.object("v2.3").grep('TODO')
193
+ #
194
+ # in any case, it returns a hash of arrays of the type:
195
+ # hsh[tree-ish] = [[line_no, match], [line_no, match2]]
196
+ # hsh[tree-ish] = [[line_no, match], [line_no, match2]]
197
+ #
198
+ # so you might use it like this:
199
+ #
200
+ # @git.grep("TODO").each do |sha, arr|
201
+ # puts "in blob #{sha}:"
202
+ # arr.each do |match|
203
+ # puts "\t line #{match[0]}: '#{match[1]}'"
204
+ # end
205
+ # end
206
+ def grep(string, path_limiter = nil, opts = {})
207
+ self.object('HEAD').grep(string, path_limiter, opts)
208
+ end
209
+
210
+ # updates the repository index using the working directory content
211
+ #
212
+ # @git.add('path/to/file')
213
+ # @git.add(['path/to/file1','path/to/file2'])
214
+ # @git.add(:all => true)
215
+ #
216
+ # options:
217
+ # :all => true
218
+ #
219
+ # @param [String,Array] paths files paths to be added (optional, default='.')
220
+ # @param [Hash] options
221
+ def add(*args)
222
+ if args[0].instance_of?(String) || args[0].instance_of?(Array)
223
+ self.lib.add(args[0],args[1]||{})
224
+ else
225
+ self.lib.add('.', args[0]||{})
226
+ end
227
+ end
228
+
229
+ # removes file(s) from the git repository
230
+ def remove(path = '.', opts = {})
231
+ self.lib.remove(path, opts)
232
+ end
233
+
234
+ # resets the working directory to the provided commitish
235
+ def reset(commitish = nil, opts = {})
236
+ self.lib.reset(commitish, opts)
237
+ end
238
+
239
+ # resets the working directory to the commitish with '--hard'
240
+ def reset_hard(commitish = nil, opts = {})
241
+ opts = {:hard => true}.merge(opts)
242
+ self.lib.reset(commitish, opts)
243
+ end
244
+
245
+ # cleans the working directory
246
+ #
247
+ # options:
248
+ # :force
249
+ # :d
250
+ #
251
+ def clean(opts = {})
252
+ self.lib.clean(opts)
253
+ end
254
+
255
+ # returns the most recent tag that is reachable from a commit
256
+ #
257
+ # options:
258
+ # :all
259
+ # :tags
260
+ # :contains
261
+ # :debug
262
+ # :exact_match
263
+ # :dirty
264
+ # :abbrev
265
+ # :candidates
266
+ # :long
267
+ # :always
268
+ # :match
269
+ #
270
+ def describe(committish=nil, opts={})
271
+ self.lib.describe(committish, opts)
272
+ end
273
+
274
+ # reverts the working directory to the provided commitish.
275
+ # Accepts a range, such as comittish..HEAD
276
+ #
277
+ # options:
278
+ # :no_edit
279
+ #
280
+ def revert(commitish = nil, opts = {})
281
+ self.lib.revert(commitish, opts)
282
+ end
283
+
284
+ # commits all pending changes in the index file to the git repository
285
+ #
286
+ # options:
287
+ # :all
288
+ # :allow_empty
289
+ # :amend
290
+ # :author
291
+ #
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', opts={})
317
+ self.lib.fetch(remote, opts)
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', opts = {})
326
+ # Small hack to keep backwards compatibility with the 'push(remote, branch, tags)' method signature.
327
+ opts = {:tags => opts} if [true, false].include?(opts)
328
+
329
+ self.lib.push(remote, branch, opts)
330
+ end
331
+
332
+ # merges one or more branches into the current working branch
333
+ #
334
+ # you can specify more than one branch to merge by passing an array of branches
335
+ def merge(branch, message = 'merge')
336
+ self.lib.merge(branch, message)
337
+ end
338
+
339
+ # iterates over the files which are unmerged
340
+ def each_conflict(&block) # :yields: file, your_version, their_version
341
+ self.lib.conflicts(&block)
342
+ end
343
+
344
+ # pulls the given branch from the given remote into the current branch
345
+ #
346
+ # @git.pull # pulls from origin/master
347
+ # @git.pull('upstream') # pulls from upstream/master
348
+ # @git.pull('upstream', 'develope') # pulls from upstream/develop
349
+ #
350
+ def pull(remote='origin', branch='master')
351
+ self.lib.pull(remote, branch)
352
+ end
353
+
354
+ # returns an array of Git:Remote objects
355
+ def remotes
356
+ self.lib.remotes.map { |r| Git::Remote.new(self, r) }
357
+ end
358
+
359
+ # adds a new remote to this repository
360
+ # url can be a git url or a Git::Base object if it's a local reference
361
+ #
362
+ # @git.add_remote('scotts_git', 'git://repo.or.cz/rubygit.git')
363
+ # @git.fetch('scotts_git')
364
+ # @git.merge('scotts_git/master')
365
+ #
366
+ # Options:
367
+ # :fetch => true
368
+ # :track => <branch_name>
369
+ def add_remote(name, url, opts = {})
370
+ url = url.repo.path if url.is_a?(Git::Base)
371
+ self.lib.remote_add(name, url, opts)
372
+ Git::Remote.new(self, name)
373
+ end
374
+
375
+ # removes a remote from this repository
376
+ #
377
+ # @git.remove_remote('scott_git')
378
+ def remove_remote(name)
379
+ self.lib.remote_remove(name)
380
+ end
381
+
382
+ # returns an array of all Git::Tag objects for this repository
383
+ def tags
384
+ self.lib.tags.map { |r| tag(r) }
385
+ end
386
+
387
+ # Creates a new git tag (Git::Tag)
388
+ # Usage:
389
+ # repo.add_tag('tag_name', object_reference)
390
+ # repo.add_tag('tag_name', object_reference, {:options => 'here'})
391
+ # repo.add_tag('tag_name', {:options => 'here'})
392
+ #
393
+ # Options:
394
+ # :a | :annotate -> true
395
+ # :d -> true
396
+ # :f -> true
397
+ # :m | :message -> String
398
+ # :s -> true
399
+ #
400
+ def add_tag(name, *opts)
401
+ self.lib.tag(name, *opts)
402
+ self.tag(name)
403
+ end
404
+
405
+ # deletes a tag
406
+ def delete_tag(name)
407
+ self.lib.tag(name, {:d => true})
408
+ end
409
+
410
+ # creates an archive file of the given tree-ish
411
+ def archive(treeish, file = nil, opts = {})
412
+ self.object(treeish).archive(file, opts)
413
+ end
414
+
415
+ # repacks the repository
416
+ def repack
417
+ self.lib.repack
418
+ end
419
+
420
+ def gc
421
+ self.lib.gc
422
+ end
423
+
424
+ def apply(file)
425
+ if File.exist?(file)
426
+ self.lib.apply(file)
427
+ end
428
+ end
429
+
430
+ def apply_mail(file)
431
+ self.lib.apply_mail(file) if File.exist?(file)
432
+ end
433
+
434
+ # Shows objects
435
+ #
436
+ # @param [String|NilClass] objectish the target object reference (nil == HEAD)
437
+ # @param [String|NilClass] path the path of the file to be shown
438
+ # @return [String] the object information
439
+ def show(objectish=nil, path=nil)
440
+ self.lib.show(objectish, path)
441
+ end
442
+
443
+ ## LOWER LEVEL INDEX OPERATIONS ##
444
+
445
+ def with_index(new_index) # :yields: new_index
446
+ old_index = @index
447
+ set_index(new_index, false)
448
+ return_value = yield @index
449
+ set_index(old_index)
450
+ return_value
451
+ end
452
+
453
+ def with_temp_index &blk
454
+ # Workaround for JRUBY, since they handle the TempFile path different.
455
+ # MUST be improved to be safer and OS independent.
456
+ if RUBY_PLATFORM == 'java'
457
+ temp_path = "/tmp/temp-index-#{(0...15).map{ ('a'..'z').to_a[rand(26)] }.join}"
458
+ else
459
+ tempfile = Tempfile.new('temp-index')
460
+ temp_path = tempfile.path
461
+ tempfile.close
462
+ tempfile.unlink
463
+ end
464
+
465
+ with_index(temp_path, &blk)
466
+ end
467
+
468
+ def checkout_index(opts = {})
469
+ self.lib.checkout_index(opts)
470
+ end
471
+
472
+ def read_tree(treeish, opts = {})
473
+ self.lib.read_tree(treeish, opts)
474
+ end
475
+
476
+ def write_tree
477
+ self.lib.write_tree
478
+ end
479
+
480
+ def write_and_commit_tree(opts = {})
481
+ tree = write_tree
482
+ commit_tree(tree, opts)
483
+ end
484
+
485
+ def update_ref(branch, commit)
486
+ branch(branch).update_ref(commit)
487
+ end
488
+
489
+
490
+ def ls_files(location=nil)
491
+ self.lib.ls_files(location)
492
+ end
493
+
494
+ def with_working(work_dir) # :yields: the Git::WorkingDirectory
495
+ return_value = false
496
+ old_working = @working_directory
497
+ set_working(work_dir)
498
+ Dir.chdir work_dir do
499
+ return_value = yield @working_directory
500
+ end
501
+ set_working(old_working)
502
+ return_value
503
+ end
504
+
505
+ def with_temp_working &blk
506
+ tempfile = Tempfile.new("temp-workdir")
507
+ temp_dir = tempfile.path
508
+ tempfile.close
509
+ tempfile.unlink
510
+ Dir.mkdir(temp_dir, 0700)
511
+ with_working(temp_dir, &blk)
512
+ end
513
+
514
+
515
+ # runs git rev-parse to convert the objectish to a full sha
516
+ #
517
+ # @git.revparse("HEAD^^")
518
+ # @git.revparse('v2.4^{tree}')
519
+ # @git.revparse('v2.4:/doc/index.html')
520
+ #
521
+ def revparse(objectish)
522
+ self.lib.revparse(objectish)
523
+ end
524
+
525
+ def ls_tree(objectish)
526
+ self.lib.ls_tree(objectish)
527
+ end
528
+
529
+ def cat_file(objectish)
530
+ self.lib.object_contents(objectish)
531
+ end
532
+
533
+ # returns the name of the branch the working directory is currently on
534
+ def current_branch
535
+ self.lib.branch_current
536
+ end
537
+
538
+ end
539
+
540
+ end