2009-12-09

PreAnnouncing the in-progress Git::PurePerl::CommitBuilder

When I blogged about how to create commits raw with git, it was really a prelude to show why I'm in progress of writing a simple API to do all the hard repetitive stuff, as well as clarify in my mind what was really necessary, so as to write a logical front-end for it.


The basic synopis example I propose will work like this:


use Git::PurePerl::CommitBuilder;

my $commitBuilder = Git::PurePerl::CommitBuilder->new(
repository => '/some/path/to/repository', # will use /some/path/to/repository/.git
auto_init => 1 # init the repository if it does not exist, without this, it will die.
);

my $commit = $commitBuilder->new_commit(
author => 'Bob Smooth',
email => 'bob@smooth.example.org',
parent => $commitBuilder->branch('SomeBranchName'),
);

$commit->add_file( name => "Foo.txt" , content => "This is the content of Foo.txt");

$commit->write(
timestamp => DateTime->now(),
branch => 'SomeBranchName', # write the commit to the top of this branch
update_head => 0 , # default.
message => "This is my first commit, I R a noob",
);

This would produce a file layout as such ( after checking it out ):

/some/path/to/repository/Foo.txt


This would be your average usecase. This enables you to add/update files and commit them to the branch, but leaving everything else intact.

Initially, supporting 'parent =>' will be limited to the commit-hash lookup so as not to discard history, and won't actually preserve any files from the previous commit in the new one. ( it will be as if the tip was rm ./* and then added files to for every commit, yeilding huge diffs ).

Although this is ideal for my use, its probably less practical for everyone else.


my $commit = $commitBuilder->new_commit(
author => 'Bob Smooth',
email => 'bob@smooth.example.org',
parent => $commitBuilder->branch('SomeBranchName'),
empty => 1
);


Will later be required to form empty-tree based commits.


$commit->delete_file( name => "Foo.txt" );
$commit->delete_dir( name => "Bar" );
$commit->get_content( file => "Foo.txt");


I'm still ambivalent how we'll support directories, they're a complicated issue.

This is how it might look:

# String name == split on delimiters
$code->add_file( name => 'path/relative/to/base/here', content => "Hello" );
# ArrayRef name = rightmost token = file.
$code->add_file( name => [qw( path relative to base here )], content => "Hello" );
# Support scalar refs too for people who want them.
$code->add_file( name => [qw( path relative to base here )], content => \"Hello" );
# Read the content from a filehandle.
open my $fh, '<', 'TheFile.txt'; $code->add_file( name => [qw( path relative to base here )], read => $fh );
# Read the content from a file by name
$code->add_file( name => [qw( path relative to base here )], read => 'TheFile.txt' );


But I worry about path/file disambiguation qualms. I can't just cheat here and offload it on the filesystem. I feel like being worried about this means I'm doing something wrong, but I can't place why.

This is a notion I'm toying with for clarity:

$code->add_file( name => 'Foo', in => 'some/path/here' ... );
$code->add_file( name => 'Foo', in => [qw( some path here )] );


That very last one would make implementation of certain things easier.

I guess people can speak up and tell me what they like, and what sucks =)

No comments:

Post a Comment