summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscott Chacon <schacon@agadorsparticus.(none)>2007-11-16 11:23:24 -0800
committerscott Chacon <schacon@agadorsparticus.(none)>2007-11-16 11:23:24 -0800
commitde071dcd8dee3d853291a5077b9dcdec07dd5362 (patch)
treebd335c0a79ed4da9fc4c05b2f44542a03a2d3b5d
parent3687e45effe8ad433da31712149b424d46effe64 (diff)
downloadthird_party-ruby-git-de071dcd8dee3d853291a5077b9dcdec07dd5362.tar.gz
third_party-ruby-git-de071dcd8dee3d853291a5077b9dcdec07dd5362.tar.xz
third_party-ruby-git-de071dcd8dee3d853291a5077b9dcdec07dd5362.zip
added some low level tree operations and tests
-rw-r--r--lib/git.rb2
-rw-r--r--lib/git/base.rb72
-rw-r--r--lib/git/index.rb1
-rw-r--r--lib/git/lib.rb26
-rw-r--r--lib/git/path.rb4
-rw-r--r--tests/units/test_tree_ops.rb106
6 files changed, 209 insertions, 2 deletions
diff --git a/lib/git.rb b/lib/git.rb
index b1d55af..f18ad11 100644
--- a/lib/git.rb
+++ b/lib/git.rb
@@ -40,7 +40,7 @@ require 'git/author'
# License:: MIT License
module Git
- VERSION = '1.0.2'
+ VERSION = '1.0.3'
# open a bare repository
#
diff --git a/lib/git/base.rb b/lib/git/base.rb
index 4e1e125..6372beb 100644
--- a/lib/git/base.rb
+++ b/lib/git/base.rb
@@ -90,6 +90,17 @@ module Git
@index
end
+
+ def set_working(work_dir, check = true)
+ @lib = nil
+ @working_directory = Git::WorkingDirectory.new(work_dir.to_s, check)
+ end
+
+ def set_index(index_file, check = true)
+ @lib = nil
+ @index = Git::Index.new(index_file.to_s, check)
+ end
+
# changes current working directory for a block
# to the git working directory
#
@@ -186,7 +197,7 @@ module Git
# actual 'git' forked system calls. At some point I hope to replace the Git::Lib
# class with one that uses native methods or libgit C bindings
def lib
- Git::Lib.new(self)
+ @lib ||= Git::Lib.new(self)
end
# will run a grep for 'string' on the HEAD of the git repository
@@ -330,6 +341,65 @@ module Git
self.lib.repack
end
+
+ ## LOWER LEVEL INDEX OPERATIONS ##
+
+ def with_index(new_index)
+ old_index = @index
+ set_index(new_index, false)
+ return_value = yield @index
+ set_index(old_index)
+ return_value
+ end
+
+ def with_temp_index &blk
+ tempfile = Tempfile.new('temp-index')
+ temp_path = tempfile.path
+ tempfile.unlink
+ with_index(temp_path, &blk)
+ end
+
+ def read_tree(treeish, opts = {})
+ self.lib.read_tree(treeish, opts)
+ end
+
+ def write_tree
+ self.lib.write_tree
+ end
+
+ def commit_tree(tree = nil, opts = {})
+ Git::Object::Commit.new(self, self.lib.commit_tree(tree, opts))
+ end
+
+ def write_and_commit_tree(opts = {})
+ tree = write_tree
+ commit_tree(tree, opts)
+ end
+
+ def ls_files
+ self.lib.ls_files
+ end
+
+ def with_working(work_dir)
+ return_value = false
+ old_working = @working_directory
+ set_working(work_dir)
+ Dir.chdir work_dir do
+ return_value = yield @working_directory
+ end
+ set_working(old_working)
+ return_value
+ end
+
+ def with_temp_working &blk
+ tempfile = Tempfile.new("temp-workdir")
+ temp_dir = tempfile.path
+ tempfile.unlink
+ Dir.mkdir(temp_dir, 0700)
+ with_working(temp_dir, &blk)
+ end
+
+
# runs git rev-parse to convert the objectish to a full sha
#
# @git.revparse("HEAD^^")
diff --git a/lib/git/index.rb b/lib/git/index.rb
index b96eedb..c27820d 100644
--- a/lib/git/index.rb
+++ b/lib/git/index.rb
@@ -1,4 +1,5 @@
module Git
class Index < Git::Path
+
end
end
diff --git a/lib/git/lib.rb b/lib/git/lib.rb
index c196312..690043d 100644
--- a/lib/git/lib.rb
+++ b/lib/git/lib.rb
@@ -350,6 +350,32 @@ module Git
command('repack', ['-a', '-d'])
end
+ # reads a tree into the current index file
+ def read_tree(treeish, opts = {})
+ arr_opts = []
+ arr_opts << "--prefix=#{opts[:prefix]}" if opts[:prefix]
+ arr_opts << treeish.to_a.join(' ')
+ command('read-tree', arr_opts)
+ end
+
+ def write_tree
+ command('write-tree')
+ end
+
+ def commit_tree(tree, opts = {})
+ opts[:message] = "commit tree #{tree}" if !opts[:message]
+ t = Tempfile.new('commit-message') do |t|
+ t.write(opts[:message])
+ end
+
+ arr_opts = []
+ arr_opts << tree
+ arr_opts << "-p #{opts[:parent]}" if opts[:parent]
+ opts[:parents].each { |p| arr_opts << "-p #{p.to_s}" } if opts[:parents]
+ arr_opts << "< #{t.path}"
+ command('commit-tree', arr_opts)
+ end
+
# creates an archive file
#
# options
diff --git a/lib/git/path.rb b/lib/git/path.rb
index e429d6f..87f5c84 100644
--- a/lib/git/path.rb
+++ b/lib/git/path.rb
@@ -19,5 +19,9 @@ module Git
File.writable?(@path)
end
+ def to_s
+ @path
+ end
+
end
end \ No newline at end of file
diff --git a/tests/units/test_tree_ops.rb b/tests/units/test_tree_ops.rb
new file mode 100644
index 0000000..7dba642
--- /dev/null
+++ b/tests/units/test_tree_ops.rb
@@ -0,0 +1,106 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class TestTreeOps < Test::Unit::TestCase
+
+ def setup
+ set_file_paths
+ @git = Git.open(@wdir)
+ end
+
+ def test_read_tree
+
+ in_temp_dir do
+ g = Git.clone(@wbare, 'test')
+
+ g.chdir do
+ g.branch('testbranch1').in_branch('tb commit 1') do
+ new_file('test-file1', 'blahblahblah2')
+ g.add
+ true
+ end
+
+ g.branch('testbranch2').in_branch('tb commit 2') do
+ new_file('test-file2', 'blahblahblah3')
+ g.add
+ true
+ end
+
+ g.branch('testbranch3').in_branch('tb commit 3') do
+ new_file('test-file3', 'blahblahblah4')
+ g.add
+ true
+ end
+
+ # test some read-trees
+ tr = g.with_temp_index do
+ g.read_tree('testbranch1')
+ g.read_tree('testbranch2', :prefix => 'b2/')
+ g.read_tree('testbranch3', :prefix => 'b2/b3/')
+ index = g.ls_files
+ assert(index['b2/test-file2'])
+ assert(index['b2/b3/test-file3'])
+ g.write_tree
+ end
+
+ assert_equal('2423ef1b38b3a140bbebf625ba024189c872e08b', tr)
+
+ # only prefixed read-trees
+ tr = g.with_temp_index do
+ g.add # add whats in our working tree
+ g.read_tree('testbranch1', :prefix => 'b1/')
+ g.read_tree('testbranch3', :prefix => 'b2/b3/')
+ index = g.ls_files
+ assert(index['example.txt'])
+ assert(index['b1/test-file1'])
+ assert(!index['b2/test-file2'])
+ assert(index['b2/b3/test-file3'])
+ g.write_tree
+ end
+
+ assert_equal('aa7349e1cdaf4b85cc6a6a0cf4f9b3f24879fa42', tr)
+
+ # new working directory too
+ tr = nil
+ g.with_temp_working do
+ tr = g.with_temp_index do
+ assert_raises Git::GitExecuteError do
+ g.add # add whats in our working tree - should be nothing
+ end
+ g.read_tree('testbranch1', :prefix => 'b1/')
+ g.read_tree('testbranch3', :prefix => 'b1/b3/')
+ index = g.ls_files
+ assert(!index['example.txt'])
+ assert(index['b1/test-file1'])
+ assert(!index['b2/test-file2'])
+ assert(index['b1/b3/test-file3'])
+ g.write_tree
+ end
+ assert_equal('b40f7a9072cdec637725700668f8fdebe39e6d38', tr)
+ end
+
+ c = g.commit_tree(tr, :parents => 'HEAD')
+ assert(c.commit?)
+ assert_equal('b40f7a9072cdec637725700668f8fdebe39e6d38', c.gtree.sha)
+
+ tmp = Tempfile.new('tesxt')
+ tmppath = tmp.path
+ tmp.unlink
+ tr2 = g.with_index(tmppath) do
+ g.read_tree('testbranch1', :prefix => 'b1/')
+ g.read_tree('testbranch3', :prefix => 'b3/')
+ index = g.ls_files
+ assert(!index['b2/test-file2'])
+ assert(index['b3/test-file3'])
+ g.commit('hi')
+ end
+
+ assert(c.commit?)
+ assert_equal('b40f7a9072cdec637725700668f8fdebe39e6d38', c.gtree.sha)
+
+ end
+ end
+ end
+
+end