summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscott Chacon <schacon@agadorsparticus.(none)>2007-11-23 11:16:46 -0800
committerscott Chacon <schacon@agadorsparticus.(none)>2007-11-23 11:16:46 -0800
commitf1366b39891402b0db9de661ad181089bfd79053 (patch)
treed6ef49a6bda5b7327d6d6a66edfb9c8bdb5a97cc
parent90dea6d415bfc5734bc87c2797b26cca311246bc (diff)
downloadthird_party-ruby-git-f1366b39891402b0db9de661ad181089bfd79053.tar.gz
third_party-ruby-git-f1366b39891402b0db9de661ad181089bfd79053.tar.xz
third_party-ruby-git-f1366b39891402b0db9de661ad181089bfd79053.zip
got log and cat-file moved to pure ruby
-rw-r--r--camping/gitweb.rb13
-rw-r--r--lib/git/lib.rb27
-rw-r--r--lib/git/raw/repository.rb109
-rw-r--r--tests/units/test_raw_internals.rb41
4 files changed, 162 insertions, 28 deletions
diff --git a/camping/gitweb.rb b/camping/gitweb.rb
index 092649d..8dc40ba 100644
--- a/camping/gitweb.rb
+++ b/camping/gitweb.rb
@@ -13,6 +13,7 @@ require 'lib/git'
# 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)
@@ -90,10 +91,7 @@ module GitWeb::Controllers
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
@@ -109,7 +107,10 @@ module GitWeb::Controllers
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
@@ -212,7 +213,7 @@ module GitWeb::Views
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
diff --git a/lib/git/lib.rb b/lib/git/lib.rb
index eb06875..9c6a041 100644
--- a/lib/git/lib.rb
+++ b/lib/git/lib.rb
@@ -13,6 +13,7 @@ module Git
@path = nil
@logger = nil
+ @raw_repo = nil
def initialize(base = nil, logger = nil)
if base.is_a?(Git::Base)
@@ -75,6 +76,15 @@ module Git
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
@@ -92,10 +102,13 @@ module Git
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
@@ -111,17 +124,22 @@ module Git
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
@@ -129,6 +147,7 @@ module Git
end
data.each do |line|
+ line = line.chomp
if in_message && line != ''
hsh['message'] += line + "\n"
end
diff --git a/lib/git/raw/repository.rb b/lib/git/raw/repository.rb
new file mode 100644
index 0000000..4a1c897
--- /dev/null
+++ b/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
diff --git a/tests/units/test_raw_internals.rb b/tests/units/test_raw_internals.rb
index 4299a2b..1437845 100644
--- a/tests/units/test_raw_internals.rb
+++ b/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
@@ -10,26 +10,31 @@ class TestRawInternals < Test::Unit::TestCase
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 \ No newline at end of file