{"thread":{"id":"42995","subject":"[PATCH] import-tars: support hard links","startedAt":"2016-08-03T13:30:40Z","lastAt":"2016-08-04T15:06:15Z","messageCount":3,"participants":["Johannes Schindelin","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"292896","messageId":"bb3b91403fae1964aa990fc16fd8a4e5f16885e6.1470230877.git.johannes.schindelin@gmx.de","threadId":"42995","inReplyTo":null,"subject":"[PATCH] import-tars: support hard links","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-08-03T13:30:20Z","receivedAt":"2016-08-03T13:30:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Previously, we simply treated hard links as if they were plain files\nwith size 0, ignoring the link type \"1\" and hence the link target.\n\nWhat we should do instead, of course, is to use the link target to get\nat the import mark for the contents, even if we cannot recreate the hard\nlink per se, as Git has no concept of hard links.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\nPublished-As: https://github.com/dscho/git/releases/tag/import-tars-hardlink-v1\n contrib/fast-import/import-tars.perl | 31 ++++++++++++++++++++-----------\n 1 file changed, 20 insertions(+), 11 deletions(-)\n\ndiff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl\nindex 95438e1..d60b431 100755\n--- a/contrib/fast-import/import-tars.perl\n+++ b/contrib/fast-import/import-tars.perl\n@@ -96,18 +96,21 @@ foreach my $tar_file (@ARGV)\n \t\t$mtime = oct $mtime;\n \t\tnext if $typeflag == 5; # directory\n \n-\t\tprint FI \"blob\\n\", \"mark :$next_mark\\n\";\n-\t\tif ($typeflag == 2) { # symbolic link\n-\t\t\tprint FI \"data \", length($linkname), \"\\n\", $linkname;\n-\t\t\t$mode = 0120000;\n-\t\t} else {\n-\t\t\tprint FI \"data $size\\n\";\n-\t\t\twhile ($size > 0 && read(I, $_, 512) == 512) {\n-\t\t\t\tprint FI substr($_, 0, $size);\n-\t\t\t\t$size -= 512;\n+\t\tif ($typeflag != 1) { # handle hard links later\n+\t\t\tprint FI \"blob\\n\", \"mark :$next_mark\\n\";\n+\t\t\tif ($typeflag == 2) { # symbolic link\n+\t\t\t\tprint FI \"data \", length($linkname), \"\\n\",\n+\t\t\t\t\t$linkname;\n+\t\t\t\t$mode = 0120000;\n+\t\t\t} else {\n+\t\t\t\tprint FI \"data $size\\n\";\n+\t\t\t\twhile ($size > 0 && read(I, $_, 512) == 512) {\n+\t\t\t\t\tprint FI substr($_, 0, $size);\n+\t\t\t\t\t$size -= 512;\n+\t\t\t\t}\n \t\t\t}\n+\t\t\tprint FI \"\\n\";\n \t\t}\n-\t\tprint FI \"\\n\";\n \n \t\tmy $path;\n \t\tif ($prefix) {\n@@ -115,7 +118,13 @@ foreach my $tar_file (@ARGV)\n \t\t} else {\n \t\t\t$path = \"$name\";\n \t\t}\n-\t\t$files{$path} = [$next_mark++, $mode];\n+\n+\t\tif ($typeflag == 1) { # hard link\n+\t\t\t$linkname = \"$prefix/$linkname\" if $prefix;\n+\t\t\t$files{$path} = [ $files{$linkname}->[0], $mode ];\n+\t\t} else {\n+\t\t\t$files{$path} = [$next_mark++, $mode];\n+\t\t}\n \n \t\t$author_time = $mtime if $mtime > $author_time;\n \t\t$path =~ m,^([^/]+)/,;\n-- \n2.9.0.281.g286a8d9\n\nbase-commit: f8f7adce9fc50a11a764d57815602dcb818d1816\n"},{"id":"292925","messageId":"xmqqinvhaji7.fsf@gitster.mtv.corp.google.com","threadId":"42995","inReplyTo":"bb3b91403fae1964aa990fc16fd8a4e5f16885e6.1470230877.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH] import-tars: support hard links","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-08-03T16:45:52Z","receivedAt":"2016-08-03T17:05:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Previously, we simply treated hard links as if they were plain files\n> with size 0, ignoring the link type \"1\" and hence the link target.\n\nNicely spotted and explained.\n\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n> Published-As: https://github.com/dscho/git/releases/tag/import-tars-hardlink-v1\n\nA link to a page that lets you download entire source tarball is not\nvery useful to most people, except for those who want \"this exact\nchange on top of some unknown base which may or may not have other\nthings they need\", which I think is a minority.\n\nCan you also (or instead) point at a branch/tag that people can do\n\n\tgit fetch $repo $branch\n\nmore easily?\n\n>  contrib/fast-import/import-tars.perl | 31 ++++++++++++++++++++-----------\n>  1 file changed, 20 insertions(+), 11 deletions(-)\n>\n> diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl\n> index 95438e1..d60b431 100755\n> --- a/contrib/fast-import/import-tars.perl\n> +++ b/contrib/fast-import/import-tars.perl\n> @@ -96,18 +96,21 @@ foreach my $tar_file (@ARGV)\n>  \t\t$mtime = oct $mtime;\n>  \t\tnext if $typeflag == 5; # directory\n>  \n> -\t\tprint FI \"blob\\n\", \"mark :$next_mark\\n\";\n> -\t\tif ($typeflag == 2) { # symbolic link\n> -\t\t\tprint FI \"data \", length($linkname), \"\\n\", $linkname;\n> -\t\t\t$mode = 0120000;\n> -\t\t} else {\n> -\t\t\tprint FI \"data $size\\n\";\n> -\t\t\twhile ($size > 0 && read(I, $_, 512) == 512) {\n> -\t\t\t\tprint FI substr($_, 0, $size);\n> -\t\t\t\t$size -= 512;\n> +\t\tif ($typeflag != 1) { # handle hard links later\n> +\t\t\tprint FI \"blob\\n\", \"mark :$next_mark\\n\";\n> +\t\t\tif ($typeflag == 2) { # symbolic link\n> +\t\t\t\tprint FI \"data \", length($linkname), \"\\n\",\n> +\t\t\t\t\t$linkname;\n> +\t\t\t\t$mode = 0120000;\n> +\t\t\t} else {\n> +\t\t\t\tprint FI \"data $size\\n\";\n> +\t\t\t\twhile ($size > 0 && read(I, $_, 512) == 512) {\n> +\t\t\t\t\tprint FI substr($_, 0, $size);\n> +\t\t\t\t\t$size -= 512;\n> +\t\t\t\t}\n>  \t\t\t}\n> +\t\t\tprint FI \"\\n\";\n>  \t\t}\n> -\t\tprint FI \"\\n\";\n\nThe resulting if/else cascade initially looked a bit unnatural\n(naively I would have expected that a new \"elsif ($typeflag == 1)\"\nwould be inserted before the final \"else\" currently is).  Because\nyou have to do avoid giving a new mark to hardlink entries, and that\nfact would not change regardless of what values of $typeflag other\nthan 1 exists in the imported tars, so I think the resulting code\nstructure makes a lot of sense.  We may want to add more elsif to\nnotice and ignore/warn/substitute things like CHRTYPE/BLKTYPE by\nenhancing the if/else cascade inside the \"if ($typeflag != 1)\"\nintroduced by this patch, but the code structure does not have to\nchange when such an enhancement happens.\n\nNicely done.\n\n>  \t\tmy $path;\n>  \t\tif ($prefix) {\n> @@ -115,7 +118,13 @@ foreach my $tar_file (@ARGV)\n>  \t\t} else {\n>  \t\t\t$path = \"$name\";\n>  \t\t}\n> -\t\t$files{$path} = [$next_mark++, $mode];\n> +\n> +\t\tif ($typeflag == 1) { # hard link\n> +\t\t\t$linkname = \"$prefix/$linkname\" if $prefix;\n> +\t\t\t$files{$path} = [ $files{$linkname}->[0], $mode ];\n> +\t\t} else {\n> +\t\t\t$files{$path} = [$next_mark++, $mode];\n> +\t\t}\n>  \n>  \t\t$author_time = $mtime if $mtime > $author_time;\n>  \t\t$path =~ m,^([^/]+)/,;\n"},{"id":"293085","messageId":"alpine.DEB.2.20.1608041658220.5786@virtualbox","threadId":"42995","inReplyTo":"xmqqinvhaji7.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH] import-tars: support hard links","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-08-04T14:59:23Z","receivedAt":"2016-08-04T15:06:15Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 3 Aug 2016, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > ---\n> > Published-As: https://github.com/dscho/git/releases/tag/import-tars-hardlink-v1\n> \n> A link to a page that lets you download entire source tarball is not\n> very useful to most people, except for those who want \"this exact\n> change on top of some unknown base which may or may not have other\n> things they need\", which I think is a minority.\n\nTrue. I added a second line that describes how to fetch it (see the t5533\npatch I just sent out).\n\nCiao,\nDscho\n"}]}