ruby-git-yz 1.3.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.
@@ -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