提交 2beec897 编写于 作者: D Deskin Miller 提交者: Junio C Hamano

git-svn: do a partial rebuild if rev_map is out-of-date

Suppose you're using git-svn to work with a certain SVN repository.
Since you don't like 'git-svn fetch' to take forever, and you don't want
to accidentally interrupt it and end up corrupting your repository, you
set up a remote Git repository to mirror the SVN repository, which does
its own 'git-svn fetch' on a cronjob; now you can 'git-fetch' from the
Git mirror into your local repository, and still dcommit to SVN when you
have changes to push.

After you do this, though, git-svn will get very confused if you ever
try to do 'git-svn fetch' in your local repository again, since its
rev_map will differ from the branch's head, and it will be unable to
fetch new commits from SVN because of the metadata conflict.  But all
the necessary metadata are there in the Git commit message; git-svn
already knows how to rebuild rev_map files that get blown away, by
using the metadata.

This patch teaches git-svn do a partial rebuild of the rev_map to
match the true state of the branch, if it ever is used to fetch again.

This will only work for projects not using either noMetadata or
useSvmProps configuration options; if you are using these options,
git-svn will fall back to the previous behaviour.
Signed-off-by: NDeskin Miller <deskinm@umich.edu>
Acked-by: NEric Wong <normalperson@yhbt.net>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 9747deb7
...@@ -2626,9 +2626,9 @@ sub rebuild_from_rev_db { ...@@ -2626,9 +2626,9 @@ sub rebuild_from_rev_db {
sub rebuild { sub rebuild {
my ($self) = @_; my ($self) = @_;
my $map_path = $self->map_path; my $map_path = $self->map_path;
return if (-e $map_path && ! -z $map_path); my $partial = (-e $map_path && ! -z $map_path);
return unless ::verify_ref($self->refname.'^0'); return unless ::verify_ref($self->refname.'^0');
if ($self->use_svm_props || $self->no_metadata) { if (!$partial && ($self->use_svm_props || $self->no_metadata)) {
my $rev_db = $self->rev_db_path; my $rev_db = $self->rev_db_path;
$self->rebuild_from_rev_db($rev_db); $self->rebuild_from_rev_db($rev_db);
if ($self->use_svm_props) { if ($self->use_svm_props) {
...@@ -2638,10 +2638,13 @@ sub rebuild { ...@@ -2638,10 +2638,13 @@ sub rebuild {
$self->unlink_rev_db_symlink; $self->unlink_rev_db_symlink;
return; return;
} }
print "Rebuilding $map_path ...\n"; print "Rebuilding $map_path ...\n" if (!$partial);
my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
(undef, undef));
my ($log, $ctx) = my ($log, $ctx) =
command_output_pipe(qw/rev-list --pretty=raw --no-color --reverse/, command_output_pipe(qw/rev-list --pretty=raw --no-color --reverse/,
$self->refname, '--'); ($head ? "$head.." : "") . $self->refname,
'--');
my $metadata_url = $self->metadata_url; my $metadata_url = $self->metadata_url;
remove_username($metadata_url); remove_username($metadata_url);
my $svn_uuid = $self->ra_uuid; my $svn_uuid = $self->ra_uuid;
...@@ -2664,12 +2667,17 @@ sub rebuild { ...@@ -2664,12 +2667,17 @@ sub rebuild {
($metadata_url && $url && ($url ne $metadata_url))) { ($metadata_url && $url && ($url ne $metadata_url))) {
next; next;
} }
if ($partial && $head) {
print "Partial-rebuilding $map_path ...\n";
print "Currently at $base_rev = $head\n";
$head = undef;
}
$self->rev_map_set($rev, $c); $self->rev_map_set($rev, $c);
print "r$rev = $c\n"; print "r$rev = $c\n";
} }
command_close_pipe($log, $ctx); command_close_pipe($log, $ctx);
print "Done rebuilding $map_path\n"; print "Done rebuilding $map_path\n" if (!$partial || !$head);
my $rev_db_path = $self->rev_db_path; my $rev_db_path = $self->rev_db_path;
if (-f $self->rev_db_path) { if (-f $self->rev_db_path) {
unlink $self->rev_db_path or croak "unlink: $!"; unlink $self->rev_db_path or croak "unlink: $!";
...@@ -2809,6 +2817,12 @@ sub rev_map_set { ...@@ -2809,6 +2817,12 @@ sub rev_map_set {
sub rev_map_max { sub rev_map_max {
my ($self, $want_commit) = @_; my ($self, $want_commit) = @_;
$self->rebuild; $self->rebuild;
my ($r, $c) = $self->rev_map_max_norebuild($want_commit);
$want_commit ? ($r, $c) : $r;
}
sub rev_map_max_norebuild {
my ($self, $want_commit) = @_;
my $map_path = $self->map_path; my $map_path = $self->map_path;
stat $map_path or return $want_commit ? (0, undef) : 0; stat $map_path or return $want_commit ? (0, undef) : 0;
sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!"; sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
......
...@@ -49,7 +49,7 @@ test_expect_success 'make full git mirror of SVN' ' ...@@ -49,7 +49,7 @@ test_expect_success 'make full git mirror of SVN' '
) )
' '
test_expect_failure 'fetch from git mirror and partial-rebuild' ' test_expect_success 'fetch from git mirror and partial-rebuild' '
git config --add remote.origin.url "file://$PWD/mirror/.git" && git config --add remote.origin.url "file://$PWD/mirror/.git" &&
git config --add remote.origin.fetch refs/remotes/*:refs/remotes/* && git config --add remote.origin.fetch refs/remotes/*:refs/remotes/* &&
git fetch origin && git fetch origin &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册