зеркало из https://github.com/microsoft/git.git
git-svn: fix several small bugs, enable branch optimization
Share the repack counter between branches when doing multi-fetch. Pass the -d flag to git repack by default. That's the main reason we will want automatic pack generation, to save space and improve disk cache performance. I won't add -a by default since it can generate extremely large packs that make RAM-starved systems unhappy. We no longer generate the .git/svn/$GIT_SVN_ID/info/uuid file, either. It was never read in the first place. Check for and create .rev_db if we need to during fetch (in case somebody manually blew away their .rev_db and wanted to start over. Mainly makes debugging easier). Croak with $? instead of $! if there's an error closing pipes Quiet down some of the chatter, too. Signed-off-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
Родитель
6c5cda89e9
Коммит
cf7424b021
|
@ -368,7 +368,6 @@ sub fetch_lib {
|
||||||
defined(my $pid = fork) or croak $!;
|
defined(my $pid = fork) or croak $!;
|
||||||
if (!$pid) {
|
if (!$pid) {
|
||||||
$SVN::Error::handler = \&libsvn_skip_unknown_revs;
|
$SVN::Error::handler = \&libsvn_skip_unknown_revs;
|
||||||
print "Fetching revisions $min .. $max\n";
|
|
||||||
|
|
||||||
# Yes I'm perfectly aware that the fourth argument
|
# Yes I'm perfectly aware that the fourth argument
|
||||||
# below is the limit revisions number. Unfortunately
|
# below is the limit revisions number. Unfortunately
|
||||||
|
@ -391,7 +390,6 @@ sub fetch_lib {
|
||||||
$log_msg, @parents);
|
$log_msg, @parents);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$SVN::Error::handler = sub { 'quiet warnings' };
|
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
waitpid $pid, 0;
|
waitpid $pid, 0;
|
||||||
|
@ -463,7 +461,7 @@ sub commit_lib {
|
||||||
my (@revs) = @_;
|
my (@revs) = @_;
|
||||||
my ($r_last, $cmt_last) = svn_grab_base_rev();
|
my ($r_last, $cmt_last) = svn_grab_base_rev();
|
||||||
defined $r_last or die "Must have an existing revision to commit\n";
|
defined $r_last or die "Must have an existing revision to commit\n";
|
||||||
my $fetched = fetch_lib();
|
my $fetched = fetch();
|
||||||
if ($r_last != $fetched->{revision}) {
|
if ($r_last != $fetched->{revision}) {
|
||||||
print STDERR "There are new revisions that were fetched ",
|
print STDERR "There are new revisions that were fetched ",
|
||||||
"and need to be merged (or acknowledged) ",
|
"and need to be merged (or acknowledged) ",
|
||||||
|
@ -523,7 +521,7 @@ sub commit_lib {
|
||||||
$no = 1;
|
$no = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close $fh or croak $!;
|
close $fh or croak $?;
|
||||||
if (! defined $r_new && ! defined $cmt_new) {
|
if (! defined $r_new && ! defined $cmt_new) {
|
||||||
unless ($no) {
|
unless ($no) {
|
||||||
die "Failed to parse revision information\n";
|
die "Failed to parse revision information\n";
|
||||||
|
@ -633,17 +631,8 @@ sub multi_init {
|
||||||
sub multi_fetch {
|
sub multi_fetch {
|
||||||
# try to do trunk first, since branches/tags
|
# try to do trunk first, since branches/tags
|
||||||
# may be descended from it.
|
# may be descended from it.
|
||||||
if (-d "$GIT_DIR/svn/trunk") {
|
if (-e "$GIT_DIR/svn/trunk/info/url") {
|
||||||
print "Fetching trunk\n";
|
fetch_child_id('trunk', @_);
|
||||||
defined(my $pid = fork) or croak $!;
|
|
||||||
if (!$pid) {
|
|
||||||
$GIT_SVN = $ENV{GIT_SVN_ID} = 'trunk';
|
|
||||||
init_vars();
|
|
||||||
fetch(@_);
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
waitpid $pid, 0;
|
|
||||||
croak $? if $?;
|
|
||||||
}
|
}
|
||||||
rec_fetch('', "$GIT_DIR/svn", @_);
|
rec_fetch('', "$GIT_DIR/svn", @_);
|
||||||
}
|
}
|
||||||
|
@ -725,6 +714,41 @@ out:
|
||||||
|
|
||||||
########################### utility functions #########################
|
########################### utility functions #########################
|
||||||
|
|
||||||
|
sub fetch_child_id {
|
||||||
|
my $id = shift;
|
||||||
|
print "Fetching $id\n";
|
||||||
|
my $ref = "$GIT_DIR/refs/remotes/$id";
|
||||||
|
my $ca = file_to_s($ref) if (-r $ref);
|
||||||
|
defined(my $pid = fork) or croak $!;
|
||||||
|
if (!$pid) {
|
||||||
|
$GIT_SVN = $ENV{GIT_SVN_ID} = $id;
|
||||||
|
init_vars();
|
||||||
|
fetch(@_);
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
waitpid $pid, 0;
|
||||||
|
croak $? if $?;
|
||||||
|
return unless $_repack || -r $ref;
|
||||||
|
|
||||||
|
my $cb = file_to_s($ref);
|
||||||
|
|
||||||
|
defined($pid = open my $fh, '-|') or croak $!;
|
||||||
|
my $url = file_to_s("$GIT_DIR/svn/$id/info/url");
|
||||||
|
$url = qr/\Q$url\E/;
|
||||||
|
if (!$pid) {
|
||||||
|
exec qw/git-rev-list --pretty=raw/,
|
||||||
|
$ca ? "$ca..$cb" : $cb or croak $!;
|
||||||
|
}
|
||||||
|
while (<$fh>) {
|
||||||
|
if (/^ git-svn-id: $url\@\d+ [a-f0-9\-]+$/) {
|
||||||
|
check_repack();
|
||||||
|
} elsif (/^ git-svn-id: \S+\@\d+ [a-f0-9\-]+$/) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close $fh;
|
||||||
|
}
|
||||||
|
|
||||||
sub rec_fetch {
|
sub rec_fetch {
|
||||||
my ($pfx, $p, @args) = @_;
|
my ($pfx, $p, @args) = @_;
|
||||||
my @dir;
|
my @dir;
|
||||||
|
@ -733,16 +757,7 @@ sub rec_fetch {
|
||||||
$pfx .= '/' if $pfx && $pfx !~ m!/$!;
|
$pfx .= '/' if $pfx && $pfx !~ m!/$!;
|
||||||
my $id = $pfx . basename $_;
|
my $id = $pfx . basename $_;
|
||||||
next if $id eq 'trunk';
|
next if $id eq 'trunk';
|
||||||
print "Fetching $id\n";
|
fetch_child_id($id, @args);
|
||||||
defined(my $pid = fork) or croak $!;
|
|
||||||
if (!$pid) {
|
|
||||||
$GIT_SVN = $ENV{GIT_SVN_ID} = $id;
|
|
||||||
init_vars();
|
|
||||||
fetch(@args);
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
waitpid $pid, 0;
|
|
||||||
croak $? if $?;
|
|
||||||
} elsif (-d $_) {
|
} elsif (-d $_) {
|
||||||
push @dir, $_;
|
push @dir, $_;
|
||||||
}
|
}
|
||||||
|
@ -943,7 +958,6 @@ sub read_uuid {
|
||||||
$SVN_UUID = $info->{'Repository UUID'} or
|
$SVN_UUID = $info->{'Repository UUID'} or
|
||||||
croak "Repository UUID unreadable\n";
|
croak "Repository UUID unreadable\n";
|
||||||
}
|
}
|
||||||
s_to_file($SVN_UUID,"$GIT_SVN_DIR/info/uuid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub quiet_run {
|
sub quiet_run {
|
||||||
|
@ -1107,7 +1121,7 @@ sub parse_diff_tree {
|
||||||
croak "Error parsing $_\n";
|
croak "Error parsing $_\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close $diff_fh or croak $!;
|
close $diff_fh or croak $?;
|
||||||
|
|
||||||
return \@mods;
|
return \@mods;
|
||||||
}
|
}
|
||||||
|
@ -1348,7 +1362,7 @@ sub get_commit_message {
|
||||||
print $msg $_ or croak $!;
|
print $msg $_ or croak $!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close $msg_fh or croak $!;
|
close $msg_fh or croak $?;
|
||||||
}
|
}
|
||||||
close $msg or croak $!;
|
close $msg or croak $!;
|
||||||
|
|
||||||
|
@ -1562,7 +1576,7 @@ sub svn_info {
|
||||||
push @{$ret->{-order}}, $1;
|
push @{$ret->{-order}}, $1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close $info_fh or croak $!;
|
close $info_fh or croak $?;
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,7 +1652,7 @@ sub do_update_index {
|
||||||
}
|
}
|
||||||
print $ui $x,"\0";
|
print $ui $x,"\0";
|
||||||
}
|
}
|
||||||
close $ui or croak $!;
|
close $ui or croak $?;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub index_changes {
|
sub index_changes {
|
||||||
|
@ -1765,11 +1779,15 @@ sub git_commit {
|
||||||
|
|
||||||
# this output is read via pipe, do not change:
|
# this output is read via pipe, do not change:
|
||||||
print "r$log_msg->{revision} = $commit\n";
|
print "r$log_msg->{revision} = $commit\n";
|
||||||
|
check_repack();
|
||||||
|
return $commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_repack {
|
||||||
if ($_repack && (--$_repack_nr == 0)) {
|
if ($_repack && (--$_repack_nr == 0)) {
|
||||||
$_repack_nr = $_repack;
|
$_repack_nr = $_repack;
|
||||||
sys("git repack $_repack_flags");
|
sys("git repack $_repack_flags");
|
||||||
}
|
}
|
||||||
return $commit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_commit_env {
|
sub set_commit_env {
|
||||||
|
@ -1877,6 +1895,10 @@ sub svn_cmd_checkout {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_upgrade_needed {
|
sub check_upgrade_needed {
|
||||||
|
if (!-r $REVDB) {
|
||||||
|
open my $fh, '>>',$REVDB or croak $!;
|
||||||
|
close $fh;
|
||||||
|
}
|
||||||
my $old = eval {
|
my $old = eval {
|
||||||
my $pid = open my $child, '-|';
|
my $pid = open my $child, '-|';
|
||||||
defined $pid or croak $!;
|
defined $pid or croak $!;
|
||||||
|
@ -2026,7 +2048,8 @@ sub migration_check {
|
||||||
sub find_rev_before {
|
sub find_rev_before {
|
||||||
my ($r, $id, $eq_ok) = @_;
|
my ($r, $id, $eq_ok) = @_;
|
||||||
my $f = "$GIT_DIR/svn/$id/.rev_db";
|
my $f = "$GIT_DIR/svn/$id/.rev_db";
|
||||||
# --$r unless $eq_ok;
|
return (undef,undef) unless -r $f;
|
||||||
|
--$r unless $eq_ok;
|
||||||
while ($r > 0) {
|
while ($r > 0) {
|
||||||
if (my $c = revdb_get($f, $r)) {
|
if (my $c = revdb_get($f, $r)) {
|
||||||
return ($r, $c);
|
return ($r, $c);
|
||||||
|
@ -2072,7 +2095,7 @@ sub set_default_vals {
|
||||||
if (defined $_repack) {
|
if (defined $_repack) {
|
||||||
$_repack = 1000 if ($_repack <= 0);
|
$_repack = 1000 if ($_repack <= 0);
|
||||||
$_repack_nr = $_repack;
|
$_repack_nr = $_repack;
|
||||||
$_repack_flags ||= '';
|
$_repack_flags ||= '-d';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2352,7 +2375,7 @@ sub libsvn_get_file {
|
||||||
close $ho or croak $?;
|
close $ho or croak $?;
|
||||||
$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
|
$hash =~ /^$sha1$/o or die "not a sha1: $hash\n";
|
||||||
print $gui $mode,' ',$hash,"\t",$p,"\0" or croak $!;
|
print $gui $mode,' ',$hash,"\t",$p,"\0" or croak $!;
|
||||||
close $fd or croak $!;
|
close $fd or croak $?;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub libsvn_log_entry {
|
sub libsvn_log_entry {
|
||||||
|
@ -2381,7 +2404,7 @@ sub process_rm {
|
||||||
while (<$ls>) {
|
while (<$ls>) {
|
||||||
print $gui '0 ',0 x 40,"\t",$_ or croak $!;
|
print $gui '0 ',0 x 40,"\t",$_ or croak $!;
|
||||||
}
|
}
|
||||||
close $ls or croak $!;
|
close $ls or croak $?;
|
||||||
} else {
|
} else {
|
||||||
print $gui '0 ',0 x 40,"\t",$f,"\0" or croak $!;
|
print $gui '0 ',0 x 40,"\t",$f,"\0" or croak $!;
|
||||||
}
|
}
|
||||||
|
@ -2411,7 +2434,7 @@ sub libsvn_fetch {
|
||||||
$pool->clear;
|
$pool->clear;
|
||||||
}
|
}
|
||||||
libsvn_get_file($gui, $_, $rev) foreach (@amr);
|
libsvn_get_file($gui, $_, $rev) foreach (@amr);
|
||||||
close $gui or croak $!;
|
close $gui or croak $?;
|
||||||
return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]);
|
return libsvn_log_entry($rev, $author, $date, $msg, [$last_commit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2514,36 +2537,30 @@ sub revisions_eq {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub libsvn_find_parent_branch {
|
sub libsvn_find_parent_branch {
|
||||||
return undef; # XXX this function is disabled atm (not tested enough)
|
|
||||||
my ($paths, $rev, $author, $date, $msg) = @_;
|
my ($paths, $rev, $author, $date, $msg) = @_;
|
||||||
my $svn_path = '/'.$SVN_PATH;
|
my $svn_path = '/'.$SVN_PATH;
|
||||||
|
|
||||||
# look for a parent from another branch:
|
# look for a parent from another branch:
|
||||||
foreach (keys %$paths) {
|
my $i = $paths->{$svn_path} or return;
|
||||||
next if ($_ ne $svn_path);
|
my $branch_from = $i->copyfrom_path or return;
|
||||||
my $i = $paths->{$_};
|
my $r = $i->copyfrom_rev;
|
||||||
my $branch_from = $i->copyfrom_path or next;
|
print STDERR "Found possible branch point: ",
|
||||||
my $r = $i->copyfrom_rev;
|
"$branch_from => $svn_path, $r\n";
|
||||||
print STDERR "Found possible branch point: ",
|
$branch_from =~ s#^/##;
|
||||||
"$branch_from => $svn_path, $r\n";
|
my $l_map = read_url_paths();
|
||||||
$branch_from =~ s#^/##;
|
my $url = $SVN->{url};
|
||||||
my $l_map = read_url_paths();
|
defined $l_map->{$url} or return;
|
||||||
my $url = $SVN->{url};
|
my $id = $l_map->{$url}->{$branch_from} or return;
|
||||||
defined $l_map->{$url} or next;
|
my ($r0, $parent) = find_rev_before($r,$id,1);
|
||||||
my $id = $l_map->{$url}->{$branch_from} or next;
|
return unless (defined $r0 && defined $parent);
|
||||||
my ($r0, $parent) = find_rev_before($r,$id,1);
|
if (revisions_eq($branch_from, $r0, $r)) {
|
||||||
if (defined $r0 && defined $parent &&
|
unlink $GIT_SVN_INDEX;
|
||||||
revisions_eq($branch_from, $r0, $r)) {
|
print STDERR "Found branch parent: $parent\n";
|
||||||
unlink $GIT_SVN_INDEX;
|
sys(qw/git-read-tree/, $parent);
|
||||||
print STDERR "Found branch parent: $parent\n";
|
return libsvn_fetch($parent, $paths, $rev,
|
||||||
sys(qw/git-read-tree/, $parent);
|
$author, $date, $msg);
|
||||||
return libsvn_fetch($parent, $paths, $rev,
|
|
||||||
$author, $date, $msg);
|
|
||||||
} else {
|
|
||||||
print STDERR
|
|
||||||
"Nope, branch point not imported or unknown\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
print STDERR "Nope, branch point not imported or unknown\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2556,7 +2573,7 @@ sub libsvn_new_tree {
|
||||||
my $pool = SVN::Pool->new;
|
my $pool = SVN::Pool->new;
|
||||||
libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool);
|
libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool);
|
||||||
$pool->clear;
|
$pool->clear;
|
||||||
close $gui or croak $!;
|
close $gui or croak $?;
|
||||||
return libsvn_log_entry($rev, $author, $date, $msg);
|
return libsvn_log_entry($rev, $author, $date, $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2630,7 +2647,7 @@ sub libsvn_commit_cb {
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fetch_lib("$rev=$c");
|
fetch("$rev=$c");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2664,7 +2681,6 @@ sub libsvn_skip_unknown_revs {
|
||||||
# 175002 - http(s)://
|
# 175002 - http(s)://
|
||||||
# More codes may be discovered later...
|
# More codes may be discovered later...
|
||||||
if ($errno == 175002 || $errno == 160013) {
|
if ($errno == 175002 || $errno == 160013) {
|
||||||
print STDERR "directory non-existent\n";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
croak "Error from SVN, ($errno): ", $err->expanded_message,"\n";
|
croak "Error from SVN, ($errno): ", $err->expanded_message,"\n";
|
||||||
|
|
Загрузка…
Ссылка в новой задаче