1 # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
2 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
3 package Ssoma::Remover;
7 use Ssoma::GitIndexInfo;
10 my ($class, $git) = @_;
11 bless { git => $git, ref => "refs/heads/master" }, $class;
15 my ($self, $simple) = @_;
16 my $git = $self->{git};
18 $git->tmp_index_do(sub {
19 $self->_remove($simple);
22 $git->sync_do(sub { $git->tmp_git_do($sub) });
25 # remove an Email::Simple object from the current index
27 my ($self, $simple) = @_;
28 my $git = $self->{git};
29 my $path = $git->mid2path($simple->header("Message-ID"));
30 my $ref = $self->{ref};
31 my $tip = $git->qx_sha1("git rev-parse $ref^0");
32 my $obj = "$tip:$path";
33 my $type = $git->type($obj);
35 if ($type eq "tree") { # unlikely
36 $git->each_in_tree($obj, sub {
37 my ($blob_id, $xpath) = ($1, $2);
38 my $tmp = $git->blob_to_simple($blob_id);
39 if ($git->simple_eq($simple, $tmp)) {
40 push @remove, "$path/$xpath";
45 } elsif ($type eq "blob") { # likely
46 my $tmp = $git->blob_to_simple($obj);
47 if ($git->simple_eq($simple, $tmp)) {
51 die "unhandled type=$type for obj=$obj\n";
54 my $gii = Ssoma::GitIndexInfo->new;
55 foreach my $rm (@remove) { $gii->remove($rm) }
57 if (scalar(@keep) == 1) { # convert tree back to blob
58 my $blob_id = $keep[0];
60 $gii->update('100644', $blob_id, $path);
61 } elsif ((scalar(@keep) == 0) && ($type eq "tree")) {
62 # this is not possible unless simple_eq changes over time
64 } # else: do nothing if (@keep > 1)
67 $git->commit_index($gii, 1, $ref, 'rm');