зеркало из https://github.com/github/grit.git
merged recent changes:
* accepts relative alt paths * orders tree writes properly * can init a git repo
This commit is contained in:
Родитель
f0ce7d5979
Коммит
0f87b4d902
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче