Skip to content

Commit f1366b3

Browse files
author
scott Chacon
committed
got log and cat-file moved to pure ruby
1 parent 90dea6d commit f1366b3

File tree

4 files changed

+162
-28
lines changed

4 files changed

+162
-28
lines changed

camping/gitweb.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# todo
1414
# - diff/patch between any two objects
1515
# - expand patch to entire file
16+
# - set title properly
1617
# - grep / search function
1718
# - prettify : http://projects.wh.techno-weenie.net/changesets/3030
1819
# - add user model (add/remove repos)
@@ -90,10 +91,7 @@ def get repo_id
9091
class View < R '/view/(\d+)'
9192
def get repo_id
9293
@repo = Repository.find repo_id
93-
logger = Logger.new('/tmp/git.log')
94-
logger.level = Logger::INFO
95-
96-
@git = Git.bare(@repo.path, :log => logger)
94+
@git = Git.bare(@repo.path)
9795
render :view
9896
end
9997
end
@@ -109,7 +107,10 @@ def get repo_id, path
109107
class Commit < R '/commit/(\d+)/(\w+)'
110108
def get repo_id, sha
111109
@repo = Repository.find repo_id
112-
@git = Git.bare(@repo.path)
110+
logger = Logger.new('/tmp/git.log')
111+
logger.level = Logger::INFO
112+
113+
@git = Git.bare(@repo.path, :log => logger)
113114
@commit = @git.gcommit(sha)
114115
render :commit
115116
end
@@ -212,7 +213,7 @@ def layout
212213
body :onload => "sh_highlightDocument();" do
213214
before = Time.now().usec
214215
self << yield
215-
self << ((Time.now().usec - before).to_f / 60).to_s + ' sec'
216+
self << '<br/>' + ((Time.now().usec - before).to_f / 60).to_s + ' sec'
216217
end
217218
end
218219
end

lib/git/lib.rb

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Lib
1313
@path = nil
1414

1515
@logger = nil
16+
@raw_repo = nil
1617

1718
def initialize(base = nil, logger = nil)
1819
if base.is_a?(Git::Base)
@@ -75,6 +76,15 @@ def log_commits(opts = {})
7576
end
7677

7778
def full_log_commits(opts = {})
79+
if !(opts[:since] || opts[:between] || opts[:path_limiter])
80+
# can do this in pure ruby
81+
sha = revparse(opts[:object] || branch_current || 'master')
82+
count = opts[:count] || 30
83+
84+
repo = Git::Raw::Repository.new(@git_dir)
85+
return process_commit_data(repo.log(sha, count))
86+
end
87+
7888
arr_opts = ['--pretty=raw']
7989
arr_opts << "-#{opts[:count]}" if opts[:count]
8090
arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
@@ -92,10 +102,13 @@ def revparse(string)
92102
end
93103

94104
head = File.join(@git_dir, 'refs', 'heads', string)
95-
return File.read(head) if File.file?(head)
105+
return File.read(head).chomp if File.file?(head)
96106

97107
head = File.join(@git_dir, 'refs', 'remotes', string)
98-
return File.read(head) if File.file?(head)
108+
return File.read(head).chomp if File.file?(head)
109+
110+
head = File.join(@git_dir, 'refs', 'tags', string)
111+
return File.read(head).chomp if File.file?(head)
99112

100113
command('rev-parse', string)
101114
end
@@ -111,24 +124,30 @@ def object_type(sha)
111124
def object_size(sha)
112125
command('cat-file', ['-s', sha]).to_i
113126
end
127+
128+
def get_raw_repo
129+
@raw_repo ||= Git::Raw::Repository.new(@git_dir)
130+
end
114131

115132
# returns useful array of raw commit object data
116133
def commit_data(sha)
117134
sha = sha.to_s
118-
cdata = command_lines('cat-file', ['commit', sha])
135+
cdata = get_raw_repo.cat_file(revparse(sha))
136+
#cdata = command_lines('cat-file', ['commit', sha])
119137
process_commit_data(cdata, sha)
120138
end
121139

122140
def process_commit_data(data, sha = nil)
123141
in_message = false
124-
142+
125143
if sha
126144
hsh = {'sha' => sha, 'message' => '', 'parent' => []}
127145
else
128146
hsh_array = []
129147
end
130148

131149
data.each do |line|
150+
line = line.chomp
132151
if in_message && line != ''
133152
hsh['message'] += line + "\n"
134153
end

lib/git/raw/repository.rb

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
require 'git/raw/internal/object'
2+
require 'git/raw/internal/pack'
3+
require 'git/raw/internal/loose'
4+
require 'git/raw/object'
5+
6+
module Git
7+
module Raw
8+
9+
class Repository
10+
def initialize(git_dir)
11+
@git_dir = git_dir
12+
@loose = Raw::Internal::LooseStorage.new(git_path("objects"))
13+
@packs = []
14+
initpacks
15+
end
16+
17+
def show
18+
@packs.each do |p|
19+
puts p.name
20+
puts
21+
p.each_sha1 do |s|
22+
puts "**#{p[s].type}**"
23+
if p[s].type.to_s == 'commit'
24+
puts s.unpack('H*')
25+
puts p[s].content
26+
end
27+
end
28+
puts
29+
end
30+
end
31+
32+
def cat_file(sha)
33+
get_raw_object_by_sha1(sha).content rescue nil
34+
end
35+
36+
def log(sha, count = 30)
37+
output = ''
38+
i = 0
39+
40+
while sha && (i < count) do
41+
o = get_raw_object_by_sha1(sha)
42+
c = Git::Raw::Object.from_raw(o)
43+
44+
output += "commit #{sha}\n"
45+
output += o.content + "\n"
46+
47+
sha = c.parent.first
48+
i += 1
49+
end
50+
51+
output
52+
end
53+
54+
def get_object_by_sha1(sha1)
55+
r = get_raw_object_by_sha1(sha1)
56+
return nil if !r
57+
Object.from_raw(r, self)
58+
end
59+
60+
def get_raw_object_by_sha1(sha1)
61+
sha1 = [sha1].pack("H*")
62+
63+
# try packs
64+
@packs.each do |pack|
65+
o = pack[sha1]
66+
return o if o
67+
end
68+
69+
# try loose storage
70+
o = @loose[sha1]
71+
return o if o
72+
73+
# try packs again, maybe the object got packed in the meantime
74+
initpacks
75+
@packs.each do |pack|
76+
o = pack[sha1]
77+
return o if o
78+
end
79+
80+
nil
81+
end
82+
83+
protected
84+
85+
def git_path(path)
86+
return "#@git_dir/#{path}"
87+
end
88+
89+
private
90+
91+
def initpacks
92+
@packs.each do |pack|
93+
pack.close
94+
end
95+
@packs = []
96+
Dir.open(git_path("objects/pack/")) do |dir|
97+
dir.each do |entry|
98+
if entry =~ /\.pack$/i
99+
@packs << Git::Raw::Internal::PackStorage.new(git_path("objects/pack/" \
100+
+ entry))
101+
end
102+
end
103+
end
104+
end
105+
106+
end
107+
108+
end
109+
end

tests/units/test_raw_internals.rb

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env ruby
2-
2+
require 'logger'
33
require File.dirname(__FILE__) + '/../test_helper'
44

55
class TestRawInternals < Test::Unit::TestCase
@@ -10,26 +10,31 @@ def setup
1010

1111
def test_raw_log
1212
g = Git.bare(@wbare)
13-
#g.repack
13+
t_log(g)
14+
end
15+
16+
def test_packed_log
17+
g = Git.bare(@wbare)
18+
g.repack
19+
t_log(g)
20+
end
21+
22+
def test_commit_object
23+
g = Git.bare(@wbare, :log => Logger.new(STDOUT))
1424

15-
c = g.object("HEAD")
16-
puts sha = c.sha
25+
c = g.gcommit("v2.5")
26+
assert_equal('test', c.message)
27+
end
28+
29+
def t_log(g)
30+
c = g.object("v2.5")
31+
sha = c.sha
1732

1833
repo = Git::Raw::Repository.new(@wbare)
19-
while sha do
20-
o = repo.get_raw_object_by_sha1(sha)
21-
c = Git::Raw::Object.from_raw(o)
22-
23-
sha = c.parent.first
24-
puts sha
25-
end
26-
27-
g.log(60).each do |c|
28-
puts c.sha
29-
end
30-
31-
puts c.inspect
34+
raw_out = repo.log(sha)
3235

36+
assert_equal('commit 546bec6f8872efa41d5d97a369f669165ecda0de', raw_out.split("\n").first)
37+
assert_equal('546bec6f8872efa41d5d97a369f669165ecda0de', c.log(30).first.sha)
3338
end
34-
39+
3540
end

0 commit comments

Comments
 (0)