git 1.2.8 → 1.2.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of git might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +75 -0
- data/README.md +27 -1
- data/VERSION +1 -0
- data/lib/git.rb +18 -0
- data/lib/git/author.rb +1 -1
- data/lib/git/base.rb +100 -120
- data/lib/git/base/factory.rb +75 -0
- data/lib/git/config.rb +19 -0
- data/lib/git/diff.rb +12 -7
- data/lib/git/lib.rb +189 -38
- data/lib/git/object.rb +37 -7
- data/lib/git/version.rb +1 -1
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f8c43aab9887b1c224856449e057fa497c9d6ed
|
4
|
+
data.tar.gz: a607710a83056295b99a6eb5f0715109ccb4ea77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcb2bc710c57c674a7f1d49a7c605ae86a76005a7ee55721c745b5fb215ecbc944892d7f3401420cf6af717c3744e730a6af32453d20f0a381f19dd23f67c068
|
7
|
+
data.tar.gz: e54136f3c5c988e9b4582fc921739de685bc5aa3ea10d2917d60bfe3c278acb8224b59c877426d718410d0a2ef92983d7066f863505f29bc4dfdcc2c15acf253
|
data/CHANGELOG
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
== 1.2.9
|
2
|
+
|
3
|
+
* Adding Git.configure (to configure the git env)
|
4
|
+
* Adding Git.ls_remote [Git.ls_remote(repo_path_or_url='.')]
|
5
|
+
* Adding Git.describe [repo.describe(objectish, opts)]
|
6
|
+
* Adding Git.show [repo.show(objectish=nil, path=nil)]
|
7
|
+
* Fixing Git::Diff to support default references (implicit references)
|
8
|
+
* Fixing Git::Diff to support diff over git .patch files
|
9
|
+
* Fixing Git.checkout when using :new_branch opt
|
10
|
+
* Fixing Git::Object::Commit to preserve its sha after fetching metadata
|
11
|
+
* Fixing Git.is_remote_branch? to actually check against remote branches
|
12
|
+
* Improvements over how ENV variables are modified
|
13
|
+
* Improving thrade safety (using --git-dir and --work-tree git opts)
|
14
|
+
* Improving Git::Object::Tag. Adding annotated?, tagger and message
|
15
|
+
* Supporting a submodule path as a valid repo
|
16
|
+
* Git.checkout - supporting -f and -b
|
17
|
+
* Git.clone - supporting --branch
|
18
|
+
* Git.fetch - supporting --prune
|
19
|
+
* Git.tag - supporting
|
20
|
+
|
21
|
+
== 1.2.8
|
22
|
+
|
23
|
+
* Keeping the old escape format for windows users
|
24
|
+
* revparse: Supporting ref names containing SHA like substrings (40-hex strings)
|
25
|
+
* Fix warnings on Ruby 2.1.2
|
26
|
+
|
27
|
+
== 1.2.7
|
28
|
+
|
29
|
+
* Fixing mesages encoding
|
30
|
+
* Fixing -f flag in git push
|
31
|
+
* Fixing log parser for multiline messages
|
32
|
+
* Supporting object references on Git.add_tag
|
33
|
+
* Including dotfiles on Git.status
|
34
|
+
* Git.fetch - supporting --tags
|
35
|
+
* Git.clean - supporting -x
|
36
|
+
* Git.add_tag options - supporting -a, -m and -s
|
37
|
+
* Added Git.delete_tag
|
38
|
+
|
39
|
+
== 1.2.6
|
40
|
+
|
41
|
+
* Ruby 1.9.X/2.0 fully supported
|
42
|
+
* JRuby 1.8/1.9 support
|
43
|
+
* Rubinius support
|
44
|
+
* Git.clone - supporting --recursive and --config
|
45
|
+
* Git.log - supporting last and [] over the results
|
46
|
+
* Git.add_remote - supporting -f and -t
|
47
|
+
* Git.add - supporting --fore
|
48
|
+
* Git.init - supporting --bare
|
49
|
+
* Git.commit - supporting --all and --amend
|
50
|
+
* Added Git.remote_remote, Git.revert and Git.clean
|
51
|
+
* Added Bundler to the formula
|
52
|
+
* Travis configuration
|
53
|
+
* Licence included with the gem
|
54
|
+
|
55
|
+
== 1.0.4
|
56
|
+
|
57
|
+
* added camping/gitweb.rb frontend
|
58
|
+
* added a number of speed-ups
|
59
|
+
|
60
|
+
== 1.0.3
|
61
|
+
|
62
|
+
* Sped up most of the operations
|
63
|
+
* Added some predicate functions (commit?, tree?, etc)
|
64
|
+
* Added a number of lower level operations (read-tree, write-tree, checkout-index, etc)
|
65
|
+
* Fixed a bug with using bare repositories
|
66
|
+
* Updated a good amount of the documentation
|
67
|
+
|
68
|
+
== 1.0.2
|
69
|
+
|
70
|
+
* Added methods to the git objects that might be helpful
|
71
|
+
|
72
|
+
== 1.0.1
|
73
|
+
|
74
|
+
* Initial version
|
75
|
+
|
data/README.md
CHANGED
@@ -57,6 +57,20 @@ Require the 'git' gem.
|
|
57
57
|
require 'git'
|
58
58
|
```
|
59
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 Key
|
68
|
+
config.git_ssh = '/path/to/ssh/script'
|
69
|
+
end
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
|
60
74
|
Here are the operations that need read permission only.
|
61
75
|
|
62
76
|
```ruby
|
@@ -113,7 +127,10 @@ Here are the operations that need read permission only.
|
|
113
127
|
g.grep('hello') # implies HEAD
|
114
128
|
g.blob('v2.5:Makefile').grep('hello')
|
115
129
|
g.tag('v2.5').grep('hello', 'docs/')
|
116
|
-
|
130
|
+
g.describe()
|
131
|
+
g.describe('0djf2aa')
|
132
|
+
g.describe('HEAD', {:all => true, :tags => true})
|
133
|
+
|
117
134
|
g.diff(commit1, commit2).size
|
118
135
|
g.diff(commit1, commit2).stats
|
119
136
|
g.gtree('v2.5').diff('v2.6').insertions
|
@@ -132,6 +149,15 @@ Here are the operations that need read permission only.
|
|
132
149
|
g.config # returns whole config hash
|
133
150
|
|
134
151
|
g.tags # returns array of Git::Tag objects
|
152
|
+
|
153
|
+
g.show()
|
154
|
+
g.show('HEAD')
|
155
|
+
g.show('v2.8', 'README.md')
|
156
|
+
|
157
|
+
Git.ls_remote('https://github.com/schacon/ruby-git.git') # returns a hash containing the available references of the repo.
|
158
|
+
Git.ls_remote('/path/to/local/repo')
|
159
|
+
Git.ls_remote() # same as Git.ls_remote('.')
|
160
|
+
|
135
161
|
```
|
136
162
|
|
137
163
|
And here are the operations that will need to write to your git repository.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.2.9
|
data/lib/git.rb
CHANGED
@@ -7,6 +7,7 @@ require 'git/author'
|
|
7
7
|
require 'git/base'
|
8
8
|
require 'git/branch'
|
9
9
|
require 'git/branches'
|
10
|
+
require 'git/config'
|
10
11
|
require 'git/diff'
|
11
12
|
require 'git/index'
|
12
13
|
require 'git/lib'
|
@@ -60,6 +61,14 @@ module Git
|
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
64
|
+
def self.configure
|
65
|
+
yield Base.config
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.config
|
69
|
+
return Base.config
|
70
|
+
end
|
71
|
+
|
63
72
|
def global_config(name = nil, value = nil)
|
64
73
|
self.class.global_config(name, value)
|
65
74
|
end
|
@@ -130,6 +139,15 @@ module Git
|
|
130
139
|
def self.init(working_dir = '.', options = {})
|
131
140
|
Base.init(working_dir, options)
|
132
141
|
end
|
142
|
+
|
143
|
+
# returns a Hash containing information about the references
|
144
|
+
# of the target repository
|
145
|
+
#
|
146
|
+
# @param [String|NilClass] location the target repository location or nil for '.'
|
147
|
+
# @return [{String=>Hash}] the available references of the target repo.
|
148
|
+
def self.ls_remote(location=nil)
|
149
|
+
Git::Lib.new.ls_remote(location)
|
150
|
+
end
|
133
151
|
|
134
152
|
# open an existing git working directory
|
135
153
|
#
|
data/lib/git/author.rb
CHANGED
data/lib/git/base.rb
CHANGED
@@ -1,16 +1,39 @@
|
|
1
|
+
require 'git/base/factory'
|
2
|
+
|
1
3
|
module Git
|
2
4
|
|
3
5
|
class Base
|
4
6
|
|
7
|
+
include Git::Base::Factory
|
8
|
+
|
5
9
|
# opens a bare Git Repository - no working directory options
|
6
10
|
def self.bare(git_dir, opts = {})
|
7
11
|
self.new({:repository => git_dir}.merge(opts))
|
8
12
|
end
|
9
13
|
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
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
|
14
37
|
end
|
15
38
|
|
16
39
|
# initializes a git repository
|
@@ -21,8 +44,8 @@ module Git
|
|
21
44
|
# :repository
|
22
45
|
#
|
23
46
|
def self.init(working_dir, opts = {})
|
24
|
-
opts[:working_directory]
|
25
|
-
opts[:repository]
|
47
|
+
opts[:working_directory] ||= working_dir
|
48
|
+
opts[:repository] ||= File.join(opts[:working_directory], '.git')
|
26
49
|
|
27
50
|
FileUtils.mkdir_p(opts[:working_directory]) if opts[:working_directory] && !File.directory?(opts[:working_directory])
|
28
51
|
|
@@ -31,30 +54,27 @@ module Git
|
|
31
54
|
}
|
32
55
|
|
33
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
|
34
66
|
|
35
67
|
Git::Lib.new(opts).init(init_opts)
|
36
68
|
|
37
69
|
self.new(opts)
|
38
70
|
end
|
39
|
-
|
40
|
-
#
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
# options:
|
46
|
-
# :repository
|
47
|
-
#
|
48
|
-
# :bare
|
49
|
-
# or
|
50
|
-
# :working_directory
|
51
|
-
# :index_file
|
52
|
-
#
|
53
|
-
def self.clone(repository, name, opts = {})
|
54
|
-
# run git-clone
|
55
|
-
self.new(Git::Lib.new.clone(repository, name, opts))
|
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))
|
56
76
|
end
|
57
|
-
|
77
|
+
|
58
78
|
def initialize(options = {})
|
59
79
|
if working_dir = options[:working_directory]
|
60
80
|
options[:repository] ||= File.join(working_dir, '.git')
|
@@ -71,36 +91,6 @@ module Git
|
|
71
91
|
@repository = options[:repository] ? Git::Repository.new(options[:repository]) : nil
|
72
92
|
@index = options[:index] ? Git::Index.new(options[:index], false) : nil
|
73
93
|
end
|
74
|
-
|
75
|
-
|
76
|
-
# returns a reference to the working directory
|
77
|
-
# @git.dir.path
|
78
|
-
# @git.dir.writeable?
|
79
|
-
def dir
|
80
|
-
@working_directory
|
81
|
-
end
|
82
|
-
|
83
|
-
# returns reference to the git repository directory
|
84
|
-
# @git.dir.path
|
85
|
-
def repo
|
86
|
-
@repository
|
87
|
-
end
|
88
|
-
|
89
|
-
# returns reference to the git index file
|
90
|
-
def index
|
91
|
-
@index
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
def set_working(work_dir, check = true)
|
96
|
-
@lib = nil
|
97
|
-
@working_directory = Git::WorkingDirectory.new(work_dir.to_s, check)
|
98
|
-
end
|
99
|
-
|
100
|
-
def set_index(index_file, check = true)
|
101
|
-
@lib = nil
|
102
|
-
@index = Git::Index.new(index_file.to_s, check)
|
103
|
-
end
|
104
94
|
|
105
95
|
# changes current working directory for a block
|
106
96
|
# to the git working directory
|
@@ -117,13 +107,6 @@ module Git
|
|
117
107
|
end
|
118
108
|
end
|
119
109
|
|
120
|
-
# returns the repository size in bytes
|
121
|
-
def repo_size
|
122
|
-
Dir.chdir(repo.path) do
|
123
|
-
return `du -s`.chomp.split.first.to_i
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
110
|
#g.config('user.name', 'Scott Chacon') # sets value
|
128
111
|
#g.config('user.email', 'email@email.com') # sets value
|
129
112
|
#g.config('user.name') # returns 'Scott Chacon'
|
@@ -140,51 +123,40 @@ module Git
|
|
140
123
|
lib.config_list
|
141
124
|
end
|
142
125
|
end
|
143
|
-
|
144
|
-
#
|
145
|
-
|
146
|
-
#
|
147
|
-
|
148
|
-
|
149
|
-
# still return a Git::Object::Commit object.
|
150
|
-
#
|
151
|
-
# @git.object calls a factory method that will run a rev-parse
|
152
|
-
# on the objectish and determine the type of the object and return
|
153
|
-
# an appropriate object for that type
|
154
|
-
def object(objectish)
|
155
|
-
Git::Object.new(self, objectish)
|
126
|
+
|
127
|
+
# returns a reference to the working directory
|
128
|
+
# @git.dir.path
|
129
|
+
# @git.dir.writeable?
|
130
|
+
def dir
|
131
|
+
@working_directory
|
156
132
|
end
|
157
133
|
|
158
|
-
|
159
|
-
|
134
|
+
# returns reference to the git index file
|
135
|
+
def index
|
136
|
+
@index
|
160
137
|
end
|
161
|
-
|
162
|
-
|
163
|
-
|
138
|
+
|
139
|
+
# returns reference to the git repository directory
|
140
|
+
# @git.dir.path
|
141
|
+
def repo
|
142
|
+
@repository
|
164
143
|
end
|
165
144
|
|
166
|
-
|
167
|
-
|
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
|
168
150
|
end
|
169
151
|
|
170
|
-
|
171
|
-
|
172
|
-
Git::
|
173
|
-
end
|
174
|
-
|
175
|
-
# returns a Git::Status object
|
176
|
-
def status
|
177
|
-
Git::Status.new(self)
|
178
|
-
end
|
179
|
-
|
180
|
-
# returns a Git::Branches object of all the Git::Branch objects for this repo
|
181
|
-
def branches
|
182
|
-
Git::Branches.new(self)
|
152
|
+
def set_index(index_file, check = true)
|
153
|
+
@lib = nil
|
154
|
+
@index = Git::Index.new(index_file.to_s, check)
|
183
155
|
end
|
184
156
|
|
185
|
-
|
186
|
-
|
187
|
-
Git::
|
157
|
+
def set_working(work_dir, check = true)
|
158
|
+
@lib = nil
|
159
|
+
@working_directory = Git::WorkingDirectory.new(work_dir.to_s, check)
|
188
160
|
end
|
189
161
|
|
190
162
|
# returns +true+ if the branch exists locally
|
@@ -195,7 +167,7 @@ module Git
|
|
195
167
|
|
196
168
|
# returns +true+ if the branch exists remotely
|
197
169
|
def is_remote_branch?(branch)
|
198
|
-
branch_names = self.branches.
|
170
|
+
branch_names = self.branches.remote.map {|b| b.name}
|
199
171
|
branch_names.include?(branch)
|
200
172
|
end
|
201
173
|
|
@@ -205,11 +177,6 @@ module Git
|
|
205
177
|
branch_names.include?(branch)
|
206
178
|
end
|
207
179
|
|
208
|
-
# returns a Git::Remote object
|
209
|
-
def remote(remote_name = 'origin')
|
210
|
-
Git::Remote.new(self, remote_name)
|
211
|
-
end
|
212
|
-
|
213
180
|
# this is a convenience method for accessing the class that wraps all the
|
214
181
|
# actual 'git' forked system calls. At some point I hope to replace the Git::Lib
|
215
182
|
# class with one that uses native methods or libgit C bindings
|
@@ -240,12 +207,7 @@ module Git
|
|
240
207
|
self.object('HEAD').grep(string, path_limiter, opts)
|
241
208
|
end
|
242
209
|
|
243
|
-
#
|
244
|
-
def diff(objectish = 'HEAD', obj2 = nil)
|
245
|
-
Git::Diff.new(self, objectish, obj2)
|
246
|
-
end
|
247
|
-
|
248
|
-
# updates the repository index using the workig dorectory content
|
210
|
+
# updates the repository index using the working directory content
|
249
211
|
#
|
250
212
|
# @git.add('path/to/file')
|
251
213
|
# @git.add(['path/to/file1','path/to/file2'])
|
@@ -290,6 +252,25 @@ module Git
|
|
290
252
|
self.lib.clean(opts)
|
291
253
|
end
|
292
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
|
+
|
293
274
|
# reverts the working directory to the provided commitish.
|
294
275
|
# Accepts a range, such as comittish..HEAD
|
295
276
|
#
|
@@ -402,11 +383,6 @@ module Git
|
|
402
383
|
def tags
|
403
384
|
self.lib.tags.map { |r| tag(r) }
|
404
385
|
end
|
405
|
-
|
406
|
-
# returns a Git::Tag object
|
407
|
-
def tag(tag_name)
|
408
|
-
Git::Object.new(self, tag_name, 'tag', true)
|
409
|
-
end
|
410
386
|
|
411
387
|
# Creates a new git tag (Git::Tag)
|
412
388
|
# Usage:
|
@@ -423,7 +399,7 @@ module Git
|
|
423
399
|
#
|
424
400
|
def add_tag(name, *opts)
|
425
401
|
self.lib.tag(name, *opts)
|
426
|
-
tag(name)
|
402
|
+
self.tag(name)
|
427
403
|
end
|
428
404
|
|
429
405
|
# deletes a tag
|
@@ -454,6 +430,15 @@ module Git
|
|
454
430
|
def apply_mail(file)
|
455
431
|
self.lib.apply_mail(file) if File.exist?(file)
|
456
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
|
457
442
|
|
458
443
|
## LOWER LEVEL INDEX OPERATIONS ##
|
459
444
|
|
@@ -492,10 +477,6 @@ module Git
|
|
492
477
|
self.lib.write_tree
|
493
478
|
end
|
494
479
|
|
495
|
-
def commit_tree(tree = nil, opts = {})
|
496
|
-
Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
|
497
|
-
end
|
498
|
-
|
499
480
|
def write_and_commit_tree(opts = {})
|
500
481
|
tree = write_tree
|
501
482
|
commit_tree(tree, opts)
|
@@ -553,7 +534,6 @@ module Git
|
|
553
534
|
def current_branch
|
554
535
|
self.lib.branch_current
|
555
536
|
end
|
556
|
-
|
557
537
|
|
558
538
|
end
|
559
539
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Git
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
module Factory
|
6
|
+
|
7
|
+
# returns a Git::Branch object for branch_name
|
8
|
+
def branch(branch_name = 'master')
|
9
|
+
Git::Branch.new(self, branch_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
# returns a Git::Branches object of all the Git::Branch
|
13
|
+
# objects for this repo
|
14
|
+
def branches
|
15
|
+
Git::Branches.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def commit_tree(tree = nil, opts = {})
|
19
|
+
Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
|
20
|
+
end
|
21
|
+
|
22
|
+
# returns a Git::Diff object
|
23
|
+
def diff(objectish = 'HEAD', obj2 = nil)
|
24
|
+
Git::Diff.new(self, objectish, obj2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def gblob(objectish)
|
28
|
+
Git::Object.new(self, objectish, 'blob')
|
29
|
+
end
|
30
|
+
|
31
|
+
def gcommit(objectish)
|
32
|
+
Git::Object.new(self, objectish, 'commit')
|
33
|
+
end
|
34
|
+
|
35
|
+
def gtree(objectish)
|
36
|
+
Git::Object.new(self, objectish, 'tree')
|
37
|
+
end
|
38
|
+
|
39
|
+
# returns a Git::Log object with count commits
|
40
|
+
def log(count = 30)
|
41
|
+
Git::Log.new(self, count)
|
42
|
+
end
|
43
|
+
|
44
|
+
# returns a Git::Object of the appropriate type
|
45
|
+
# you can also call @git.gtree('tree'), but that's
|
46
|
+
# just for readability. If you call @git.gtree('HEAD') it will
|
47
|
+
# still return a Git::Object::Commit object.
|
48
|
+
#
|
49
|
+
# @git.object calls a factory method that will run a rev-parse
|
50
|
+
# on the objectish and determine the type of the object and return
|
51
|
+
# an appropriate object for that type
|
52
|
+
def object(objectish)
|
53
|
+
Git::Object.new(self, objectish)
|
54
|
+
end
|
55
|
+
|
56
|
+
# returns a Git::Remote object
|
57
|
+
def remote(remote_name = 'origin')
|
58
|
+
Git::Remote.new(self, remote_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
# returns a Git::Status object
|
62
|
+
def status
|
63
|
+
Git::Status.new(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
# returns a Git::Tag object
|
67
|
+
def tag(tag_name)
|
68
|
+
Git::Object.new(self, tag_name, 'tag', true)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/lib/git/config.rb
ADDED
data/lib/git/diff.rb
CHANGED
@@ -6,8 +6,8 @@ module Git
|
|
6
6
|
|
7
7
|
def initialize(base, from = nil, to = nil)
|
8
8
|
@base = base
|
9
|
-
@from = from.to_s
|
10
|
-
@to = to.to_s
|
9
|
+
@from = from && from.to_s
|
10
|
+
@to = to && to.to_s
|
11
11
|
|
12
12
|
@path = nil
|
13
13
|
@full_diff = nil
|
@@ -116,20 +116,25 @@ module Git
|
|
116
116
|
|
117
117
|
# break up @diff_full
|
118
118
|
def process_full_diff
|
119
|
+
defaults = {
|
120
|
+
:mode => '',
|
121
|
+
:src => '',
|
122
|
+
:dst => '',
|
123
|
+
:type => 'modified'
|
124
|
+
}
|
119
125
|
final = {}
|
120
126
|
current_file = nil
|
121
127
|
@full_diff.split("\n").each do |line|
|
122
|
-
if m =
|
128
|
+
if m = /^diff --git a\/(.*?) b\/(.*?)/.match(line)
|
123
129
|
current_file = m[1]
|
124
|
-
final[current_file] = {:patch => line, :path => current_file
|
125
|
-
:mode => '', :src => '', :dst => '', :type => 'modified'}
|
130
|
+
final[current_file] = defaults.merge({:patch => line, :path => current_file})
|
126
131
|
else
|
127
|
-
if m =
|
132
|
+
if m = /^index (.......)\.\.(.......)( ......)*/.match(line)
|
128
133
|
final[current_file][:src] = m[1]
|
129
134
|
final[current_file][:dst] = m[2]
|
130
135
|
final[current_file][:mode] = m[3].strip if m[3]
|
131
136
|
end
|
132
|
-
if m =
|
137
|
+
if m = /^([[:alpha:]]*?) file mode (......)/.match(line)
|
133
138
|
final[current_file][:type] = m[1]
|
134
139
|
final[current_file][:mode] = m[2]
|
135
140
|
end
|
data/lib/git/lib.rb
CHANGED
@@ -6,7 +6,9 @@ module Git
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class Lib
|
9
|
-
|
9
|
+
|
10
|
+
@@semaphore = Mutex.new
|
11
|
+
|
10
12
|
def initialize(base = nil, logger = nil)
|
11
13
|
@git_dir = nil
|
12
14
|
@git_index_file = nil
|
@@ -44,10 +46,13 @@ module Git
|
|
44
46
|
# {:working_directory} otherwise
|
45
47
|
#
|
46
48
|
# accepts options:
|
47
|
-
# :remote:: name of remote (rather than 'origin')
|
48
49
|
# :bare:: no working directory
|
49
|
-
# :
|
50
|
+
# :branch:: name of branch to track (rather than 'master')
|
50
51
|
# :depth:: the number of commits back to pull
|
52
|
+
# :origin:: name of remote (same as remote)
|
53
|
+
# :path:: directory where the repo will be cloned
|
54
|
+
# :remote:: name of remote (rather than 'origin')
|
55
|
+
# :recursive:: after the clone is created, initialize all submodules within, using their default settings.
|
51
56
|
#
|
52
57
|
# TODO - make this work with SSH password or auth_key
|
53
58
|
#
|
@@ -56,13 +61,15 @@ module Git
|
|
56
61
|
clone_dir = opts[:path] ? File.join(@path, name) : name
|
57
62
|
|
58
63
|
arr_opts = []
|
59
|
-
arr_opts <<
|
60
|
-
arr_opts <<
|
61
|
-
arr_opts <<
|
62
|
-
arr_opts <<
|
63
|
-
arr_opts <<
|
64
|
+
arr_opts << '--bare' if opts[:bare]
|
65
|
+
arr_opts << '--branch' << opts[:branch] if opts[:branch]
|
66
|
+
arr_opts << '--depth' << opts[:depth].to_i if opts[:depth] && opts[:depth].to_i > 0
|
67
|
+
arr_opts << '--config' << opts[:config] if opts[:config]
|
68
|
+
arr_opts << '--origin' << opts[:remote] || opts[:origin] if opts[:remote] || opts[:origin]
|
69
|
+
arr_opts << '--recursive' if opts[:recursive]
|
64
70
|
|
65
71
|
arr_opts << '--'
|
72
|
+
|
66
73
|
arr_opts << repository
|
67
74
|
arr_opts << clone_dir
|
68
75
|
|
@@ -74,6 +81,49 @@ module Git
|
|
74
81
|
|
75
82
|
## READ COMMANDS ##
|
76
83
|
|
84
|
+
#
|
85
|
+
# Returns most recent tag that is reachable from a commit
|
86
|
+
#
|
87
|
+
# accepts options:
|
88
|
+
# :all
|
89
|
+
# :tags
|
90
|
+
# :contains
|
91
|
+
# :debug
|
92
|
+
# :exact_match
|
93
|
+
# :dirty
|
94
|
+
# :abbrev
|
95
|
+
# :candidates
|
96
|
+
# :long
|
97
|
+
# :always
|
98
|
+
# :math
|
99
|
+
#
|
100
|
+
# @param [String|NilClass] committish target commit sha or object name
|
101
|
+
# @param [{Symbol=>Object}] opts the given options
|
102
|
+
# @return [String] the tag name
|
103
|
+
#
|
104
|
+
def describe(committish=nil, opts={})
|
105
|
+
arr_opts = []
|
106
|
+
|
107
|
+
arr_opts << '--all' if opts[:all]
|
108
|
+
arr_opts << '--tags' if opts[:tags]
|
109
|
+
arr_opts << '--contains' if opts[:contains]
|
110
|
+
arr_opts << '--debug' if opts[:debug]
|
111
|
+
arr_opts << '--long' if opts[:long]
|
112
|
+
arr_opts << '--always' if opts[:always]
|
113
|
+
arr_opts << '--exact-match' if opts[:exact_match] || opts[:"exact-match"]
|
114
|
+
|
115
|
+
arr_opts << '--dirty' if opts['dirty'] == true
|
116
|
+
arr_opts << "--dirty=#{opts['dirty']}" if opts['dirty'].is_a?(String)
|
117
|
+
|
118
|
+
arr_opts << "--abbrev=#{opts['abbrev']}" if opts[:abbrev]
|
119
|
+
arr_opts << "--candidates=#{opts['candidates']}" if opts[:candidates]
|
120
|
+
arr_opts << "--match=#{opts['match']}" if opts[:match]
|
121
|
+
|
122
|
+
arr_opts << committish if committish
|
123
|
+
|
124
|
+
return command('describe', arr_opts)
|
125
|
+
end
|
126
|
+
|
77
127
|
def log_commits(opts={})
|
78
128
|
arr_opts = log_common_options(opts)
|
79
129
|
|
@@ -150,6 +200,31 @@ module Git
|
|
150
200
|
|
151
201
|
return hsh
|
152
202
|
end
|
203
|
+
|
204
|
+
def tag_data(name)
|
205
|
+
sha = sha.to_s
|
206
|
+
tdata = command_lines('cat-file', ['tag', name])
|
207
|
+
process_tag_data(tdata, name, 0)
|
208
|
+
end
|
209
|
+
|
210
|
+
def process_tag_data(data, name, indent=4)
|
211
|
+
hsh = {
|
212
|
+
'name' => name,
|
213
|
+
'message' => ''
|
214
|
+
}
|
215
|
+
|
216
|
+
loop do
|
217
|
+
key, *value = data.shift.split
|
218
|
+
|
219
|
+
break if key.nil?
|
220
|
+
|
221
|
+
hsh[key] = value.join(' ')
|
222
|
+
end
|
223
|
+
|
224
|
+
hsh['message'] = data.collect {|line| line[indent..-1]}.join("\n") + "\n"
|
225
|
+
|
226
|
+
return hsh
|
227
|
+
end
|
153
228
|
|
154
229
|
def process_commit_log_data(data)
|
155
230
|
in_message = false
|
@@ -317,6 +392,19 @@ module Git
|
|
317
392
|
hsh
|
318
393
|
end
|
319
394
|
|
395
|
+
def ls_remote(location=nil)
|
396
|
+
location ||= '.'
|
397
|
+
Hash.new{ |h,k| h[k] = {} }.tap do |hsh|
|
398
|
+
command_lines('ls-remote', [location], false).each do |line|
|
399
|
+
(sha, info) = line.split("\t")
|
400
|
+
(ref, type, name) = info.split('/', 3)
|
401
|
+
type ||= 'head'
|
402
|
+
type = 'branches' if type == 'heads'
|
403
|
+
value = {:ref => ref, :sha => sha}
|
404
|
+
hsh[type].update( name.nil? ? value : { name => value })
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
320
408
|
|
321
409
|
def ignored_files
|
322
410
|
command_lines('ls-files', ['--others', '-i', '--exclude-standard'])
|
@@ -377,6 +465,19 @@ module Git
|
|
377
465
|
def parse_config(file)
|
378
466
|
parse_config_list command_lines('config', ['--list', '--file', file], false)
|
379
467
|
end
|
468
|
+
|
469
|
+
# Shows objects
|
470
|
+
#
|
471
|
+
# @param [String|NilClass] objectish the target object reference (nil == HEAD)
|
472
|
+
# @param [String|NilClass] path the path of the file to be shown
|
473
|
+
# @return [String] the object information
|
474
|
+
def show(objectish=nil, path=nil)
|
475
|
+
arr_opts = []
|
476
|
+
|
477
|
+
arr_opts << (path ? "#{objectish}:#{path}" : objectish)
|
478
|
+
|
479
|
+
command('show', arr_opts.compact)
|
480
|
+
end
|
380
481
|
|
381
482
|
## WRITE COMMANDS ##
|
382
483
|
|
@@ -388,7 +489,7 @@ module Git
|
|
388
489
|
command('config', ['--global', name, value], false)
|
389
490
|
end
|
390
491
|
|
391
|
-
# updates the repository index using the
|
492
|
+
# updates the repository index using the working directory content
|
392
493
|
#
|
393
494
|
# lib.add('path/to/file')
|
394
495
|
# lib.add(['path/to/file1','path/to/file2'])
|
@@ -521,8 +622,8 @@ module Git
|
|
521
622
|
|
522
623
|
def checkout(branch, opts = {})
|
523
624
|
arr_opts = []
|
524
|
-
arr_opts << '-
|
525
|
-
arr_opts << '
|
625
|
+
arr_opts << '-b' if opts[:new_branch] || opts[:b]
|
626
|
+
arr_opts << '--force' if opts[:force] || opts[:f]
|
526
627
|
arr_opts << branch
|
527
628
|
|
528
629
|
command('checkout', arr_opts)
|
@@ -610,6 +711,7 @@ module Git
|
|
610
711
|
def fetch(remote, opts)
|
611
712
|
arr_opts = [remote]
|
612
713
|
arr_opts << '--tags' if opts[:t] || opts[:tags]
|
714
|
+
arr_opts << '--prune' if opts[:p] || opts[:prune]
|
613
715
|
|
614
716
|
command('fetch', arr_opts)
|
615
717
|
end
|
@@ -699,8 +801,14 @@ module Git
|
|
699
801
|
opts[:add_gzip] = true
|
700
802
|
end
|
701
803
|
|
702
|
-
file
|
703
|
-
|
804
|
+
if !file
|
805
|
+
tempfile = Tempfile.new('archive')
|
806
|
+
file = tempfile.path
|
807
|
+
# delete it now, before we write to it, so that Ruby doesn't delete it
|
808
|
+
# when it finalizes the Tempfile.
|
809
|
+
tempfile.close!
|
810
|
+
end
|
811
|
+
|
704
812
|
arr_opts = []
|
705
813
|
arr_opts << "--format=#{opts[:format]}" if opts[:format]
|
706
814
|
arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
|
@@ -728,42 +836,88 @@ module Git
|
|
728
836
|
|
729
837
|
|
730
838
|
private
|
839
|
+
|
840
|
+
# Systen ENV variables involved in the git commands.
|
841
|
+
#
|
842
|
+
# @return [<String>] the names of the EVN variables involved in the git commands
|
843
|
+
ENV_VARIABLE_NAMES = ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_SSH']
|
731
844
|
|
732
845
|
def command_lines(cmd, opts = [], chdir = true, redirect = '')
|
733
846
|
command(cmd, opts, chdir).split("\n")
|
734
847
|
end
|
735
848
|
|
736
|
-
|
849
|
+
# Takes the current git's system ENV variables and store them.
|
850
|
+
def store_git_system_env_variables
|
851
|
+
@git_system_env_variables = {}
|
852
|
+
ENV_VARIABLE_NAMES.each do |env_variable_name|
|
853
|
+
@git_system_env_variables[env_variable_name] = ENV[env_variable_name]
|
854
|
+
end
|
855
|
+
end
|
856
|
+
|
857
|
+
# Takes the previously stored git's ENV variables and set them again on ENV.
|
858
|
+
def restore_git_system_env_variables
|
859
|
+
ENV_VARIABLE_NAMES.each do |env_variable_name|
|
860
|
+
ENV[env_variable_name] = @git_system_env_variables[env_variable_name]
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
# Sets git's ENV variables to the custom values for the current instance.
|
865
|
+
def set_custom_git_env_variables
|
737
866
|
ENV['GIT_DIR'] = @git_dir
|
738
867
|
ENV['GIT_WORK_TREE'] = @git_work_dir
|
739
868
|
ENV['GIT_INDEX_FILE'] = @git_index_file
|
869
|
+
ENV['GIT_SSH'] = Git::Base.config.git_ssh
|
870
|
+
end
|
740
871
|
|
741
|
-
|
742
|
-
|
872
|
+
# Runs a block inside an environment with customized ENV variables.
|
873
|
+
# It restores the ENV after execution.
|
874
|
+
#
|
875
|
+
# @param [Proc] block block to be executed within the customized environment
|
876
|
+
def with_custom_env_variables(&block)
|
877
|
+
@@semaphore.synchronize do
|
878
|
+
store_git_system_env_variables()
|
879
|
+
set_custom_git_env_variables()
|
880
|
+
return block.call()
|
881
|
+
end
|
882
|
+
ensure
|
883
|
+
restore_git_system_env_variables()
|
884
|
+
end
|
885
|
+
|
886
|
+
def command(cmd, opts = [], chdir = true, redirect = '', &block)
|
887
|
+
global_opts = []
|
888
|
+
global_opts << "--git-dir=#{@git_dir}" if !@git_dir.nil?
|
889
|
+
global_opts << "--work-tree=#{@git_work_dir}" if !@git_work_dir.nil?
|
890
|
+
|
743
891
|
opts = [opts].flatten.map {|s| escape(s) }.join(' ')
|
892
|
+
|
893
|
+
global_opts = global_opts.flatten.map {|s| escape(s) }.join(' ')
|
894
|
+
|
895
|
+
git_cmd = "#{Git::Base.config.binary_path} #{global_opts} #{cmd} #{opts} #{redirect} 2>&1"
|
896
|
+
|
897
|
+
output = nil
|
898
|
+
|
899
|
+
command_thread = nil;
|
900
|
+
|
901
|
+
exitstatus = nil
|
744
902
|
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
out = run_command(git_cmd, &block)
|
903
|
+
with_custom_env_variables do
|
904
|
+
command_thread = Thread.new do
|
905
|
+
output = run_command(git_cmd, &block)
|
906
|
+
exitstatus = $?.exitstatus
|
907
|
+
end
|
908
|
+
command_thread.join
|
753
909
|
end
|
754
|
-
|
910
|
+
|
755
911
|
if @logger
|
756
912
|
@logger.info(git_cmd)
|
757
|
-
@logger.debug(
|
913
|
+
@logger.debug(output)
|
758
914
|
end
|
759
915
|
|
760
|
-
if
|
761
|
-
|
762
|
-
return ''
|
763
|
-
end
|
764
|
-
raise Git::GitExecuteError.new(git_cmd + ':' + out.to_s)
|
916
|
+
if exitstatus > 1 || (exitstatus == 1 && output != '')
|
917
|
+
raise Git::GitExecuteError.new(git_cmd + ':' + output.to_s)
|
765
918
|
end
|
766
|
-
|
919
|
+
|
920
|
+
return output
|
767
921
|
end
|
768
922
|
|
769
923
|
# Takes the diff command line output (as Array) and parse it into a Hash
|
@@ -816,16 +970,13 @@ module Git
|
|
816
970
|
|
817
971
|
arr_opts << opts[:object] if opts[:object].is_a? String
|
818
972
|
arr_opts << '--' << opts[:path_limiter] if opts[:path_limiter]
|
819
|
-
|
820
973
|
arr_opts
|
821
974
|
end
|
822
975
|
|
823
976
|
def run_command(git_cmd, &block)
|
824
|
-
if block_given?
|
825
|
-
|
826
|
-
|
827
|
-
`#{git_cmd}`.chomp
|
828
|
-
end
|
977
|
+
return IO.popen(git_cmd, &block) if block_given?
|
978
|
+
|
979
|
+
`#{git_cmd}`.chomp
|
829
980
|
end
|
830
981
|
|
831
982
|
def escape(s)
|
data/lib/git/object.rb
CHANGED
@@ -217,9 +217,7 @@ module Git
|
|
217
217
|
end
|
218
218
|
|
219
219
|
def set_commit(data)
|
220
|
-
|
221
|
-
@sha = data['sha']
|
222
|
-
end
|
220
|
+
@sha ||= data['sha']
|
223
221
|
@committer = Git::Author.new(data['committer'])
|
224
222
|
@author = Git::Author.new(data['author'])
|
225
223
|
@tree = Git::Object::Tree.new(@base, data['tree'])
|
@@ -235,10 +233,10 @@ module Git
|
|
235
233
|
|
236
234
|
# see if this object has been initialized and do so if not
|
237
235
|
def check_commit
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
236
|
+
return if @tree
|
237
|
+
|
238
|
+
data = @base.lib.commit_data(@objectish)
|
239
|
+
set_commit(data)
|
242
240
|
end
|
243
241
|
|
244
242
|
end
|
@@ -249,11 +247,43 @@ module Git
|
|
249
247
|
def initialize(base, sha, name)
|
250
248
|
super(base, sha)
|
251
249
|
@name = name
|
250
|
+
@annotated = nil
|
251
|
+
@loaded = false
|
252
|
+
end
|
253
|
+
|
254
|
+
def annotated?
|
255
|
+
@annotated ||= (@base.lib.object_type(self.name) == 'tag')
|
252
256
|
end
|
253
257
|
|
258
|
+
def message
|
259
|
+
check_tag()
|
260
|
+
return @message
|
261
|
+
end
|
262
|
+
|
254
263
|
def tag?
|
255
264
|
true
|
256
265
|
end
|
266
|
+
|
267
|
+
def tagger
|
268
|
+
check_tag()
|
269
|
+
return @tagger
|
270
|
+
end
|
271
|
+
|
272
|
+
private
|
273
|
+
|
274
|
+
def check_tag
|
275
|
+
return if @loaded
|
276
|
+
|
277
|
+
if !self.annotated?
|
278
|
+
@message = @tagger = nil
|
279
|
+
else
|
280
|
+
tdata = @base.lib.tag_data(@name)
|
281
|
+
@message = tdata['message'].chomp
|
282
|
+
@tagger = Git::Author.new(tdata['tagger'])
|
283
|
+
end
|
284
|
+
|
285
|
+
@loaded = true
|
286
|
+
end
|
257
287
|
|
258
288
|
end
|
259
289
|
|
data/lib/git/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -44,14 +44,20 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '4'
|
48
51
|
type: :development
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
55
|
- - ">="
|
53
56
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
57
|
+
version: '2'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '4'
|
55
61
|
description:
|
56
62
|
email: schacon@gmail.com
|
57
63
|
executables: []
|
@@ -59,13 +65,17 @@ extensions: []
|
|
59
65
|
extra_rdoc_files:
|
60
66
|
- README.md
|
61
67
|
files:
|
68
|
+
- CHANGELOG
|
62
69
|
- LICENSE
|
63
70
|
- README.md
|
71
|
+
- VERSION
|
64
72
|
- lib/git.rb
|
65
73
|
- lib/git/author.rb
|
66
74
|
- lib/git/base.rb
|
75
|
+
- lib/git/base/factory.rb
|
67
76
|
- lib/git/branch.rb
|
68
77
|
- lib/git/branches.rb
|
78
|
+
- lib/git/config.rb
|
69
79
|
- lib/git/diff.rb
|
70
80
|
- lib/git/index.rb
|
71
81
|
- lib/git/lib.rb
|
@@ -101,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
111
|
requirements:
|
102
112
|
- git 1.6.0.0, or greater
|
103
113
|
rubyforge_project:
|
104
|
-
rubygems_version: 2.4.
|
114
|
+
rubygems_version: 2.4.5
|
105
115
|
signing_key:
|
106
116
|
specification_version: 4
|
107
117
|
summary: Ruby/Git is a Ruby library that can be used to create, read and manipulate
|