* accepts relative alt paths
* orders tree writes properly
* can init a git repo
This commit is contained in:
Scott Chacon 2008-08-22 14:51:56 -07:00
Родитель f0ce7d5979
Коммит 0f87b4d902
10 изменённых файлов: 203 добавлений и 42 удалений

Просмотреть файл

@ -1,6 +1,5 @@
require 'grit/git-ruby/repository'
require 'grit/git-ruby/file_index'
require 'grit/git-ruby/commit_db'
module Grit
@ -11,6 +10,14 @@ module Grit
attr_accessor :ruby_git_repo, :git_file_index
def init(options)
if options.size == 0
Grit::GitRuby::Repository.init(@git_dir)
else
method_missing('init', options)
end
end
def cat_file(options, ref)
if options[:t]
file_type(ref)
@ -172,4 +179,4 @@ module Grit
# git log --pretty='raw' --max-count='1' 'master' -- 'test'
end
end
end

Просмотреть файл

@ -162,7 +162,6 @@ module Grit
pos += CrcSize
end
@size.times do |i|
puts "#{i} : #{pos}"
offset = idx[pos,OffsetSize].unpack('N')[0]
data[i][2] = offset
pos += OffsetSize

Просмотреть файл

@ -37,6 +37,7 @@ module Grit
def initialize(git_dir, options = {})
@git_dir = git_dir
@options = options
@packs = []
end
# returns the loose objects object lazily
@ -599,6 +600,53 @@ module Grit
found_data
end
# initialize a git repository
def self.init(dir, bare = false)
FileUtils.mkdir_p(dir) if !File.exists?(dir)
FileUtils.cd(dir) do
if(File.exists?('objects'))
return false # already initialized
else
# initialize directory
create_initial_config(bare)
FileUtils.mkdir_p('refs/heads')
FileUtils.mkdir_p('refs/tags')
FileUtils.mkdir_p('objects/info')
FileUtils.mkdir_p('objects/pack')
FileUtils.mkdir_p('branches')
add_file('description', 'Unnamed repository; edit this file to name it for gitweb.')
add_file('HEAD', "ref: refs/heads/master\n")
FileUtils.mkdir_p('hooks')
FileUtils.cd('hooks') do
add_file('applypatch-msg', '# add shell script and make executable to enable')
add_file('post-commit', '# add shell script and make executable to enable')
add_file('post-receive', '# add shell script and make executable to enable')
add_file('post-update', '# add shell script and make executable to enable')
add_file('pre-applypatch', '# add shell script and make executable to enable')
add_file('pre-commit', '# add shell script and make executable to enable')
add_file('pre-rebase', '# add shell script and make executable to enable')
add_file('update', '# add shell script and make executable to enable')
end
FileUtils.mkdir_p('info')
add_file('info/exclude', "# *.[oa]\n# *~")
end
end
end
def self.create_initial_config(bare = false)
bare ? bare_status = 'true' : bare_status = 'false'
config = "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = #{bare_status}\n\tlogallrefupdates = true"
add_file('config', config)
end
def self.add_file(name, contents)
File.open(name, 'w') do |f|
f.write contents
end
end
def close
@packs.each do |pack|
pack.close

Просмотреть файл

