[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby/Git?

Andre Nathan

9/27/2006 6:33:00 PM

Hi

I've been working with subversion for some time now and thought I'd have
a look at trying one of the distributed SCMs. I read about many of them,
and ended up with a choice between mercurial and git.

Since both seem to be quite similar, and mercurial is written in python,
I was wondering if someone is working (or at least thinking of) writing
ruby wrappers for git, so we could get rid of the stinky shell scripts
from cogito.

Any git users here at all? I wonder if there's a libgit that could be
wrapped in an extension...

Regards,
Andre


4 Answers

Bil Kleb

9/27/2006 7:07:00 PM

0

Andre Nathan wrote:
> Hi

Hi.

> Any git users here at all? I wonder if there's a libgit that could be
> wrapped in an extension...

Check out the bottom figure caption of Why's shiny new page:

http://code.whythelucky...

Later,
--
Bil Kleb
http://fun3d.lar...

Andre Nathan

9/27/2006 7:56:00 PM

0

On Thu, 2006-09-28 at 04:20 +0900, Bil Kleb wrote:

> Check out the bottom figure caption of Why's shiny new page:

Yeah, I saw that... well at least he didn't have to wait the 2 centuries
it takes to compile Monotone...

Andre


Christian Neukirchen

9/27/2006 8:31:00 PM

0

Andre Nathan <andre@digirati.com.br> writes:

> I've been working with subversion for some time now and thought I'd have
> a look at trying one of the distributed SCMs. I read about many of them,
> and ended up with a choice between mercurial and git.
>
> Since both seem to be quite similar, and mercurial is written in python,
> I was wondering if someone is working (or at least thinking of) writing
> ruby wrappers for git, so we could get rid of the stinky shell scripts
> from cogito.
>
> Any git users here at all? I wonder if there's a libgit that could be
> wrapped in an extension...

I gave it a try some months ago, but lost interest.


require 'dl/import'
require 'dl/struct'

module Git
extend DL::Importable

dlload "/Users/chris/src/git/libgit.bundle"

extern "const char *setup_git_directory()"

extern "int git_config (void*)"
# extern "int git_default_config (const char *, const char *)"

extern "int get_sha1 (const char *, unsigned char *)"

extern "void *parse_tree_indirect(const unsigned char *)"

extern "int read_tree_recursive(void*, const char*, int, int, const char*, void*)"
# extern "int read_tree_recursive(void*, int, int, int, int, void*)"

extern "int sha1_object_info(const unsigned char*, void*, long*)"
extern "void* read_sha1_file(const unsigned char*, void*, long*)"

extern "int index_fd(unsigned char *, int, void *, int, const char *)"
extern "int index_pipe(unsigned char *, int, int, const char *)"

extern "void* parse_object(const unsigned char *)"


Object = struct [
"long flags",
"char sha1[20]",
]

TreeStruct = struct [
"void *object",
"void *buffer",
"long size",
]

def self.config
git_config(symbol('git_default_config', 'ISS'))
end

def self.hash_object(thing, type="blob")
buf = DL.malloc(20)

if thing.kind_of? String # filename
rstat = File.stat thing
stat = DL::PtrData.new(rstat.object_id*2).to_a('P', 5).last
file = File.open(thing)
index_fd(buf, file.fileno, stat, 0, type) # will close
elsif thing.kind_of? IO
index_pipe(buf, thing.fileno, 0, type)
else
raise "Can't hash #{thing}"
end
SHA1.new buf.to_s(20)
end

class Commit
def initialize(string)
replace string
end

def replace(string)
head, @body = string.split("\n\n", 2)

@fields = {}
head.each { |line|
field, value = line.chomp.split(" ", 2)

if field == "tree" || field == "parent"
value = SHA1[value]
end

if field == "parent"
(@fields[field] ||= []) << value
else
@fields[field] = value
end
}
end

def title
@body[/.*/]
end

def [](field)
@fields[field]
end
end

class SHA1
attr_reader :data

def self.[](str)
if str.size == 20
new str
elsif str.size == 40
p str
new [str].pack("H*")
else
raise "Can't make hash object from #{str}"
end
end

def initialize(sha = '\0'*20)
@data = sha
end

def inspect
type
"#<%s:0x%x %s %s(%d)>" % [self.class.name, object_id, type, to_s, @size]
end

def to_s
@data.unpack("C*").map { |byte| "%02x" % byte }.join
end

def type
buf = DL.malloc(16)
buf2 = DL.malloc(4)
Git.sha1_object_info(@data, buf, buf2)
@size = buf2.to_s(4).unpack("L").first
@type = buf.to_s
end

def read
buf = DL.malloc(16)
buf2 = DL.malloc(4)
buf3 = Git.read_sha1_file(@data, buf, buf2)
@size = buf2.to_s(4).unpack("L").first
@type = buf.to_s
data = buf3.to_s(@size)

case @type
when "commit"
Commit.new data
else
raise "Can't deal with #{@type} yet."
end
end

def size
type
@size
end

def parse
obj = Git.parse_object @data
Object.new obj
end
end

class Tree
def initialize(sha1)
@tree = TreeStruct.new Git.parse_tree_indirect(sha1.data)
end

READ_TREE = DL.callback("IPPIPII") {
|sha1, base, baselen, pathname, mode, stage|
s = Git::SHA1.new(sha1.to_s(20))

if base
path = base.to_s(baselen)
else
path = ""
end
path << pathname.to_s

id = path.slice!(0, 4).unpack("L").first
block = ObjectSpace._id2ref(id & ~1)

block.call [s, path, mode, stage]
id & 1
}

def each(recursive=false, &block)
Git.read_tree_recursive(@tree, [block.object_id | (recursive ? 1 : 0)].
pack("L"), 4, 0, nil, READ_TREE)
end
end

def self.sha1(name)
buffer = DL.malloc(20)
# p buffer.to_s(20)
get_sha1(name, buffer)
SHA1.new buffer.to_s(20)
end

def self.parse_tree(sha)
Tree.new parse_tree_indirect(sha.data)
end
end

Dir.chdir(File.expand_path("~/src/git")) {
p Git.setup_git_directory
p Git.config

x = Git.sha1("HEAD")
p x
p x.type
commit = x.read

while commit['parent']
p commit.title
commit = commit['parent'].first.read
end

Git::Tree.new(x).each { |sh1, file|
p [sh1, Git::SHA1.new(sh1.parse.sha1.pack("c*"))]
p file
}
}

__END__
x=Time.now
Dir.chdir("testrep")
1000.times {
`git-hash-object Makefile`
}
p Time.now-x

__END__
head = Git.sha1("HEAD")
p head
p head.type
tree = Git.parse_tree(head)
p tree
read_tree = DL.callback("IPPIPII") {
|sha1, base, baselen, pathname, mode, stage|
s = Git::SHA1.new(sha1.to_s(20))
p s
p s.type
if base
path = base.to_s(baselen)
else
path = ""
end
path << pathname.to_s
p path
p mode.to_s(8)
p stage
1
}
p Git.read_tree_recursive(tree, 0, 0, 0, 0, read_tree)
}

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...

Christian Neukirchen

9/28/2006 12:43:00 PM

0

Andre Nathan <andre@digirati.com.br> writes:

> On Thu, 2006-09-28 at 04:20 +0900, Bil Kleb wrote:
>
>> Check out the bottom figure caption of Why's shiny new page:
>
> Yeah, I saw that... well at least he didn't have to wait the 2 centuries
> it takes to compile Monotone...

That's still nothing compared to darcs and GHC. :-)

> Andre
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...