git-svn: track writes writes to the index in fetch
authorEric Wong <normalperson@yhbt.net>
Wed, 24 Jan 2007 11:30:57 +0000 (03:30 -0800)
committerEric Wong <normalperson@yhbt.net>
Fri, 23 Feb 2007 08:57:10 +0000 (00:57 -0800)
Introducing Git::IndexInfo.  This module will probably be useful
outside of git-svn, so I'm not putting it in the Git::SVN
namespace.

This will allow me to more easily avoid the use of get_log() in
the future and simply run do_update in incrementing ranges.
get_log() should be avoided because there are cases where
moved/deleted directories do not track correctly (until
--follow-parent is run on a new branch).

Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn.perl

index 123d4d63f425739b59e18f66577e529419cb94ed..a19afb83fbb9e7424cf6783dd1665d19f8c79f6b 100755 (executable)
@@ -1643,8 +1643,7 @@ sub new {
        $self->{file_prop} = {};
        $self->{absent_dir} = {};
        $self->{absent_file} = {};
-       ($self->{gui}, $self->{ctx}) = $git_svn->tmp_index_do(
-              sub { command_input_pipe(qw/update-index -z --index-info/) } );
+       $self->{gii} = $git_svn->tmp_index_do(sub { Git::IndexInfo->new });
        require Digest::MD5;
        $self;
 }
@@ -1671,7 +1670,6 @@ sub git_path {
 
 sub delete_entry {
        my ($self, $path, $rev, $pb) = @_;
-       my $gui = $self->{gui};
 
        my $gpath = $self->git_path($path);
        # remove entire directories.
@@ -1681,14 +1679,15 @@ sub delete_entry {
                                                     $self->{c}, '--', $gpath);
                local $/ = "\0";
                while (<$ls>) {
-                       print $gui '0 ',0 x 40,"\t",$_ or croak $!;
+                       chomp;
+                       $self->{gii}->remove($_);
                        print "\tD\t$_\n" unless $self->{q};
                }
                print "\tD\t$gpath/\n" unless $self->{q};
                command_close_pipe($ls, $ctx);
                $self->{empty}->{$path} = 0
        } else {
-               print $gui '0 ',0 x 40,"\t",$gpath,"\0" or croak $!;
+               $self->{gii}->remove($gpath);
                print "\tD\t$gpath\n" unless $self->{q};
        }
        undef;
@@ -1824,22 +1823,23 @@ sub close_file {
                $hash = $fb->{blob} or die "no blob information\n";
        }
        $fb->{pool}->clear;
-       my $gui = $self->{gui};
-       print $gui "$fb->{mode_b} $hash\t$path\0" or croak $!;
+       $self->{gii}->update($fb->{mode_b}, $hash, $path) or croak $!;
        print "\t$fb->{action}\t$path\n" if $fb->{action} && ! $self->{q};
        undef;
 }
 
 sub abort_edit {
        my $self = shift;
-       eval { command_close_pipe($self->{gui}, $self->{ctx}) };
+       $self->{nr} = $self->{gii}->{nr};
+       delete $self->{gii};
        $self->SUPER::abort_edit(@_);
 }
 
 sub close_edit {
        my $self = shift;
-       command_close_pipe($self->{gui}, $self->{ctx});
        $self->{git_commit_ok} = 1;
+       $self->{nr} = $self->{gii}->{nr};
+       delete $self->{gii};
        $self->SUPER::close_edit(@_);
 }
 
@@ -2832,6 +2832,38 @@ sub migration_check {
        minimize_connections() if $_minimize;
 }
 
+package Git::IndexInfo;
+use strict;
+use warnings;
+use Git qw/command_input_pipe command_close_pipe/;
+
+sub new {
+       my ($class) = @_;
+       my ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);
+       bless { gui => $gui, ctx => $ctx, nr => 0}, $class;
+}
+
+sub remove {
+       my ($self, $path) = @_;
+       if (print { $self->{gui} } '0 ', 0 x 40, "\t", $path, "\0") {
+               return ++$self->{nr};
+       }
+       undef;
+}
+
+sub update {
+       my ($self, $mode, $hash, $path) = @_;
+       if (print { $self->{gui} } $mode, ' ', $hash, "\t", $path, "\0") {
+               return ++$self->{nr};
+       }
+       undef;
+}
+
+sub DESTROY {
+       my ($self) = @_;
+       command_close_pipe($self->{gui}, $self->{ctx});
+}
+
 __END__
 
 Data structures: