=head1 Invocation
- git-archimport [ -h ] [ -v ] [ -T ] [ -t tempdir ] <archive>/<branch> [ <archive>/<branch> ]
+ git-archimport [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ]
+ [ -D depth] [ -t tempdir ] <archive>/<branch> [ <archive>/<branch> ]
Imports a project from one or more Arch repositories. It will follow branches
and repositories within the namespaces defined by the <archive/branch>
-parameters suppplied. If it cannot find the remote branch a merge comes from
+parameters supplied. If it cannot find the remote branch a merge comes from
it will just import it as a regular commit. If it can find it, it will mark it
as a merge whenever possible.
sub usage() {
print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from Arch
- [ -f ] [ -o ] [ -h ] [ -v ] [ -T ] [ -a ] [ -D depth ] [ -t tempdir ]
+ [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ] [ -D depth ] [ -t tempdir ]
repository/arch-branch [ repository/arch-branch] ...
END
exit(1);
# $arch_branches:
# values associated with keys:
# =1 - Arch version / git 'branch' detected via abrowse on a limit
-# >1 - Arch version / git 'branch' of an auxilliary branch we've merged
+# >1 - Arch version / git 'branch' of an auxiliary branch we've merged
my %arch_branches = map { $_ => 1 } @ARGV;
$ENV{'TMPDIR'} = $opt_t if $opt_t; # $ENV{TMPDIR} will affect tempdir() calls:
my $tmp = tempdir('git-archimport-XXXXXX', TMPDIR => 1, CLEANUP => 1);
$opt_v && print "+ Using $tmp as temporary directory\n";
+unless (-d $git_dir) { # initial import needs empty directory
+ opendir DIR, '.' or die "Unable to open current directory: $!\n";
+ while (my $entry = readdir DIR) {
+ $entry =~ /^\.\.?$/ or
+ die "Initial import needs an empty current working directory.\n"
+ }
+ closedir DIR
+}
+
my %reachable = (); # Arch repositories we can access
my %unreachable = (); # Arch repositories we can't access :<
my @psets = (); # the collection
unless (-d $git_dir) { # initial import
if ($psets[0]{type} eq 'i' || $psets[0]{type} eq 't') {
print "Starting import from $psets[0]{id}\n";
- `git-init-db`;
+ `git-init`;
die $! if $?;
$import = 1;
} else {
}
# update the index with all the changes we got
+ system('git-diff-files --name-only -z | '.
+ 'git-update-index --remove -z --stdin') == 0 or die "$! $?\n";
system('git-ls-files --others -z | '.
'git-update-index --add -z --stdin') == 0 or die "$! $?\n";
- system('git-ls-files --deleted -z | '.
- 'git-update-index --remove -z --stdin') == 0 or die "$! $?\n";
- system('git-ls-files -z | '.
- 'git-update-index -z --stdin') == 0 or die "$! $?\n";
return 1;
}
# imports don't give us good info
# on added files. Shame on them
if ($ps->{type} eq 'i' || $ps->{type} eq 't') {
- system('git-ls-files --others -z | '.
- 'git-update-index --add -z --stdin') == 0 or die "$! $?\n";
system('git-ls-files --deleted -z | '.
'git-update-index --remove -z --stdin') == 0 or die "$! $?\n";
+ system('git-ls-files --others -z | '.
+ 'git-update-index --add -z --stdin') == 0 or die "$! $?\n";
}
# TODO: handle removed_directories and renamed_directories:
-
- if (my $add = $ps->{new_files}) {
- while (@$add) {
- my @slice = splice(@$add, 0, 100);
- system('git-update-index','--add','--',@slice) == 0 or
- die "Error in git-update-index --add: $! $?\n";
- }
- }
-
+
if (my $del = $ps->{removed_files}) {
unlink @$del;
while (@$del) {
}
}
+ if (my $add = $ps->{new_files}) {
+ while (@$add) {
+ my @slice = splice(@$add, 0, 100);
+ system('git-update-index','--add','--',@slice) == 0 or
+ die "Error in git-update-index --add: $! $?\n";
+ }
+ }
+
if (my $mod = $ps->{modified_files}) {
while (@$mod) {
my @slice = splice(@$mod, 0, 100);
#
if (ptag($ps->{id})) {
$opt_v && print " * Skipping already imported: $ps->{id}\n";
- return 0;
+ next;
}
print " * Starting to work on $ps->{id}\n";
print " + commit $commitid\n";
$opt_v && print " + commit date is $ps->{date} \n";
$opt_v && print " + parents: ",join(' ',@par),"\n";
- if (my $dirty = `git-diff-files`) {
- die "22 Unclean tree when about to process $ps->{id} " .
- " - did we fail to commit cleanly before?\n$dirty";
- }
}
if ($opt_v) {
if (`find $tmp/changeset/patches -type f -name '*.patch'`) {
# this can be sped up considerably by doing
# (find | xargs cat) | patch
- # but that cna get mucked up by patches
+ # but that can get mucked up by patches
# with missing trailing newlines or the standard
# 'missing newline' flag in the patch - possibly
# produced with an old/buggy diff.
# skip Arch control files, unescape pika-escaped files
foreach my $k (keys %want_headers) {
next unless (defined $ps->{$k});
- my @tmp;
+ my @tmp = ();
foreach my $t (@{$ps->{$k}}) {
next unless length ($t);
next if $t =~ m!\{arch\}/!;
}
push @tmp, $t;
}
- $ps->{$k} = \@tmp if scalar @tmp;
+ $ps->{$k} = \@tmp;
}
}
# now walk up to the mergepoint collecting what patches we have
my $branchtip = git_rev_parse($ps->{branch});
- my @ancestors = `git-rev-list --merge-order $branchtip ^$mergebase`;
+ my @ancestors = `git-rev-list --topo-order $branchtip ^$mergebase`;
my %have; # collected merges this branch has
foreach my $merge (@{$ps->{merges}}) {
$have{$merge} = 1;
# see what the remote branch has - these are the merges we
# will want to have in a consecutive series from the mergebase
my $otherbranchtip = git_rev_parse($branch);
- my @needraw = `git-rev-list --merge-order $otherbranchtip ^$mergebase`;
+ my @needraw = `git-rev-list --topo-order $otherbranchtip ^$mergebase`;
my @need;
foreach my $needps (@needraw) { # get the psets
$needps = commitid2pset($needps);
}
-# an alterative to `command` that allows input to be passed as an array
+# an alternative to `command` that allows input to be passed as an array
# to work around shell problems with weird characters in arguments
sub safe_pipe_capture {
my @output;