All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] tar archive frontend for fast-import.
@ 2007-02-08 20:38 Shawn O. Pearce
  2007-02-08 20:56 ` Johannes Schindelin
  0 siblings, 1 reply; 3+ messages in thread
From: Shawn O. Pearce @ 2007-02-08 20:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This is an example fast-import frontend, in less than 100 lines
of Perl.  It accepts one or more tar archives on the command line,
passes them through gzcat/bzcat/zcat if necessary, parses out the
individual file headers and feeds all contained data to fast-import.
No temporary files are involved.

Each tar is treated as one commit, with the commit timestamp coming
from the oldest file modification date found within the tar.

Each tar is also tagged with an annotated tag, using the basename
of the tar file as the name of the tag.

Currently symbolic links and hard links are not handled by the
importer.  The file checksums are also not verified.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---

 Nifty, eh?  :-)

 contrib/fast-import/import-tars.perl |  105 ++++++++++++++++++++++++++++++++++
 1 files changed, 105 insertions(+), 0 deletions(-)
 create mode 100755 contrib/fast-import/import-tars.perl

diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl
new file mode 100755
index 0000000..26c42c9
--- /dev/null
+++ b/contrib/fast-import/import-tars.perl
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+## tar archive frontend for git-fast-import
+##
+## For example:
+##
+##  mkdir project; cd project; git init
+##  perl import-tars.perl *.tar.bz2
+##  git whatchanged import-tars
+##
+
+use strict;
+die "usage: import-tars *.tar.{gz,bz2,Z}\n" unless @ARGV;
+
+my $branch_name = 'import-tars';
+my $branch_ref = "refs/heads/$branch_name";
+my $committer_name = 'T Ar Creator';
+my $committer_email = 'tar@example.com';
+
+open(FI, '|-', 'git', 'fast-import', '--quiet')
+	or die "Unable to start git fast-import: $!\n";
+foreach my $tar_file (@ARGV)
+{
+	$tar_file =~ m,([^/]+)$,;
+	my $tar_name = $1;
+
+	if ($tar_name =~ s/\.(tar\.gz|tgz)$//) {
+		open(I, '-|', 'gzcat', $tar_file) or die "Unable to gzcat $tar_file: $!\n";
+	} elsif ($tar_name =~ s/\.(tar\.bz2|tbz2)$//) {
+		open(I, '-|', 'bzcat', $tar_file) or die "Unable to bzcat $tar_file: $!\n";
+	} elsif ($tar_name =~ s/\.tar\.Z$//) {
+		open(I, '-|', 'zcat', $tar_file) or die "Unable to zcat $tar_file: $!\n";
+	} elsif ($tar_name =~ s/\.tar$//) {
+		open(I, $tar_file) or die "Unable to open $tar_file: $!\n";
+	} else {
+		die "Unrecognized compression format: $tar_file\n";
+	}
+
+	my $commit_time = 0;
+	my $next_mark = 1;
+	my $have_top_dir = 1;
+	my ($top_dir, %files);
+
+	while (read(I, $_, 512) == 512) {
+		my ($name, $mode, $uid, $gid, $size, $mtime,
+			$chksum, $typeflag, $linkname, $magic,
+			$version, $uname, $gname, $devmajor, $devminor,
+			$prefix) = unpack 'Z100 Z8 Z8 Z8 Z12 Z12
+			Z8 Z1 Z100 Z6
+			Z2 Z32 Z32 Z8 Z8 Z*', $_;
+		last unless $name;
+		$mode = oct $mode;
+		$size = oct $size;
+		$mtime = oct $mtime;
+		next if $mode & 0040000;
+
+		print FI "blob\n", "mark :$next_mark\n", "data $size\n";
+		while ($size > 0 && read(I, $_, 512) == 512) {
+			print FI substr($_, 0, $size);
+			$size -= 512;
+		}
+		print FI "\n";
+
+		my $path = "$prefix$name";
+		$files{$path} = [$next_mark++, $mode];
+
+		$commit_time = $mtime if $mtime > $commit_time;
+		$path =~ m,^([^/]+)/,;
+		$top_dir = $1 unless $top_dir;
+		$have_top_dir = 0 if $top_dir ne $1;
+	}
+
+	print FI <<EOF;
+commit $branch_ref
+committer $committer_name <$committer_email> $commit_time +0000
+data <<END_OF_COMMIT_MESSAGE
+Imported from $tar_file.
+END_OF_COMMIT_MESSAGE
+
+deleteall
+EOF
+
+	foreach my $path (keys %files)
+	{
+		my ($mark, $mode) = @{$files{$path}};
+		my $git_mode = 0644;
+		$git_mode |= 0700 if $mode & 0111;
+		$path =~ s,^([^/]+)/,, if $have_top_dir;
+		printf FI "M %o :%i %s\n", $git_mode, $mark, $path;
+	}
+	print FI "\n";
+
+	print FI <<EOF;
+tag $tar_name
+from $branch_ref
+tagger $committer_name <$committer_email> $commit_time +0000
+data <<END_OF_TAG_MESSAGE
+Package $tar_name
+END_OF_TAG_MESSAGE
+
+EOF
+
+	close I;
+}
+close FI;
-- 
1.5.0.rc4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] tar archive frontend for fast-import.
  2007-02-08 20:38 [PATCH 2/2] tar archive frontend for fast-import Shawn O. Pearce
@ 2007-02-08 20:56 ` Johannes Schindelin
  2007-02-08 21:01   ` Shawn O. Pearce
  0 siblings, 1 reply; 3+ messages in thread
From: Johannes Schindelin @ 2007-02-08 20:56 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Junio C Hamano, git

Hi,

On Thu, 8 Feb 2007, Shawn O. Pearce wrote:

> Each tar is treated as one commit, with the commit timestamp coming
> from the oldest file modification date found within the tar.

You mean the youngest, i.e. the newest file, right? (I did not read the 
code yet...)

>  Nifty, eh?  :-)

Yes!

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] tar archive frontend for fast-import.
  2007-02-08 20:56 ` Johannes Schindelin
@ 2007-02-08 21:01   ` Shawn O. Pearce
  0 siblings, 0 replies; 3+ messages in thread
From: Shawn O. Pearce @ 2007-02-08 21:01 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Thu, 8 Feb 2007, Shawn O. Pearce wrote:
> 
> > Each tar is treated as one commit, with the commit timestamp coming
> > from the oldest file modification date found within the tar.
> 
> You mean the youngest, i.e. the newest file, right? (I did not read the 
> code yet...)

Arrggh!  Yes, of course, the youngest/newest file.  The code (and
you) is right, the commit message is wrong.  ;-)

-- 
Shawn.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-02-08 21:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-08 20:38 [PATCH 2/2] tar archive frontend for fast-import Shawn O. Pearce
2007-02-08 20:56 ` Johannes Schindelin
2007-02-08 21:01   ` Shawn O. Pearce

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.