- while(my($path,$action) = each %$changed_paths) {
- if ($action->[0] eq "A") {
- my $f = get_file($revision,$branch,$path);
- push(@new,$f) if $f;
- } elsif ($action->[0] eq "D") {
- push(@old,$path);
- } elsif ($action->[0] eq "M") {
- my $f = get_file($revision,$branch,$path);
- push(@new,$f) if $f;
- } elsif ($action->[0] eq "R") {
- # refer to a file/tree in an earlier commit
- push(@old,$path); # remove any old stuff
-
- # ... and add any new stuff
- my($b,$p) = split_path($revision,$action->[1]);
- open my $F,"-|","git-ls-tree","-r","-z", $branches{$b}{$action->[2]}, $p;
- local $/ = '\0';
- while(<$F>) {
- chomp;
- my($m,$p) = split(/\t/,$_,2);
- my($mode,$type,$sha1) = split(/ /,$m);
- next if $type ne "blob";
- push(@new,[$mode,$sha1,$p]);
+ my $cid;
+ if($tag and not %$changed_paths) {
+ $cid = $rev;
+ } else {
+ my @paths = sort keys %$changed_paths;
+ foreach my $path(@paths) {
+ my $action = $changed_paths->{$path};
+
+ if ($action->[0] eq "A") {
+ my $f = get_file($revision,$branch,$path);
+ if($f) {
+ push(@new,$f) if $f;
+ } elsif($action->[1]) {
+ copy_subdir($revision,$branch,$path,$action->[1],$action->[2],\@new);
+ } else {
+ my $opath = $action->[3];
+ print STDERR "$revision: $branch: could not fetch '$opath'\n";
+ }
+ } elsif ($action->[0] eq "D") {
+ push(@old,$path);
+ } elsif ($action->[0] eq "M") {
+ my $f = get_file($revision,$branch,$path);
+ push(@new,$f) if $f;
+ } elsif ($action->[0] eq "R") {
+ # refer to a file/tree in an earlier commit
+ push(@old,$path); # remove any old stuff
+
+ # ... and add any new stuff
+ my($b,$srcpath) = split_path($revision,$action->[1]);
+ $srcpath =~ s#/*$#/#;
+ open my $F,"-|","git-ls-tree","-r","-z", $branches{$b}{$action->[2]}, $srcpath;
+ local $/ = "\0";
+ while(<$F>) {
+ chomp;
+ my($m,$p) = split(/\t/,$_,2);
+ my($mode,$type,$sha1) = split(/ /,$m);
+ next if $type ne "blob";
+ $p = substr($p,length($srcpath)-1);
+ push(@new,[$mode,$sha1,$path.$p]);
+ }
+ close($F);
+ } else {
+ die "$revision: unknown action '".$action->[0]."' for $path\n";