I couldn't figure out git-filter-branch, so I did the following, which worked for me:
First, export commits as patches in mbox format:
git log -p --first-parent --reverse --pretty=email $* > mbox
Second, run the mbox file through a filter which selectively renames files (since almost always I want the files in a different directory in the new repository):
myfilter scripts=bin perllib=lib < mbox > mbox2
Finally, import into new repo:
git-am mbox2
It's a bit slow on the import step but it meets my needs at this time.
Nick.
Filter script follows, for what it's worth ...
#!/usr/bin/perl # @(#) git-filter-rename.pl # # Read an mbox file containing patches on standard input, # modify the filenames within according to a list of substitutions # supplied on the command line, and write the modified mbox file # to standard output.
my @subs;
foreach (@ARGV) {
if (/(.*)=(.*)/) {
my $len = length($1);
push(@subs, [ $1, $2, $len ]);
} else {
print STDERR "Unknown arg: $_\n";
}
}while (<STDIN>) {
chomp;
my $line = $_; if ($line =~ /^(---|\+\+\+) ([ab]\/)(.+)$/) {
my $line_1 = $1;
my $line_2 = $2;
my $line_3 = $3; subFilename($line_3);
print "$line_1 $line_2$line_3\n";
next;
}
if ($line =~ /^diff --git ([ab]\/)(\S+) ([ab]\/)(\S+)/) {
my ($line_1, $line_2, $line_3, $line_4) = ($1, $2, $3, $4);
subFilename($line_2);
subFilename($line_4);
print "diff --git $line_1$line_2 $line_3$line_4\n";
next;
} print $line, "\n";
}
exit(0);
# ------------------------------------------------------------------------ # Substitute a filename in-place (modifies argument) # ------------------------------------------------------------------------
sub subFilename { foreach my $lr (@subs) {
my ($lhs, $rhs, $len) = @$lr;
if (substr($_[0], 0, $len) eq $lhs) {
print STDERR "Match on $lhs, $_[0]\n";
substr($_[0], 0, $len) = $rhs;
last;
}
}
}