summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Brown <ben@demerara.io>2021-11-24 17:19:22 +0000
committerBen Brown <ben@demerara.io>2021-11-24 17:19:22 +0000
commit51accdb426463e3669d729f7959714068d2b9af9 (patch)
tree53073913383603a9abce6cde7701acb0eaf6d9b1
parent796a2ae9622a37ab02195880c19d2055bb2412dc (diff)
parent4c789da454d03b0e2840ba52aa9063b6d27f646a (diff)
downloadlorry-51accdb426463e3669d729f7959714068d2b9af9.tar.gz
Merge branch 'benbrown/hard-links' into 'master'
lorry.tar-importer: support hard links See merge request CodethinkLabs/lorry/lorry!23
-rwxr-xr-xlorry.tar-importer32
-rwxr-xr-xtests/tar-hard-links.script33
-rwxr-xr-xtests/tar-hard-links.setup39
3 files changed, 92 insertions, 12 deletions
diff --git a/lorry.tar-importer b/lorry.tar-importer
index 10696bf..7ffdfa9 100755
--- a/lorry.tar-importer
+++ b/lorry.tar-importer
@@ -112,11 +112,7 @@ foreach my $tar_file (@ARGV)
$mtime = oct $mtime;
next if $typeflag == 5; # directory
- if ($typeflag == 2) { # symbolic link
- print FI "blob\n", "mark :$next_mark\n";
- print FI "data ", length($linkname), "\n", $linkname;
- $mode = 0120000;
- } elsif ($typeflag eq 'x') { # extended header
+ if ($typeflag eq 'x') { # extended header
# If extended header, check for path
my $pax_header = '';
while ($size > 0 && read(I, $_, 512) == 512) {
@@ -136,15 +132,21 @@ foreach my $tar_file (@ARGV)
} elsif ($name =~ m{/\z}) {
# If it's a folder, ignore
next;
- } else {
+ } elsif ($typeflag != 1) { # handle hard links later
print FI "blob\n", "mark :$next_mark\n";
- print FI "data $size\n";
- while ($size > 0 && read(I, $_, 512) == 512) {
- print FI substr($_, 0, $size);
- $size -= 512;
+ 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";
next if ($typeflag eq 'g'); # ignore global header
@@ -154,7 +156,13 @@ foreach my $tar_file (@ARGV)
} 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,^([^/]+)/,;
diff --git a/tests/tar-hard-links.script b/tests/tar-hard-links.script
new file mode 100755
index 0000000..3d7fc8f
--- /dev/null
+++ b/tests/tar-hard-links.script
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Tests hard links and their targets are all imported with content.
+#
+# Copyright (C) 2021 Ben Brown
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+set -e
+
+logfile="${DATADIR}/tar-hard-links.log"
+workdir="${DATADIR}/work-dir"
+
+"${SRCDIR}/test-lorry" \
+ --pull-only \
+ --log="${logfile}" \
+ --working-area="${workdir}" \
+ "${DATADIR}/hard-links.lorry" >/dev/null
+
+[ "$(git -C "${workdir}/hard-links/git-a" cat-file -s HEAD:hard-link)" -gt 0 ]
+[ "$(git -C "${workdir}/hard-links/git-a" cat-file -s HEAD:test)" -gt 0 ]
diff --git a/tests/tar-hard-links.setup b/tests/tar-hard-links.setup
new file mode 100755
index 0000000..0d68cee
--- /dev/null
+++ b/tests/tar-hard-links.setup
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# Creates a tarball containing a hard link.
+#
+# Copyright (C) 2021 Ben Brown
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+set -e
+
+dir="${DATADIR}/tar-hard-links"
+mkdir -p "${dir}"
+echo foo > "${dir}"/test
+ln "${dir}"/test "${dir}"/hard-link
+
+tar_path="${DATADIR}/hard-links.tar"
+tar -C "${DATADIR}" -cf "${tar_path}" "$(basename "${dir}")"
+
+# create the .lorry file for the repository
+cat <<EOF > "${DATADIR}/hard-links.lorry"
+hard-links:
+ type: tarball
+ url: file://${tar_path}
+EOF
+
+# create the working directory
+mkdir -p "${DATADIR}/work-dir"