summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/git.rb5
-rw-r--r--lib/git/base.rb10
-rw-r--r--lib/git/commit.rb4
-rw-r--r--lib/git/lib.rb46
-rw-r--r--lib/git/log.rb62
-rw-r--r--lib/git/object.rb64
6 files changed, 160 insertions, 31 deletions
diff --git a/lib/git.rb b/lib/git.rb
index c8e14ad..91c3e0f 100644
--- a/lib/git.rb
+++ b/lib/git.rb
@@ -15,13 +15,8 @@ require 'git/working_directory'
require 'git/log'
require 'git/object'
-require 'git/commit'
-
=begin
-require 'git/object/blob'
-require 'git/object/tree'
-require 'git/object/tag'
require 'git/author'
require 'git/ref'
diff --git a/lib/git/base.rb b/lib/git/base.rb
index c943b86..3c10389 100644
--- a/lib/git/base.rb
+++ b/lib/git/base.rb
@@ -49,6 +49,11 @@ module Git
@index
end
+ # factory methods
+
+ def object(objectish)
+ Git::Object.new(self, objectish)
+ end
def log(count = 30)
Git::Log.new(self, count)
@@ -57,11 +62,6 @@ module Git
def lib
Git::Lib.new(self)
end
-
- private
-
- def is_git_dir(dir)
- end
end
diff --git a/lib/git/commit.rb b/lib/git/commit.rb
deleted file mode 100644
index 1cd5d1d..0000000
--- a/lib/git/commit.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-module Git
- class Commit < Git::Object
- end
-end \ No newline at end of file
diff --git a/lib/git/lib.rb b/lib/git/lib.rb
index 3df049c..595f294 100644
--- a/lib/git/lib.rb
+++ b/lib/git/lib.rb
@@ -1,21 +1,57 @@
module Git
+
+ class GitExecuteError < StandardError
+ end
+
class Lib
-
+
@base = nil
def initialize(base)
@base = base
end
- def log_shas(count)
- command('log', "-#{count} --pretty=oneline").split("\n").map { |l| Git::Commit.new(l.split.first) }
+ def log_commits(opts)
+ arr_opts = ['--pretty=oneline']
+ arr_opts << "-#{opts[:count]}" if opts[:count]
+ arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
+ arr_opts << "#{opts[:between][0]}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
+ arr_opts << opts[:file] if opts[:file].is_a? String
+
+ command('log', arr_opts).split("\n").map { |l| Git::Commit.new(l.split.first) }
+ end
+
+ def revparse(string)
+ command('rev-parse', string)
+ end
+
+ def object_type(sha)
+ command('cat-file', ['-t', sha])
+ end
+
+ def object_size(sha)
+ command('cat-file', ['-s', sha])
+ end
+
+ def object_contents(sha)
+ command('cat-file', ['-p', sha])
end
private
def command(cmd, opts)
- ENV['GIT_DIR'] = @base.repo.path
- `git #{cmd} #{opts}`
+ ENV['GIT_DIR'] = @base.repo.path
+ ENV['GIT_INDEX_FILE'] = @base.index.path
+ ENV['GIT_WORK_DIR'] = @base.dir.path
+ Dir.chdir(@base.dir.path) do
+ opts = opts.to_a.join(' ')
+ #puts "git #{cmd} #{opts}"
+ out = `git #{cmd} #{opts} 2>&1`.chomp
+ if $?.exitstatus != 0
+ raise Git::GitExecuteError.new(out)
+ end
+ out
+ end
end
end
diff --git a/lib/git/log.rb b/lib/git/log.rb
index fab605e..d11a6fa 100644
--- a/lib/git/log.rb
+++ b/lib/git/log.rb
@@ -7,29 +7,79 @@ module Git
@base = nil
@commits = nil
+ @file = nil
+ @count = nil
+ @since = nil
+ @between = nil
+
+ @dirty_flag = nil
+
def initialize(base, count = 30)
+ dirty_log
@base = base
- @commits = @base.lib.log_shas(count)
+ @count = count
+ end
+
+ def file(file)
+ dirty_log
+ @file = file
+ return self
+ end
+
+ def since(date)
+ dirty_log
+ @since = date
+ return self
+ end
+
+ def between(sha1, sha2 = nil)
+ dirty_log
+ @between = [@base.lib.revparse(sha1), @base.lib.revparse(sha2)]
+ return self
+ end
+
+ def to_s
+ self.map { |c| c.sha }.join("\n")
end
+
+ # forces git log to run
+
def size
- @commits.size
+ check_log
+ @commits.size rescue nil
end
def each
+ check_log
@commits.each do |c|
yield c
end
end
def first
- @commits.first
+ check_log
+ @commits.first rescue nil
end
- def to_s
- self.map { |c| c.sha }.join("\n")
- end
+ private
+ def dirty_log
+ @dirty_flag = true
+ end
+
+ def check_log
+ if @dirty_flag
+ run_log
+ @dirty_flag = false
+ end
+ end
+
+ # actually run the 'git log' command
+ def run_log
+ @commits = @base.lib.log_commits(:count => @count, :file => @file, :since => @since, :between => @between)
+ end
+
end
end \ No newline at end of file
diff --git a/lib/git/object.rb b/lib/git/object.rb
index 0252fdb..9346b87 100644
--- a/lib/git/object.rb
+++ b/lib/git/object.rb
@@ -1,16 +1,68 @@
module Git
class Object
- attr_accessor :sha, :type
- def initialize(sha)
- @sha = sha
- end
+ class AbstractObject
+ attr_accessor :sha, :size, :type
+
+ @base = nil
+
+ def initialize(base, sha)
+ @base = base
+ @sha = sha
+ @size = @base.lib.object_size(@sha)
+ setup
+ end
- def cat_file
+ def contents
+ @base.lib.object_contents(@sha)
+ end
+
+ def contents_array
+ self.contents.split("\n")
+ end
+
+ def setup
+ raise NotImplementedError
+ end
+
end
+
- def raw
+ class Blob < AbstractObject
+ def setup
+ @type = 'blob'
+ end
+ end
+
+ class Tree < AbstractObject
+ def setup
+ @type = 'tree'
+ end
+ end
+
+ class Commit < AbstractObject
+ def setup
+ @type = 'commit'
+ end
end
+
+
+ class << self
+ # if we're calling this, we don't know what type it is yet
+ # so this is our little factory method
+ def new(base, objectish)
+ sha = base.lib.revparse(objectish)
+ type = base.lib.object_type(sha)
+
+ klass =
+ case type
+ when /blob/: Blob
+ when /commit/: Commit
+ when /tree/: Tree
+ end
+ klass::new(base, sha)
+ end
+ end
end
end \ No newline at end of file