From 9d59d2965184964ab6662282ef5f9ceac2c58552 Mon Sep 17 00:00:00 2001 From: scott Chacon Date: Fri, 9 Nov 2007 13:11:22 -0800 Subject: added branches, more log stuff, better tests, changed the log api a bit added tests for Git::Lib, started Git::Diff development --- EXAMPLES | 109 ++++++++++++++++++++++++++++++++ README | 129 ++------------------------------------ lib/git.rb | 10 +-- lib/git/base.rb | 8 +++ lib/git/branch.rb | 16 ++++- lib/git/branches.rb | 30 ++++++++- lib/git/diff.rb | 37 +++++++++++ lib/git/lib.rb | 50 +++++++++++++-- lib/git/log.rb | 17 +++-- lib/git/object.rb | 10 +++ lib/git/remote.rb | 21 +++++++ tests/files/working | 1 + tests/files/working/ex_dir/ex.txt | 0 tests/files/working/example.txt | 1 - tests/units/test_branch.rb | 49 +++++++++++++++ tests/units/test_diff.rb | 29 +++++++++ tests/units/test_lib.rb | 124 ++++++++++++++++++++++++++++++++++++ tests/units/test_log.rb | 8 +-- tests/units/test_object.rb | 17 +++++ 19 files changed, 522 insertions(+), 144 deletions(-) create mode 100644 EXAMPLES create mode 100644 lib/git/diff.rb create mode 100644 lib/git/remote.rb create mode 160000 tests/files/working delete mode 100644 tests/files/working/ex_dir/ex.txt delete mode 100644 tests/files/working/example.txt create mode 100644 tests/units/test_branch.rb create mode 100644 tests/units/test_diff.rb create mode 100644 tests/units/test_lib.rb diff --git a/EXAMPLES b/EXAMPLES new file mode 100644 index 0000000..bea9be7 --- /dev/null +++ b/EXAMPLES @@ -0,0 +1,109 @@ +require 'git' + +# needs read permission only + +g = Git.open (working_dir = '.') + (git_dir, index_file) + +g.index +g.index.readable? +g.index.writable? +g.repo +g.dir + +g.log # returns array of Git::Commit objects +g.log.since('2 weeks ago') +g.log.between('v2.5', 'v2.6') +g.log.each {|l| puts l.sha } +g.blob('v2.5:Makefile').log.since('2 weeks ago') + +g.object('HEAD^').to_s # git show / git rev-parse +g.object('HEAD^').contents +g.object('v2.5:Makefile').size +g.object('v2.5:Makefile').sha + +g.tree(treeish) +g.blob(treeish) +g.commit(treeish) + +g.revparse('v2.5:Makefile') + +g.branches # returns Git::Branch objects +g.branches.local +g.branches.remote +g.branches[:master].commit +g.branches['origin/master'].commit + +g.grep('hello') # implies HEAD +g.blob('v2.5:Makefile').grep('hello') +g.tag('v2.5').grep('hello', 'docs/') + + +***** IMPLEMENTED ***** + +g.diff +g.diff.shortstat +g.diff.summary +g.diff(commit1, commit2) +g.diff("commit1..commit2") + +g.diff_tree(Git::Tree, Git::Tree) + + +g.status + +g.ls_files +g.ls_files(:stage => true) + +g.tag # returns array of Git::Tag objects + + +# needs write permission + +g = Git.clone(URI, 'name', working_dir = GIT_DIR, {options}) + (username, password, ssl_key, git_dir, index_file) + +g = Git.init + Git.init('project') + Git.init('/home/schacon/proj', + { :git_dir => '/opt/git/proj.git', + :index_file => '/tmp/index'} ) + + + +g.config('user.name', 'Scott Chacon') +g.config('user.email', 'email@email.com') +g.config('user.name') # returns 'Scott Chacon' +g.config # returns whole config hash + +g.add('.') +g.add([file1, file2]) + +g.remove('file.txt').and_file + +g.commit('message') +g.commit_a('message') + +g.reset # defaults to HEAD +g.reset_hard(Git::Commit) + +g.branch('new_branch') +g.branch('new_branch').delete + +g.checkout('new_branch') +g.checkout('new_branch', :create_branch => true) +g.checkout_b('new_branch') + +g.merge('new_branch') +g.merge(Git::Branch) +g.merge(Git::Branch, Git::Branch) + +g.fetch +g.fetch(Git::Repo) + +g.pull +g.pull(Git::Repo, Git::Branch) # fetch and a merge + +g.tag('tag_name') # returns Git::Tag + +g.pack diff --git a/README b/README index dacfefe..5f9c69a 100644 --- a/README +++ b/README @@ -1,131 +1,14 @@ Git Library for Ruby ----------------------------- -Git -Git::Repository -Git::Index -Git::WorkingDirectory << Dir - -Git::Object - -Git::Commit << Git::Object -Git::Blob -Git::Tree -Git::Tag - -Git::Author -Git::Ref -Git::File (in working dir) -Git::Log -Git::Sha -Git::Diff -Git::Branch -Git::Remote << Git::Repository - -require 'git' - - -# needs read permission only - -g = Git.open (working_dir = '.') - (git_dir, index_file) - -g.index -g.index.readable? -g.index.writable? -g.repo -g.dir - -g.log # returns array of Git::Commit objects -g.log.since('2 weeks ago') -g.log.between('v2.5', 'v2.6') -g.log.since('v2.5').file('Makefile') -g.log.each {|l| puts l.sha } - -g.object('HEAD^').to_s # git show / git rev-parse -g.object('HEAD^').contents -g.object('v2.5:Makefile').size -g.object('v2.5:Makefile').sha - -g.revparse('v2.5:Makefile') - -********** - -g.file('flim/ChangeLog').tags.each {|tag,rev| p [tag,rev.to_s]} -g.file('flim/ChangeLog').logs.each { |log| log.sha } - -g.branches # returns Git::Branch objects -g.branches.local -g.branches.remote - -g.status - -g.grep('hello') -g.grep('hello', Git::Tag) - - -g.ls_files -g.ls_files(:stage => true) - -g.diff -g.diff_cached -g.diff(commit1, commit2) -g.diff("commit1..commit2") - -g.diff_tree(Git::Tree, Git::Tree) - -g.tag # returns array of Git::Tag objects - - -# needs write permission - -g = Git.clone(URI, 'name', working_dir = GIT_DIR, {options}) - (username, password, ssl_key, git_dir, index_file) - -g = Git.init - Git.init('project') - Git.init('/home/schacon/proj', - { :git_dir => '/opt/git/proj.git', - :index_file => '/tmp/index'} ) - - - -g.config('user.name', 'Scott Chacon') -g.config('user.email', 'email@email.com') -g.config('user.name') # returns 'Scott Chacon' -g.config # returns whole config hash - -g.add('.') -g.add([file1, file2]) - -g.remove('file.txt').and_file - -g.commit('message') -g.commit_a('message') - -g.reset # defaults to HEAD -g.reset_hard(Git::Commit) - -g.branch('new_branch') -g.branch('new_branch').delete - -g.checkout('new_branch') -g.checkout('new_branch', :create_branch => true) -g.checkout_b('new_branch') - -g.merge('new_branch') -g.merge(Git::Branch) -g.merge(Git::Branch, Git::Branch) - -g.fetch -g.fetch(Git::Repo) - -g.pull -g.pull(Git::Repo, Git::Branch) # fetch and a merge +Library for using Git in Ruby. -g.tag('tag_name') # returns Git::Tag +Right now I'm forking calls to the 'git' binary, +but eventually I'll replace that with either C bindings +to libgit or libgit-thin, or I'll write pure ruby +handlers for at least some of the Git stuff. -g.pack +See EXAMPLES file for, well, examples. diff --git a/lib/git.rb b/lib/git.rb index 634109e..a43aee2 100644 --- a/lib/git.rb +++ b/lib/git.rb @@ -15,19 +15,19 @@ require 'git/working_directory' require 'git/log' require 'git/object' +require 'git/branches' require 'git/branch' +require 'git/remote' =begin - - require 'git/author' -require 'git/ref' require 'git/file' -require 'git/sha' require 'git/diff' - require 'git/remote' + +require 'git/sha' +require 'git/ref' =end module Git diff --git a/lib/git/base.rb b/lib/git/base.rb index d552432..8170065 100644 --- a/lib/git/base.rb +++ b/lib/git/base.rb @@ -54,6 +54,10 @@ module Git def object(objectish) Git::Object.new(self, objectish) end + alias_method :tree, :object + alias_method :commit, :object + alias_method :blob, :object + def log(count = 30) Git::Log.new(self, count) @@ -67,6 +71,10 @@ module Git Git::Lib.new(self) end + def grep(string) + self.object('HEAD').grep(string) + end + # convenience methods def revparse(objectish) diff --git a/lib/git/branch.rb b/lib/git/branch.rb index 8f8953b..cc33970 100644 --- a/lib/git/branch.rb +++ b/lib/git/branch.rb @@ -1,10 +1,24 @@ module Git class Branch < Path + attr_accessor :full, :remote, :name, :current, :commit + @base = nil - def initialize(base, name) + def initialize(base, name, current = false) + @remote = nil + @full = name @base = base + @commit = @base.object(name) + @current = current + + parts = name.split('/') + if parts[1] + @remote = Git::Remote.new(@base, parts[0]) + @name = parts[1] + else + @name = parts[0] + end end end diff --git a/lib/git/branches.rb b/lib/git/branches.rb index d664d59..81abe22 100644 --- a/lib/git/branches.rb +++ b/lib/git/branches.rb @@ -8,8 +8,36 @@ module Git @branches = nil def initialize(base) + @branches = {} + @base = base - @branches = @base.lib.branches_all + @base.lib.branches_all.each do |b| + @branches[b.full] = b + end + end + + def local + self.select { |b| !b.remote } + end + + def remote + self.select { |b| b.remote } + end + + # array like methods + + def size + @branches.size + end + + def each + @branches.each do |k, b| + yield b + end + end + + def [](symbol) + @branches[symbol.to_s] end end diff --git a/lib/git/diff.rb b/lib/git/diff.rb new file mode 100644 index 0000000..3686edb --- /dev/null +++ b/lib/git/diff.rb @@ -0,0 +1,37 @@ +module Git + + # object that holds the last X commits on given branch + class Diff + include Enumerable + + @base = nil + @from = nil + @to = nil + + @full_diff = nil + + def initialize(base, from = nil, to = nil) + dirty_log + @base = base + @from = from + @to = to + end + + def + # enumerable methods + + def each + cache_diff + @full_diff.each do |file| + yield file + end + end + + private + + def cache_diff + if !@full_diff + @full_diff = @base.lib.diff_files(@from, @to) + end + end +end \ No newline at end of file diff --git a/lib/git/lib.rb b/lib/git/lib.rb index c83ecaa..2937d52 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -3,6 +3,9 @@ module Git class GitExecuteError < StandardError end + class GitNoOutput < StandardError + end + class Lib @base = nil @@ -11,14 +14,15 @@ module Git @base = base end - def log_commits(opts) + 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 + arr_opts << opts[:object] if opts[:object].is_a? String + arr_opts << '-- ' + opts[:path_limiter] if opts[:path_limiter].is_a? String - command_lines('log', arr_opts).map { |l| Git::Object::Commit.new(@base, l.split.first) } + command_lines('log', arr_opts).map { |l| l.split.first } end def revparse(string) @@ -38,7 +42,42 @@ module Git end def branches_all - command_lines('branch', '-a').map { |l| Git::Branch.new(@base, l) } + command_lines('branch', '-a').map do |b| + current = false + current = true if b[0, 2] == '* ' + Git::Branch.new(@base, b.gsub('* ', '').strip, current) + end + end + + def config_remote(name) + hsh = {} + command_lines('config', ['--get-regexp', "remote.#{name}"]).each do |line| + (key, value) = line.split + hsh[key.gsub("remote.#{name}.", '')] = value + end + hsh + end + + # returns hash + # [tree-ish] = [[line_no, match], [line_no, match2]] + # [tree-ish] = [[line_no, match], [line_no, match2]] + def grep(string, opts = {}) + opts[:object] = 'HEAD' if !opts[:object] + + grep_opts = ['-n'] + grep_opts << '-i' if opts[:ignore_case] + grep_opts << '-v' if opts[:invert_match] + grep_opts << "-e '#{string}'" + grep_opts << opts[:object] if opts[:object].is_a? String + grep_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String + hsh = {} + command_lines('grep', grep_opts).each do |line| + if m = /(.*)\:(\d+)\:(.*)/.match(line) + hsh[m[1]] ||= [] + hsh[m[1]] << [m[2].to_i, m[3]] + end + end + hsh end private @@ -55,7 +94,8 @@ module Git opts = opts.to_a.join(' ') #puts "git #{cmd} #{opts}" out = `git #{cmd} #{opts} 2>&1`.chomp - if $?.exitstatus != 0 + #puts out + if $?.exitstatus > 1 raise Git::GitExecuteError.new(out) end out diff --git a/lib/git/log.rb b/lib/git/log.rb index d11a6fa..eb625f3 100644 --- a/lib/git/log.rb +++ b/lib/git/log.rb @@ -7,7 +7,8 @@ module Git @base = nil @commits = nil - @file = nil + @object = nil + @path = nil @count = nil @since = nil @between = nil @@ -20,9 +21,15 @@ module Git @count = count end - def file(file) + def object(objectish) dirty_log - @file = file + @object = objectish + return self + end + + def path(path) + dirty_log + @path = path return self end @@ -77,7 +84,9 @@ module Git # actually run the 'git log' command def run_log - @commits = @base.lib.log_commits(:count => @count, :file => @file, :since => @since, :between => @between) + log = @base.lib.log_commits(:count => @count, :object => @object, + :path_limiter => @path, :since => @since, :between => @between) + @commits = log.map { |l| Git::Object::Commit.new(@base, l) } end end diff --git a/lib/git/object.rb b/lib/git/object.rb index 4f8e559..f2d4114 100644 --- a/lib/git/object.rb +++ b/lib/git/object.rb @@ -29,6 +29,16 @@ module Git "#{@type.ljust(6)} #{@sha}" end + def grep(string, path_limiter = nil, opts = {}) + default = {:object => @sha, :path_limiter => path_limiter} + grep_options = default.merge(opts) + @base.lib.grep(string, grep_options) + end + + def log(count = 30) + Git::Log.new(self, count).object(@sha) + end + end diff --git a/lib/git/remote.rb b/lib/git/remote.rb new file mode 100644 index 0000000..6956d47 --- /dev/null +++ b/lib/git/remote.rb @@ -0,0 +1,21 @@ +module Git + class Remote < Path + + attr_accessor :name, :url, :fetch + + @base = nil + + def initialize(base, name) + @base = base + config = @base.lib.config_remote(name) + @name = name + @url = config['url'] + @fetch = config['fetch'] + end + + def to_s + @name + end + + end +end \ No newline at end of file diff --git a/tests/files/working b/tests/files/working new file mode 160000 index 0000000..935badc --- /dev/null +++ b/tests/files/working @@ -0,0 +1 @@ +Subproject commit 935badc874edd62a8629aaf103418092c73f0a56 diff --git a/tests/files/working/ex_dir/ex.txt b/tests/files/working/ex_dir/ex.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/files/working/example.txt b/tests/files/working/example.txt deleted file mode 100644 index 1f09f2e..0000000 --- a/tests/files/working/example.txt +++ /dev/null @@ -1 +0,0 @@ -replace with new text diff --git a/tests/units/test_branch.rb b/tests/units/test_branch.rb new file mode 100644 index 0000000..ea242fc --- /dev/null +++ b/tests/units/test_branch.rb @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../test_helper' + +class TestBranch < Test::Unit::TestCase + def setup + set_file_paths + @git = Git.open(@wdir) + + @commit = @git.object('1cc8667014381') + @tree = @git.object('1cc8667014381^{tree}') + @blob = @git.object('v2.5:example.txt') + + @branches = @git.branches + end + + + def test_branches_all + assert(@git.branches[:master].is_a?(Git::Branch)) + assert(@git.branches.size > 5) + end + + def test_branches_local + bs = @git.branches.local + assert(bs.size > 4) + end + + def test_branches_remote + bs = @git.branches.remote + assert_equal(1, bs.size) + end + + def test_branches_single + b = @git.branches[:test_object] + assert_equal('test_object', b.name) + + b = @git.branches['working/master'] + assert_equal('master', b.name) + assert_equal('working/master', b.full) + assert_equal('working', b.remote.name) + assert_equal('+refs/heads/*:refs/remotes/working/*', b.remote.fetch) + assert_equal('../working.git', b.remote.url) + end + + def test_branch_commit + assert_equal(270, @git.branches[:test_branches].commit.size) + end + +end \ No newline at end of file diff --git a/tests/units/test_diff.rb b/tests/units/test_diff.rb new file mode 100644 index 0000000..b8ed6b8 --- /dev/null +++ b/tests/units/test_diff.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../test_helper' + +class TestDiff < Test::Unit::TestCase + def setup + set_file_paths + @git = Git.open(@wdir) + end + + def test_diff + end + + def test_diff_summary + end + + def test_diff_stat + end + + def test_diff_shortstat + end + + def test_patch + end + + def test_unified + end + +end \ No newline at end of file diff --git a/tests/units/test_lib.rb b/tests/units/test_lib.rb new file mode 100644 index 0000000..03a4411 --- /dev/null +++ b/tests/units/test_lib.rb @@ -0,0 +1,124 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../test_helper' + +# tests all the low level git communication +# +# this will be helpful if we ever figure out how +# to either build these in pure ruby or get git bindings working +# because right now it forks for every call + +class TestLib < Test::Unit::TestCase + def setup + set_file_paths + @lib = Git.open(@wdir).lib + end + + # takes parameters, returns array of appropriate commit objects + # :count + # :since + # :between + # :object + def test_log_commits + a = @lib.log_commits :count => 10 + assert(a.first.is_a?(String)) + assert_equal(10, a.size) + + a = @lib.log_commits :count => 20, :since => '3 years ago' + assert(a.first.is_a?(String)) + assert_equal(20, a.size) + + a = @lib.log_commits :count => 20, :since => '1 second ago' + assert_equal(0, a.size) + + a = @lib.log_commits :count => 20, :between => ['v2.5', 'v2.6'] + assert_equal(2, a.size) + + a = @lib.log_commits :count => 20, :object => 'example.txt' + assert_equal(20, a.size) + + a = @lib.log_commits :count => 20, :object => 'ex_dir/ex.txt' + assert_equal(1, a.size) + end + + def test_revparse + assert_equal('1cc8667014381e2788a94777532a788307f38d26', @lib.revparse('1cc8667014381')) # commit + assert_equal('94c827875e2cadb8bc8d4cdd900f19aa9e8634c7', @lib.revparse('1cc8667014381^{tree}')) #tree + assert_equal('ba492c62b6227d7f3507b4dcc6e6d5f13790eabf', @lib.revparse('v2.5:example.txt')) #blob + end + + def test_object_type + assert_equal('commit', @lib.object_type('1cc8667014381')) # commit + assert_equal('tree', @lib.object_type('1cc8667014381^{tree}')) #tree + assert_equal('blob', @lib.object_type('v2.5:example.txt')) #blob + assert_equal('commit', @lib.object_type('v2.5')) + end + + def test_object_size + assert_equal(265, @lib.object_size('1cc8667014381')) # commit + assert_equal(72, @lib.object_size('1cc8667014381^{tree}')) #tree + assert_equal(128, @lib.object_size('v2.5:example.txt')) #blob + assert_equal(265, @lib.object_size('v2.5')) + end + + def test_object_contents + commit = "tree 94c827875e2cadb8bc8d4cdd900f19aa9e8634c7\n" + commit += "parent 546bec6f8872efa41d5d97a369f669165ecda0de\n" + commit += "author scott Chacon 1194561188 -0800\n" + commit += "committer scott Chacon 1194561188 -0800\n" + commit += "\ntest" + assert_equal(commit, @lib.object_contents('1cc8667014381')) # commit + + tree = "040000 tree 6b790ddc5eab30f18cabdd0513e8f8dac0d2d3ed\tex_dir\n" + tree += "100644 blob 3aac4b445017a8fc07502670ec2dbf744213dd48\texample.txt" + assert_equal(tree, @lib.object_contents('1cc8667014381^{tree}')) #tree + + blob = "1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n2" + assert_equal(blob, @lib.object_contents('v2.5:example.txt')) #blob + + end + + # returns Git::Branch object array + def test_branches_all + branches = @lib.branches_all + assert(branches.size > 0) + assert(branches.select { |b| b.current }.size > 0) # has a current branch + assert(branches.select { |b| b.remote }.size > 0) # has a remote branch + assert(branches.select { |b| !b.remote }.size > 0) # has a local branch + assert(branches.select { |b| b.name == 'master' }.size > 0) # has a master branch + end + + def test_config_remote + config = @lib.config_remote('working') + assert_equal('../working.git', config['url']) + assert_equal('+refs/heads/*:refs/remotes/working/*', config['fetch']) + end + + # options this will accept + # :treeish + # :path_limiter + # :ignore_case (bool) + # :invert_match (bool) + def test_grep + match = @lib.grep('search', :object => 'gitsearch1') + assert_equal('to search one', match['gitsearch1:scott/text.txt'].assoc(6)[1]) + assert_equal(2, match['gitsearch1:scott/text.txt'].size) + assert_equal(2, match.size) + + match = @lib.grep('search', :object => 'gitsearch1', :path_limiter => 'scott/new*') + assert_equal("you can't search me!", match["gitsearch1:scott/newfile"].first[1]) + assert_equal(1, match.size) + + match = @lib.grep('SEARCH', :object => 'gitsearch1') + assert_equal(0, match.size) + + match = @lib.grep('SEARCH', :object => 'gitsearch1', :ignore_case => true) + assert_equal("you can't search me!", match["gitsearch1:scott/newfile"].first[1]) + assert_equal(2, match.size) + + match = @lib.grep('search', :object => 'gitsearch1', :invert_match => true) + assert_equal(6, match['gitsearch1:scott/text.txt'].size) + assert_equal(2, match.size) + end + +end \ No newline at end of file diff --git a/tests/units/test_log.rb b/tests/units/test_log.rb index 770c245..b62c544 100644 --- a/tests/units/test_log.rb +++ b/tests/units/test_log.rb @@ -32,19 +32,19 @@ class TestLog < Test::Unit::TestCase end def test_get_log_since_file - l = @git.log.file('example.txt') + l = @git.log.object('example.txt') assert_equal(30, l.size) - l = @git.log.between('v2.5').file('example.txt') + l = @git.log.between('v2.5').object('example.txt') assert_equal(2, l.size) - l = @git.log.between('v2.5', 'test').file('example.txt') + l = @git.log.between('v2.5', 'test').object('example.txt') assert_equal(1, l.size) end def test_log_file_noexist assert_raise Git::GitExecuteError do - @git.log.file('no-exist.txt').size + @git.log.object('no-exist.txt').size end end diff --git a/tests/units/test_object.rb b/tests/units/test_object.rb index 44bfc57..df565d5 100644 --- a/tests/units/test_object.rb +++ b/tests/units/test_object.rb @@ -76,4 +76,21 @@ class TestObject < Test::Unit::TestCase assert_equal('1f09f2edb9c0d9275d15960771b363ca6940fbe3', sha) end + def test_grep + g = @git.tree('a3db7143944dcfa0').grep('search') # there + assert_equal(3, g.to_a.flatten.size) + assert_equal(1, g.size) + + assert_equal({}, @git.tree('a3db7143944dcfa0').grep('34a566d193')) # not there + + g = @git.commit('gitsearch1').grep('search') # there + assert_equal(8, g.to_a.flatten.size) + assert_equal(2, g.size) + + g = @git.commit('gitsearch1').grep('search', 'scott/new*') # there + assert_equal(3, g.to_a.flatten.size) + assert_equal(1, g.size) + end + + end \ No newline at end of file -- cgit