]> Sergey Matveev's repositories - public-inbox.git/commitdiff
import: switch to "replace_oids" interface for purge
authorEric Wong (Contractor, The Linux Foundation) <e@80x24.org>
Sun, 9 Jun 2019 02:51:39 +0000 (02:51 +0000)
committerEric Wong <e@80x24.org>
Sun, 9 Jun 2019 04:33:16 +0000 (04:33 +0000)
Continuing the work by Eric Biederman in commit a118d58a402bd31b
("Import.pm: When purging replace a purged file with a zero length file"),
we can use a generic OID replacement mechanism to implement
purge.

lib/PublicInbox/Import.pm
lib/PublicInbox/V2Writable.pm

index 6ee1935e6f8bbd1900500698674ee9b8fdcf37be..2c8fe848fc606c0461b5b5d349015daeb239d55b 100644 (file)
@@ -501,16 +501,16 @@ sub clean_purge_buffer {
        }
 }
 
-sub purge_oids {
-       my ($self, $purge) = @_;
-       my $tmp = "refs/heads/purge-".((keys %$purge)[0]);
+sub replace_oids {
+       my ($self, $replace) = @_; # oid => raw string
+       my $tmp = "refs/heads/replace-".((keys %$replace)[0]);
        my $old = $self->{'ref'};
        my $git = $self->{git};
        my @export = (qw(fast-export --no-data --use-done-feature), $old);
        my $rd = $git->popen(@export);
        my ($r, $w) = $self->gfi_start;
        my @buf;
-       my $npurge = 0;
+       my $nreplace = 0;
        my @oids;
        my ($done, $mark);
        my $tree = $self->{-tree};
@@ -533,10 +533,13 @@ sub purge_oids {
                } elsif (/^M 100644 ([a-f0-9]+) (\w+)/) {
                        my ($oid, $path) = ($1, $2);
                        $tree->{$path} = 1;
-                       if ($purge->{$oid}) {
+                       my $sref = $replace->{$oid};
+                       if (defined $sref) {
                                push @oids, $oid;
-                               my $cmd = "M 100644 inline $path\ndata 0\n\n";
-                               push @buf, $cmd;
+                               my $n = length($$sref);
+                               push @buf, "M 100644 inline $path\ndata $n\n";
+                               push @buf, $$sref; # hope CoW works...
+                               push @buf, "\n";
                        } else {
                                push @buf, $_;
                        }
@@ -549,7 +552,7 @@ sub purge_oids {
                                $out =~ s/^/# /sgm;
                                warn "purge rewriting\n", $out, "\n";
                                clean_purge_buffer(\@oids, \@buf);
-                               $npurge++;
+                               $nreplace++;
                        }
                        $w->print(@buf, "\n") or wfail;
                        @buf = ();
@@ -567,28 +570,30 @@ sub purge_oids {
                $w->print(@buf) or wfail;
        }
        die 'done\n not seen from fast-export' unless $done;
-       chomp(my $cmt = $self->get_mark(":$mark")) if $npurge;
+       chomp(my $cmt = $self->get_mark(":$mark")) if $nreplace;
        $self->{nchg} = 0; # prevent _update_git_info until update-ref:
        $self->done;
        my @git = ('git', "--git-dir=$git->{git_dir}");
 
-       run_die([@git, qw(update-ref), $old, $tmp]) if $npurge;
+       run_die([@git, qw(update-ref), $old, $tmp]) if $nreplace;
 
        run_die([@git, qw(update-ref -d), $tmp]);
 
-       return if $npurge == 0;
+       return if $nreplace == 0;
 
        run_die([@git, qw(-c gc.reflogExpire=now gc --prune=all)]);
+
+       # check that old OIDs are gone
        my $err = 0;
-       foreach my $oid (keys %$purge) {
+       foreach my $oid (keys %$replace) {
                my @info = $git->check($oid);
                if (@info) {
-                       warn "$oid not purged\n";
+                       warn "$oid not replaced\n";
                        $err++;
                }
        }
        _update_git_info($self, 0);
-       die "Failed to purge $err object(s)\n" if $err;
+       die "Failed to replace $err object(s)\n" if $err;
        $cmt;
 }
 
index a435814a371fc88a54f47871fa8b284326e77947..d6f72b07e756f7b5b2206e6e5fa1f05be77b4a04 100644 (file)
@@ -298,7 +298,7 @@ sub idx_init {
 }
 
 sub purge_oids ($$) {
-       my ($self, $purge) = @_; # $purge = { $object_id => 1, ... }
+       my ($self, $purge) = @_; # $purge = { $object_id => \'', ... }
        $self->done;
        my $pfx = "$self->{-inbox}->{mainrepo}/git";
        my $purges = [];
@@ -313,7 +313,7 @@ sub purge_oids ($$) {
                -d $git_dir or next;
                my $git = PublicInbox::Git->new($git_dir);
                my $im = $self->import_init($git, 0, 1);
-               $purges->[$i] = $im->purge_oids($purge);
+               $purges->[$i] = $im->replace_oids($purge);
                $im->done;
        }
        $purges;
@@ -386,7 +386,7 @@ sub remove_internal ($$$$) {
                        $removed = $smsg;
                        my $oid = $smsg->{blob};
                        if ($purge) {
-                               $purge->{$oid} = 1;
+                               $purge->{$oid} = \'';
                        } else {
                                ($mark, undef) = $im->remove($orig, $cmt_msg);
                        }