@ -1,11 +1,12 @@
module Grit
class Index
attr_accessor :repo, :tree
attr_accessor :repo, :tree, :current_tree
def initialize(repo)
self.repo = repo
self.tree = {}
self.current_tree = nil
end
# Add a file to the index
@ -28,12 +29,16 @@ module Grit
current[filename] = data
end
def read_tree(tree)
self.current_tree = self.repo.tree(tree)
end
# Commit the contents of the index
# +message+ is the commit message
#
# Returns a String of the SHA1 of the commit
def commit(message, parents = nil, actor = nil, last_tree = nil)
tree_sha1 = write_tree(self.tree)
def commit(message, parents = nil, actor = nil, last_tree = nil, head = 'master')
tree_sha1 = write_tree(self.tree, self.current_tree)
return false if tree_sha1 == last_tree # don't write identical commits
contents = []
@ -60,7 +65,7 @@ module Grit
commit_sha1 = self.repo.git.ruby_git.put_raw_object(contents.join("\n"), 'commit')
# self.repo.git.update_ref({}, 'HEAD', commit_sha1)
File.open(File.join(self.repo.path, 'refs', 'heads', 'master'), 'w') do |f|
File.open(File.join(self.repo.path, 'refs', 'heads', head), 'w') do |f|
f.write(commit_sha1)
end if commit_sha1
@ -71,23 +76,35 @@ module Grit
# +tree+ is the tree
#
# Returns the SHA1 String of the tree
def write_tree(tree)
tree_contents = ''
def write_tree(tree, now_tree = nil)
tree_contents = {}
# fill in original tree
now_tree.contents.each do |obj|
sha = [obj.id].pack("H*")
k = obj.name
k += '/' if (obj.class == Grit::Tree)
tree_contents[k] = "%s %s\0%s" % [obj.mode.to_s, obj.name, sha]
end if now_tree
# overwrite with new tree contents
tree.each do |k, v|
case v
when String:
sha = write_blob(v)
sha = [sha].pack("H*")
str = "%s %s\0%s" % ['100644', k, sha]
tree_contents += str
tree_contents[k] = str
when Hash:
sha = write_tree(v)
ctree = now_tree/k if now_tree
sha = write_tree(v, ctree)
sha = [sha].pack("H*")
str = "%s %s\0%s" % ['040000', k, sha]
tree_contents += str
tree_contents[k + '/'] = str
end
end
self.repo.git.ruby_git.put_raw_object(tree_contents, 'tree')
tr = tree_contents.sort.map { |k, v| v }.join('')
self.repo.git.ruby_git.put_raw_object(tr, 'tree')
end
# Write the blob to the index

Просмотреть файл

@ -5,6 +5,7 @@ module Grit
# The path of the git repo as a String
attr_accessor :path
attr_accessor :working_dir
attr_reader :bare
# The git command line interface object
@ -22,6 +23,7 @@ module Grit
epath = File.expand_path(path)
if File.exist?(File.join(epath, '.git'))
self.working_dir = epath
self.path = File.join(epath, '.git')
@bare = false
elsif File.exist?(epath) && (epath =~ /\.git$/ || options[:is_bare])
@ -60,6 +62,10 @@ module Grit
alias_method :branches, :heads
def is_head?(head_name)
heads.find { |h| h.name == head_name }
end
# Object reprsenting the current repo head.
#
# Returns Grit::Head (baked)

Просмотреть файл

@ -88,25 +88,27 @@ module Grit
def construct_status
@files = ls_files
# find untracked in working dir
Dir.glob('**/*') do |file|
if !@files[file]
@files[file] = {:path => file, :untracked => true} if !File.directory?(file)
Dir.chdir(@base.working_dir) do
# find untracked in working dir
Dir.glob('**/*') do |file|
if !@files[file]
@files[file] = {:path => file, :untracked => true} if !File.directory?(file)
end
end
end
# find modified in tree
diff_files.each do |path, data|
@files[path] ? @files[path].merge!(data) : @files[path] = data
end
# find modified in tree
diff_files.each do |path, data|
@files[path] ? @files[path].merge!(data) : @files[path] = data
end
# find added but not committed - new files
diff_index('HEAD').each do |path, data|
@files[path] ? @files[path].merge!(data) : @files[path] = data
end
# find added but not committed - new files
diff_index('HEAD').each do |path, data|
@files[path] ? @files[path].merge!(data) : @files[path] = data
end
@files.each do |k, file_hash|
@files[k] = StatusFile.new(@base, file_hash)
@files.each do |k, file_hash|
@files[k] = StatusFile.new(@base, file_hash)
end
end
end

Просмотреть файл

@ -28,6 +28,12 @@ class TestHead < Test::Unit::TestCase
head = @r.heads[2]
assert_equal %Q{#<Grit::Head "test/chacon">}, head.inspect
end
def test_is_head
assert @r.is_head?('master')
assert @r.is_head?('test/chacon')
assert !@r.is_head?('masterblah')
end
def test_head_count
assert_equal 5, @r.heads.size

Просмотреть файл

@ -1,4 +1,5 @@
require File.dirname(__FILE__) + '/helper'
require 'tempfile'
class TestRubyGit < Test::Unit::TestCase
@ -9,6 +10,16 @@ class TestRubyGit < Test::Unit::TestCase
@blob_sha = '4232d073306f01cf0b895864e5a5cfad7dd76fce'
end
def test_init_gitdir
tf = Tempfile.new('gitdir')
temppath = tf.path
tf.unlink
git = Git.new(temppath)
git.init({})
assert File.exists?(File.join(temppath, 'config'))
end
def test_log_merge
c1 = '420eac97a826bfac8724b6b0eef35c20922124b7'
c2 = '30e367cef2203eba2b341dc9050993b06fd1e108'

Просмотреть файл

@ -0,0 +1,76 @@
require File.dirname(__FILE__) + '/helper'
require 'pp'
class TestRubyGitIndex < Test::Unit::TestCase
def setup
@base_repo = create_temp_repo(File.join(File.dirname(__FILE__), *%w[dot_git_iv2]))
@git = Grit::Repo.new(@base_repo, :is_bare => true)
@rgit = @git.git.ruby_git
@user = Actor.from_string("Tom Werner <tom@example.com>")
end
def teardown
FileUtils.rm_r(@base_repo)
end
def create_temp_repo(clone_path)
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s.rjust(3, '0')
tmp_path = File.join("/tmp/", filename)
FileUtils.mkdir_p(tmp_path)
FileUtils.cp_r(clone_path, tmp_path)
File.join(tmp_path, 'dot_git_iv2')
end
def test_add_files
sha = @git.commits.first.tree.id
i = @git.index
i.read_tree(sha)
i.add('atester.rb', 'test stuff')
i.commit('message', [@git.commits.first], @user, nil, 'master')
b = @git.commits.first.tree/'atester.rb'
assert_equal 'f80c3b68482d5e1c8d24c9b8139340f0d0a928d0', b.id
end
def test_add_path_file
sha = @git.commits.first.tree.id
i = @git.index
i.read_tree(sha)
i.add('lib/atester.rb', 'test stuff')
i.commit('message', [@git.commits.first], @user, nil, 'master')
b = @git.commits.first.tree/'lib'/'atester.rb'
assert_equal 'f80c3b68482d5e1c8d24c9b8139340f0d0a928d0', b.id
b = @git.commits.first.tree/'lib'/'grit.rb'
assert_equal '77aa887449c28a922a660b2bb749e4127f7664e5', b.id
end
def test_ordered_properly
sha = @git.commits.first.tree.id
i = @git.index
i.read_tree(sha)
i.add('lib.rb', 'test stuff')
i.commit('message', [@git.commits.first], @user, nil, 'master')
tr = @git.commits.first.tree.contents
entries = tr.select { |c| c.name[0, 3] == 'lib' }.map { |c| c.name }
assert_equal 'lib.rb', entries[0]
assert_equal 'lib', entries[1]
end
def test_modify_file
sha = @git.commits.first.tree.id
i = @git.index
i.read_tree(sha)
i.add('README.txt', 'test more stuff')
i.commit('message', [@git.commits.first], @user, nil, 'master')
b = @git.commits.first.tree/'README.txt'
assert_equal 'e45d6b418e34951ddaa3e78e4fc4d3d92a46d3d1', b.id
end
end

Просмотреть файл

@ -7,21 +7,10 @@ class TestRubyGitIv2 < Test::Unit::TestCase
@git = Grit::Repo.new(File.join(File.dirname(__FILE__), *%w[dot_git_iv2]), :is_bare => true)
@rgit = @git.git.ruby_git
@commit_sha = 'ca8a30f5a7f0f163bbe3b6f0abf18a6c83b0687a'
@tree_sha = 'cd7422af5a2e0fff3e94d6fb1a8fff03b2841881'
@blob_sha = '4232d073306f01cf0b895864e5a5cfad7dd76fce'
@tree_sha = 'cd7422af5a2e0fff3e94d6fb1a8fff03b2841881'
@blob_sha = '4232d073306f01cf0b895864e5a5cfad7dd76fce'
end
=begin
def test_sha
i = 0
@rgit.packs[0].each_sha1 do |sha|
i += 1
sha = sha.unpack("H*")[0]
#puts "#{i} : #{sha}"
end
end
=end
def test_basic
assert @rgit.object_exists?(@commit_sha)
assert_equal 10, @git.commits.size