Documentation/git-send-email.txt: style fixes
[gitweb.git] / contrib / fast-import / import-tars.perl
index 95438e1ed42f7289131a1b08654a2b23098c8e26..e800d9f5c9cf25e1aae3a0b87ad35f46b2a973c3 100755 (executable)
@@ -63,6 +63,8 @@
        my $have_top_dir = 1;
        my ($top_dir, %files);
 
+       my $next_path = '';
+
        while (read(I, $_, 512) == 512) {
                my ($name, $mode, $uid, $gid, $size, $mtime,
                        $chksum, $typeflag, $linkname, $magic,
                        $prefix) = unpack 'Z100 Z8 Z8 Z8 Z12 Z12
                        Z8 Z1 Z100 Z6
                        Z2 Z32 Z32 Z8 Z8 Z*', $_;
+
+               unless ($next_path eq '') {
+                       # Recover name from previous extended header
+                       $name = $next_path;
+                       $next_path = '';
+               }
+
                last unless length($name);
                if ($name eq '././@LongLink') {
                        # GNU tar extension
                        Z8 Z1 Z100 Z6
                        Z2 Z32 Z32 Z8 Z8 Z*', $_;
                }
-               next if $name =~ m{/\z};
                $mode = oct $mode;
                $size = oct $size;
                $mtime = oct $mtime;
                next if $typeflag == 5; # directory
 
-               print FI "blob\n", "mark :$next_mark\n";
-               if ($typeflag == 2) { # symbolic link
-                       print FI "data ", length($linkname), "\n", $linkname;
-                       $mode = 0120000;
-               } else {
-                       print FI "data $size\n";
+               if ($typeflag eq 'x') { # extended header
+                       # If extended header, check for path
+                       my $pax_header = '';
                        while ($size > 0 && read(I, $_, 512) == 512) {
-                               print FI substr($_, 0, $size);
+                               $pax_header = $pax_header . substr($_, 0, $size);
                                $size -= 512;
                        }
+
+                       my @lines = split /\n/, $pax_header;
+                       foreach my $line (@lines) {
+                               my ($len, $entry) = split / /, $line;
+                               my ($key, $value) = split /=/, $entry;
+                               if ($key eq 'path') {
+                                       $next_path = $value;
+                               }
+                       }
+                       next;
+               } elsif ($name =~ m{/\z}) { # directory
+                       next;
+               } elsif ($typeflag != 1) { # handle hard links later
+                       print FI "blob\n", "mark :$next_mark\n";
+                       if ($typeflag == 2) { # symbolic link
+                               print FI "data ", length($linkname), "\n",
+                                       $linkname;
+                               $mode = 0120000;
+                       } else {
+                               print FI "data $size\n";
+                               while ($size > 0 && read(I, $_, 512) == 512) {
+                                       print FI substr($_, 0, $size);
+                                       $size -= 512;
+                               }
+                       }
+                       print FI "\n";
                }
-               print FI "\n";
 
                my $path;
                if ($prefix) {
                } else {
                        $path = "$name";
                }
-               $files{$path} = [$next_mark++, $mode];
+
+               if ($typeflag == 1) { # hard link
+                       $linkname = "$prefix/$linkname" if $prefix;
+                       $files{$path} = [ $files{$linkname}->[0], $mode ];
+               } else {
+                       $files{$path} = [$next_mark++, $mode];
+               }
 
                $author_time = $mtime if $mtime > $author_time;
                $path =~ m,^([^/]+)/,;