]> Sergey Matveev's repositories - public-inbox.git/blobdiff - script/public-inbox-convert
v2: support incremental indexing + purge
[public-inbox.git] / script / public-inbox-convert
index e6fb4f5f3cb11868e9ad72092bfc5bcce7faa0ec..9aa27814d4538a28c75c513d3b90a7e825714767 100755 (executable)
@@ -5,9 +5,10 @@ use strict;
 use warnings;
 use Getopt::Long qw(:config gnu_getopt no_ignore_case auto_abbrev);
 use PublicInbox::MIME;
-use PublicInbox::Inbox;
+use PublicInbox::InboxWritable;
 use PublicInbox::Config;
 use PublicInbox::V2Writable;
+use PublicInbox::Import;
 use PublicInbox::Spawn qw(spawn);
 use Cwd 'abs_path';
 my $usage = "Usage: public-inbox-convert OLD NEW\n";
@@ -39,16 +40,28 @@ unless ($old) {
        };
        $old = PublicInbox::Inbox->new($old);
 }
+$old = PublicInbox::InboxWritable->new($old);
 if (($old->{version} || 1) >= 2) {
        die "Only conversion from v1 inboxes is supported\n";
 }
 my $new = { %$old };
 delete $new->{altid}; # TODO: support altid for v2
-$new->{mainrepo} = $new_dir;
+$new->{mainrepo} = abs_path($new_dir);
 $new->{version} = 2;
-$new = PublicInbox::Inbox->new($new);
-my $v2w = PublicInbox::V2Writable->new($new, 1);
-$v2w->init_inbox($jobs);
+$new = PublicInbox::InboxWritable->new($new);
+my $v2w;
+$old->umask_prepare;
+$old->with_umask(sub {
+       local $ENV{GIT_CONFIG} = "$old->{mainrepo}/config";
+       $v2w = PublicInbox::V2Writable->new($new, 1);
+       $v2w->init_inbox($jobs);
+       chomp(my $sr = $old->git->qx('config', 'core.sharedRepository'));
+       if ($sr ne '') {
+               PublicInbox::Import::run_die(['git', 'config',
+                       "--file=$new->{mainrepo}/all.git/config",
+                       'core.sharedRepository', $sr]);
+       }
+});
 my $state = '';
 my ($prev, $from);
 my $head = $old->{ref_head} || 'HEAD';
@@ -58,6 +71,7 @@ my $im = $v2w->importer;
 my ($r, $w) = $im->gfi_start;
 my $h = '[0-9a-f]';
 my %D;
+my $last;
 while (<$rd>) {
        if ($_ eq "blob\n") {
                $state = 'blob';
@@ -77,13 +91,21 @@ while (<$rd>) {
                if (m{^M 100644 :(\d+) (${h}{2}/${h}{38})}o) {
                        my ($mark, $path) = ($1, $2);
                        $D{$path} = $mark;
+                       if ($last && $last ne 'm') {
+                               $w->print("D $last\n") or $im->wfail;
+                       }
                        $w->print("M 100644 :$mark m\n") or $im->wfail;
+                       $last = 'm';
                        next;
                }
                if (m{^D (${h}{2}/${h}{38})}o) {
                        my $mark = delete $D{$1};
                        defined $mark or die "undeleted path: $1\n";
-                       $w->print("M 100644 :$mark _/D\n") or $im->wfail;
+                       if ($last && $last ne 'd') {
+                               $w->print("D $last\n") or $im->wfail;
+                       }
+                       $w->print("M 100644 :$mark d\n") or $im->wfail;
+                       $last = 'd';
                        next;
                }
                if (m{^from (:\d+)}) {
@@ -103,6 +125,6 @@ my $mm = $old->mm;
 $mm->{dbh}->sqlite_backup_to_file("$new_dir/msgmap.sqlite3") if $mm;
 $v2w->done;
 if ($index) {
-       $v2w->reindex;
+       $v2w->index_sync;
        $v2w->done;
 }