Skip to content

Commit 907b039

Browse files
author
scott Chacon
committed
added tagging
1 parent b81ee93 commit 907b039

File tree

9 files changed

+235
-19
lines changed

9 files changed

+235
-19
lines changed

EXAMPLES

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,10 @@ end
5555
g.config('user.name') # returns 'Scott Chacon'
5656
g.config # returns whole config hash
5757

58-
***** IMPLEMENTED *****
59-
6058
g.tag # returns array of Git::Tag objects
6159

6260

6361

64-
6562
# needs write permission
6663

6764

@@ -114,21 +111,25 @@ g.merge('origin/remote_branch')
114111
g.merge(b.branch('master'))
115112
g.merge([branch1, branch2])
116113

114+
r = g.add_remote(name, uri) # Git::Remote
115+
r = g.add_remote(name, Git::Base) # Git::Remote
117116

118-
***** IMPLEMENTED *****
119-
120-
g.add_remote(uri, name) # Git::Remote
121-
g.remotes
117+
g.remotes # array of Git::Remotes
122118
g.remote(name).fetch
119+
g.remote(name).remove
123120
g.remote(name).merge
124121
g.remote(name).merge(branch)
125122

126123
g.fetch
127-
g.fetch(Git::Remote)
124+
g.fetch(g.remotes.first)
128125

129126
g.pull
130127
g.pull(Git::Repo, Git::Branch) # fetch and a merge
131128

132-
g.tag('tag_name') # returns Git::Tag
129+
g.add_tag('tag_name') # returns Git::Tag
130+
131+
132+
***** IMPLEMENTED *****
133+
133134

134135
g.pack

TODO

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
* More Error Examples
3+
4+
* More Git::Status methods
5+
6+
* Speed up through pure ruby
7+
8+
* Speed up through C bindings to libgit-thin

lib/git/base.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ def index
8484
@index
8585
end
8686

87+
def chdir
88+
Dir.chdir(dir.path) do
89+
yield dir.path
90+
end
91+
end
8792

8893
#g.config('user.name', 'Scott Chacon') # sets value
8994
#g.config('user.email', 'email@email.com') # sets value
@@ -128,6 +133,10 @@ def branch(branch_name = 'master')
128133
Git::Branch.new(self, branch_name)
129134
end
130135

136+
def remote(remote_name = 'origin')
137+
Git::Remote.new(self, remote_name)
138+
end
139+
131140

132141
def lib
133142
Git::Lib.new(self)
@@ -172,11 +181,46 @@ def checkout(branch, opts = {})
172181
self.lib.checkout(branch, opts)
173182
end
174183

184+
def fetch(remote = 'origin')
185+
self.lib.fetch(remote)
186+
end
187+
175188
def merge(branch, message = 'merge')
176189
self.lib.merge(branch, message)
177190
end
178191

192+
def pull(remote = 'origin', branch = 'master', message = 'origin pull')
193+
fetch(remote)
194+
merge(branch, message)
195+
end
196+
197+
def remotes
198+
self.lib.remotes.map { |r| Git::Remote.new(self, r) }
199+
end
200+
201+
def add_remote(name, url, opts = {})
202+
if url.is_a?(Git::Base)
203+
url = url.repo.path
204+
end
205+
self.lib.remote_add(name, url, opts)
206+
Git::Remote.new(self, name)
207+
end
208+
209+
def tags
210+
self.lib.tags.map { |r| tag(r) }
211+
end
212+
213+
def tag(tag_name)
214+
Git::Object.new(self, tag_name, true)
215+
end
216+
217+
def add_tag(tag_name)
218+
self.lib.tag(tag_name)
219+
tag(tag_name)
220+
end
221+
179222
# convenience methods
223+
180224

181225
def revparse(objectish)
182226
self.lib.revparse(objectish)

lib/git/branch.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def merge(branch = nil, message = nil)
7373
end
7474

7575
def to_s
76-
@name
76+
@full
7777
end
7878

7979
private

lib/git/lib.rb

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,43 @@ def merge(branch, message = nil)
264264
command('merge', arr_opts)
265265
end
266266

267+
def remote_add(name, url, opts = {})
268+
arr_opts = ['add']
269+
arr_opts << '-f' if opts[:with_fetch]
270+
arr_opts << name
271+
arr_opts << url
272+
273+
command('remote', arr_opts)
274+
end
275+
276+
# this is documented as such, but seems broken for some reason
277+
# i'll try to get around it some other way later
278+
def remote_remove(name)
279+
command('remote', ['rm', name])
280+
end
281+
282+
def remotes
283+
command_lines('remote')
284+
end
285+
286+
def tags
287+
command_lines('tag')
288+
end
289+
290+
def tag(tag)
291+
command('tag', tag)
292+
end
293+
294+
295+
def fetch(remote)
296+
command('fetch', remote.to_s)
297+
end
298+
299+
def tag_sha(tag_name)
300+
command('show-ref', ['--tags', '-s', tag_name])
301+
end
302+
303+
267304

268305
private
269306

@@ -278,19 +315,20 @@ def command(cmd, opts = {})
278315
path = @git_work_dir || @git_dir || @path
279316
Dir.chdir(path) do
280317
opts = opts.to_a.join(' ')
318+
git_cmd = "git #{cmd} #{opts}"
281319
out = `git #{cmd} #{opts} 2>&1`.chomp
282320
#puts path
283321
#puts "gd: #{@git_work_dir}"
284322
#puts "gi: #{@git_index_file}"
285323
#puts "pp: #{@path}"
286-
#puts "git #{cmd} #{opts}"
324+
#puts git_cmd
287325
#puts out
288326
#puts
289327
if $?.exitstatus > 0
290328
if $?.exitstatus == 1 && out == ''
291329
return ''
292330
end
293-
raise Git::GitExecuteError.new(out)
331+
raise Git::GitExecuteError.new(git_cmd + out.to_s)
294332
end
295333
out
296334
end

lib/git/object.rb

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
module Git
2+
3+
class GitTagNameDoesNotExist< StandardError
4+
end
5+
26
class Object
37

48
class AbstractObject
@@ -64,14 +68,34 @@ def setup
6468
end
6569
end
6670

67-
71+
class Tag < AbstractObject
72+
attr_accessor :name
73+
74+
def initialize(base, sha, name)
75+
super(base, sha)
76+
@name = name
77+
end
78+
79+
def setup
80+
@type = 'tag'
81+
end
82+
end
83+
6884
class << self
6985
# if we're calling this, we don't know what type it is yet
7086
# so this is our little factory method
71-
def new(base, objectish)
72-
sha = base.lib.revparse(objectish)
73-
type = base.lib.object_type(sha)
74-
87+
def new(base, objectish, is_tag = false)
88+
if is_tag
89+
sha = base.lib.tag_sha(objectish)
90+
if sha == ''
91+
raise Git::GitTagNameDoesNotExist.new(objectish)
92+
end
93+
return Tag.new(base, sha, objectish)
94+
else
95+
sha = base.lib.revparse(objectish)
96+
type = base.lib.object_type(sha)
97+
end
98+
7599
klass =
76100
case type
77101
when /blob/: Blob

lib/git/remote.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Git
22
class Remote < Path
33

4-
attr_accessor :name, :url, :fetch
4+
attr_accessor :name, :url, :fetch_opts
55

66
@base = nil
77

@@ -10,7 +10,28 @@ def initialize(base, name)
1010
config = @base.lib.config_remote(name)
1111
@name = name
1212
@url = config['url']
13-
@fetch = config['fetch']
13+
@fetch_opts = config['fetch']
14+
end
15+
16+
def remove
17+
@base.remote_remove(@name)
18+
end
19+
20+
def fetch
21+
@base.fetch(@name)
22+
end
23+
24+
# merge this remote locally
25+
def merge(branch = 'master')
26+
@base.merge("#{@name}/#{branch}")
27+
end
28+
29+
def branch(branch = 'master')
30+
Git::Branch.new(@base, "#{@name}/#{branch}")
31+
end
32+
33+
def remove
34+
@base.lib.remote_remove(@name)
1435
end
1536

1637
def to_s

tests/units/test_remotes.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env ruby
2+
3+
require File.dirname(__FILE__) + '/../test_helper'
4+
5+
class TestRemotes < Test::Unit::TestCase
6+
def setup
7+
set_file_paths
8+
end
9+
10+
def test_remote_fun
11+
in_temp_dir do |path|
12+
loc = Git.clone(@wbare, 'local')
13+
rem = Git.clone(@wbare, 'remote')
14+
15+
r = loc.add_remote('testrem', rem)
16+
17+
Dir.chdir('remote') do
18+
new_file('test-file1', 'blahblahblah1')
19+
rem.add
20+
rem.commit('master commit')
21+
22+
rem.branch('testbranch').in_branch('tb commit') do
23+
new_file('test-file3', 'blahblahblah3')
24+
rem.add
25+
true
26+
end
27+
end
28+
assert(!loc.status['test-file1'])
29+
assert(!loc.status['test-file3'])
30+
31+
r.fetch
32+
r.merge
33+
assert(loc.status['test-file1'])
34+
35+
loc.merge(loc.remote('testrem').branch('testbranch'))
36+
assert(loc.status['test-file3'])
37+
38+
#puts loc.remotes.map { |r| r.to_s }.inspect
39+
40+
#r.remove
41+
#puts loc.remotes.inspect
42+
end
43+
end
44+
45+
end

tests/units/test_tags.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env ruby
2+
3+
require File.dirname(__FILE__) + '/../test_helper'
4+
5+
class TestTags < Test::Unit::TestCase
6+
def setup
7+
set_file_paths
8+
end
9+
10+
def test_tags
11+
in_temp_dir do |path|
12+
r1 = Git.clone(@wbare, 'repo1')
13+
r2 = Git.clone(@wbare, 'repo2')
14+
15+
assert_raise Git::GitTagNameDoesNotExist do
16+
r1.tag('first')
17+
end
18+
19+
r1.add_tag('first')
20+
r1.chdir do
21+
new_file('new_file', 'new content')
22+
end
23+
r1.add
24+
r1.commit('my commit')
25+
r1.add_tag('second')
26+
27+
assert(r1.tags.map{|t| t.name}.include?('first'))
28+
29+
r2.add_tag('third')
30+
31+
assert(r2.tags.map{|t| t.name}.include?('third'))
32+
assert(!r2.tags.map{|t| t.name}.include?('second'))
33+
end
34+
end
35+
end

0 commit comments

Comments
 (0)