import-tars: support hard links

Previously, we simply treated hard links as if they were plain files with size 0, ignoring the link type "1" and hence the link target. What we should do instead, of course, is to use the link target to get at the import mark for the contents, even if we cannot recreate the hard link per se, as Git has no concept of hard links. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Aug 3, 2016 at 15:30 UTC 04e0869876f726d5af9ac901911781d440e6aed2
1 file changed +20 -11
contrib/fast-import/import-tars.perl
+20 -11
@@ -96,18 +96,21 @@ foreach my $tar_file (@ARGV)
96 $mtime = oct $mtime;
97 next if $typeflag == 5; # directory
98
99 - print FI "blob\n", "mark :$next_mark\n";
100 - if ($typeflag == 2) { # symbolic link
101 - print FI "data ", length($linkname), "\n", $linkname;
102 - $mode = 0120000;
103 - } else {
104 - print FI "data $size\n";
105 - while ($size > 0 && read(I, $_, 512) == 512) {
106 - print FI substr($_, 0, $size);
107 - $size -= 512;
99 + if ($typeflag != 1) { # handle hard links later
100 + print FI "blob\n", "mark :$next_mark\n";
101 + if ($typeflag == 2) { # symbolic link
102 + print FI "data ", length($linkname), "\n",
103 + $linkname;
104 + $mode = 0120000;
105 + } else {
106 + print FI "data $size\n";
107 + while ($size > 0 && read(I, $_, 512) == 512) {
108 + print FI substr($_, 0, $size);
109 + $size -= 512;
110 + }
111 }
112 + print FI "\n";
113 }
110 - print FI "\n";
114
115 my $path;
116 if ($prefix) {
@@ -115,7 +118,13 @@ foreach my $tar_file (@ARGV)
118 } else {
119 $path = "$name";
120 }
118 - $files{$path} = [$next_mark++, $mode];
121 +
122 + if ($typeflag == 1) { # hard link
123 + $linkname = "$prefix/$linkname" if $prefix;
124 + $files{$path} = [ $files{$linkname}->[0], $mode ];
125 + } else {
126 + $files{$path} = [$next_mark++, $mode];
127 + }
128
129 $author_time = $mtime if $mtime > $author_time;
130 $path =~ m,^([^/]+)/,;