Skip to content

Commit

Permalink
got log and cat-file moved to pure ruby
Browse files Browse the repository at this point in the history
  • Loading branch information
scott Chacon committed Nov 23, 2007
1 parent 90dea6d commit f1366b3
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 28 deletions.
13 changes: 7 additions & 6 deletions camping/gitweb.rb
Expand Up @@ -13,6 +13,7 @@
# todo
# - diff/patch between any two objects
# - expand patch to entire file
# - set title properly
# - grep / search function
# - prettify : http://projects.wh.techno-weenie.net/changesets/3030
# - add user model (add/remove repos)
Expand Down Expand Up @@ -90,10 +91,7 @@ def get repo_id
class View < R '/view/(\d+)'
def get repo_id
@repo = Repository.find repo_id
logger = Logger.new('/tmp/git.log')
logger.level = Logger::INFO

@git = Git.bare(@repo.path, :log => logger)
@git = Git.bare(@repo.path)
render :view
end
end
Expand All @@ -109,7 +107,10 @@ def get repo_id, path
class Commit < R '/commit/(\d+)/(\w+)'
def get repo_id, sha
@repo = Repository.find repo_id
@git = Git.bare(@repo.path)
logger = Logger.new('/tmp/git.log')
logger.level = Logger::INFO

@git = Git.bare(@repo.path, :log => logger)
@commit = @git.gcommit(sha)
render :commit
end
Expand Down Expand Up @@ -212,7 +213,7 @@ def layout
body :onload => "sh_highlightDocument();" do
before = Time.now().usec
self << yield
self << ((Time.now().usec - before).to_f / 60).to_s + ' sec'
self << '<br/>' + ((Time.now().usec - before).to_f / 60).to_s + ' sec'
end
end
end
Expand Down
27 changes: 23 additions & 4 deletions lib/git/lib.rb
Expand Up @@ -13,6 +13,7 @@ class Lib
@path = nil

@logger = nil
@raw_repo = nil

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

def full_log_commits(opts = {})
if !(opts[:since] || opts[:between] || opts[:path_limiter])
# can do this in pure ruby
sha = revparse(opts[:object] || branch_current || 'master')
count = opts[:count] || 30

repo = Git::Raw::Repository.new(@git_dir)
return process_commit_data(repo.log(sha, count))
end

arr_opts = ['--pretty=raw']
arr_opts << "-#{opts[:count]}" if opts[:count]
arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
Expand All @@ -92,10 +102,13 @@ def revparse(string)
end

head = File.join(@git_dir, 'refs', 'heads', string)
return File.read(head) if File.file?(head)
return File.read(head).chomp if File.file?(head)

head = File.join(@git_dir, 'refs', 'remotes', string)
return File.read(head) if File.file?(head)
return File.read(head).chomp if File.file?(head)

head = File.join(@git_dir, 'refs', 'tags', string)
return File.read(head).chomp if File.file?(head)

command('rev-parse', string)
end
Expand All @@ -111,24 +124,30 @@ def object_type(sha)
def object_size(sha)
command('cat-file', ['-s', sha]).to_i
end

def get_raw_repo
@raw_repo ||= Git::Raw::Repository.new(@git_dir)
end

# returns useful array of raw commit object data
def commit_data(sha)
sha = sha.to_s
cdata = command_lines('cat-file', ['commit', sha])
cdata = get_raw_repo.cat_file(revparse(sha))
#cdata = command_lines('cat-file', ['commit', sha])
process_commit_data(cdata, sha)
end

def process_commit_data(data, sha = nil)
in_message = false

if sha
hsh = {'sha' => sha, 'message' => '', 'parent' => []}
else
hsh_array = []
end

data.each do |line|
line = line.chomp
if in_message && line != ''
hsh['message'] += line + "\n"
end
Expand Down
109 changes: 109 additions & 0 deletions lib/git/raw/repository.rb
@@ -0,0 +1,109 @@
require 'git/raw/internal/object'
require 'git/raw/internal/pack'
require 'git/raw/internal/loose'
require 'git/raw/object'

module Git
module Raw

class Repository
def initialize(git_dir)
@git_dir = git_dir
@loose = Raw::Internal::LooseStorage.new(git_path("objects"))
@packs = []
initpacks
end

def show
@packs.each do |p|
puts p.name
puts
p.each_sha1 do |s|
puts "**#{p[s].type}**"
if p[s].type.to_s == 'commit'
puts s.unpack('H*')
puts p[s].content
end
end
puts
end
end

def cat_file(sha)
get_raw_object_by_sha1(sha).content rescue nil
end

def log(sha, count = 30)
output = ''
i = 0

while sha && (i < count) do
o = get_raw_object_by_sha1(sha)
c = Git::Raw::Object.from_raw(o)

output += "commit #{sha}\n"
output += o.content + "\n"

sha = c.parent.first
i += 1
end

output
end

def get_object_by_sha1(sha1)
r = get_raw_object_by_sha1(sha1)
return nil if !r
Object.from_raw(r, self)
end

def get_raw_object_by_sha1(sha1)
sha1 = [sha1].pack("H*")

# try packs
@packs.each do |pack|
o = pack[sha1]
return o if o
end

# try loose storage
o = @loose[sha1]
return o if o

# try packs again, maybe the object got packed in the meantime
initpacks
@packs.each do |pack|
o = pack[sha1]
return o if o
end

nil
end

protected

def git_path(path)
return "#@git_dir/#{path}"
end

private

def initpacks
@packs.each do |pack|
pack.close
end
@packs = []
Dir.open(git_path("objects/pack/")) do |dir|
dir.each do |entry|
if entry =~ /\.pack$/i
@packs << Git::Raw::Internal::PackStorage.new(git_path("objects/pack/" \
+ entry))
end
end
end
end

end

end
end
41 changes: 23 additions & 18 deletions tests/units/test_raw_internals.rb
@@ -1,5 +1,5 @@
#!/usr/bin/env ruby

require 'logger'
require File.dirname(__FILE__) + '/../test_helper'

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

def test_raw_log
g = Git.bare(@wbare)
#g.repack
t_log(g)
end

def test_packed_log
g = Git.bare(@wbare)
g.repack
t_log(g)
end

def test_commit_object
g = Git.bare(@wbare, :log => Logger.new(STDOUT))

c = g.object("HEAD")
puts sha = c.sha
c = g.gcommit("v2.5")
assert_equal('test', c.message)
end

def t_log(g)
c = g.object("v2.5")
sha = c.sha

repo = Git::Raw::Repository.new(@wbare)
while sha do
o = repo.get_raw_object_by_sha1(sha)
c = Git::Raw::Object.from_raw(o)

sha = c.parent.first
puts sha
end

g.log(60).each do |c|
puts c.sha
end

puts c.inspect
raw_out = repo.log(sha)

assert_equal('commit 546bec6f8872efa41d5d97a369f669165ecda0de', raw_out.split("\n").first)
assert_equal('546bec6f8872efa41d5d97a369f669165ecda0de', c.log(30).first.sha)
end

end

0 comments on commit f1366b3

Please sign in to comment.