git-svn: disallow ambigious local refspecs
authorEric Wong <normalperson@yhbt.net>
Mon, 22 Jan 2007 21:52:04 +0000 (13:52 -0800)
committerEric Wong <normalperson@yhbt.net>
Fri, 23 Feb 2007 08:57:09 +0000 (00:57 -0800)
Having multiple fetch refspecs pointing to the same local ref
would be a very bad thing. Start avoiding the use of fatal() or
exit() inside the modules so we can libify more easily.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn.perl
t/t9100-git-svn-basic.sh
index 84f467957030ae9249a9e3d669449295fd99c90d..f01fb9a35d55dd2e6499ef0df884188f5c839910 100755 (executable)
@@ -169,7 +169,11 @@ BEGIN
 unless ($cmd =~ /^(?:init|rebuild|multi-init|commit-diff)$/) {
        Git::SVN::Migration::migration_check();
 }
-$cmd{$cmd}->[0]->(@ARGV);
+eval {
+       Git::SVN::verify_remotes_sanity();
+       $cmd{$cmd}->[0]->(@ARGV);
+};
+fatal $@ if $@;
 exit 0;
 
 ####################### primary functions ######################
@@ -715,6 +719,22 @@ sub read_all_remotes {
        $r;
 }
 
+sub verify_remotes_sanity {
+       my %seen;
+       foreach (command(qw/config -l/)) {
+               if (m!^svn-remote\.(?:.+)\.fetch=.*:refs/remotes/(\S+)\s*$!) {
+                       if ($seen{$1}) {
+                               die "Remote ref refs/remote/$1 is tracked by",
+                                   "\n  \"$_\"\nand\n  \"$seen{$1}\"\n",
+                                   "Please resolve this ambiguity in ",
+                                   "your git configuration file before ",
+                                   "continuing\n";
+                       }
+                       $seen{$1} = $_;
+               }
+       }
+}
+
 # we allow more chars than remotes2config.sh...
 sub sanitize_remote_name {
        my ($name) = @_;
@@ -727,16 +747,22 @@ sub init {
        my $self = _new($class, $repo_id, $ref_id, $path);
        if (defined $url) {
                $url =~ s!/+$!!; # strip trailing slash
+
+               # verify that we aren't overwriting anything:
                my $orig_url = eval {
                        command_oneline('config', '--get',
                                        "svn-remote.$repo_id.url")
                };
-               if ($orig_url) {
-                       if ($orig_url ne $url) {
-                               die "svn-remote.$repo_id.url already set: ",
-                                   "$orig_url\nwanted to set to: $url\n";
-                       }
-               } else {
+               if ($orig_url && ($orig_url ne $url)) {
+                       die "svn-remote.$repo_id.url already set: ",
+                           "$orig_url\nwanted to set to: $url\n";
+               }
+               my ($xrepo_id, $xpath) = find_ref($self->refname);
+               if (defined $xpath) {
+                       die "svn-remote.$xrepo_id.fetch already set to track ",
+                           "$xpath:refs/remotes/", $self->refname, "\n";
+               }
+               if (!$orig_url) {
                        command_noisy('config',
                                      "svn-remote.$repo_id.url", $url);
                }
index 040da92756787371d584f33b53b54a3fc84f55b1..af617486dda5194a5fb21e6e6536952b37ac7fb1 100755 (executable)
@@ -215,4 +215,15 @@ echo tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 >> expected
 
 test_expect_success "$name" "diff -u a expected"
 
+test_expect_failure 'exit if remote refs are ambigious' "
+        git-repo-config --add svn-remote.git-svn.fetch \
+                              bar:refs/remotes/git-svn &&
+        git-svn migrate
+        "
+test_expect_failure 'exit if init-ing a would clobber a URL' "
+        git-repo-config --unset svn-remote.git-svn.fetch \
+                                '^bar:refs/remotes/git-svn$' &&
+        git-svn init $svnrepo/bar
+        "
+
 test_done