copy+modify+commit and possible adjustment to internal datastructures (was Re: Invalid change ordering?)

Stephen Lee stephen.lee at hexagonmetrology.com
Tue Feb 13 08:51:15 EST 2007


Dirk wrote:
>
> I was confused by the fact, that VSS does not support "project" shares.
> Therefore I was wondering, how we could turn MOVEs into SHAREs.
>
To clarify, that's why I separated out a "file MOVE" and a "dir MOVE".

> I believe, that this problem is more or less a home made problem, due to
> incorrect MOVE merging. I would like to see a scenario, where this
> happens, and whether we can reliably share from the other parent.
>
ADD testfile.txt
SHARE testfile.txt $project1
MOVE $project1/testfile.txt $project2/testfile.txt
DELETE $project1

It might be helpful to consider a MOVE (of a file) to be deconstructed 
into a SHARE (at the target project) and a DELETE (at the source 
project). Come to think of it, for a *file* it could avoid the 
move_merge altogether. Is there ever a reason why vss2svn should 
consider the following two scenarios to be conceptually different?

Scenario 1:
SHARE location1/file location2/file
DELETE location1/file

Scenario 2:
MOVE location1/file location2

Even if the order of the actions get reversed I think this works...
Scenario 3:
DELETE location1/file
SHARE (physical file that was location1/file) location2/file

because vss2svn keys this off the physical name rather than path names.

It would be roughly equivalent to a similar scenario, but with a RECOVER 
rather than a SHARE (indeed RECOVER and SHARE seem so similar they could 
probably even use the same handler with a little tweaking, depending on 
how much you care about the aesthetics of where it appears to come from).

In all of these cases there are two nodes in the final output - an add+ 
and a delete.

Even on a project, a MOVE could in principle be split to a DELETE in one 
location and a RECOVER/SHARE at the other (something not possible in 
SourceSafe, but which the layout used by vss2svn's .tmp files allows). 
In principle, the only time the RECOVER/SHARE could occur without the 
DELETE would be when the dir is orphaned (otherwise the parent record 
would give the other half of the MOVE that translates to a DELETE...)

> >> > e) dir MOVE to/from an unknown location can become a MOVE to/from
> >> > orphaned
> Ok, this is already implemented. I simply did not understand exactly the
> meaning of the point
>
Implemented, but not working... see the attached updated version of the 
patch I did. The Dumpfile.pm change fixes a problem when doing a MOVE to 
the orphaned folder, and the ActionHandler.pm change fixes a problem 
that occurred for me when doing the later MOVE from the orphaned folder 
(but probably handles the attempt to issue a warning message 
incorrectly, and should probably also explicitly check for if the item 
is a dir, and whine even more loudly as it did not detect exactly one 
active copy).

> Naturally the whole structure grew up, while I was working on it. But
> the {pinned} field had some specific reason in a rename scenario. The
> problem is, that during a rename pinned files are also renamed. This is
> one of the "flaws" of VSS and plagued me in real life a few times.
>
Hmmm... well if you can get around that behaviour somehow, so a file 
remains pinned to the name it had when pinned, that would be even better ;)

Maybe even to go so far as a --renamepinnedfiles command line option.

The only instances of which I am aware in my repository, that a pinned 
file has been renamed, this was incorrect behaviour.


>  * vivid parents: contexts where renames are allowed
>
I'd noted the name "vivid" kicking around and never looked in to what it 
meant...

The proposed refactoring would still work, but keeping the indication of 
whether a file is live or merely "vivid"...


re: other mail:

 > Arrgh, I love it. what should happen if you destroy the parent project
 > in between?

Hmmmm... interesting way to be plain evil to the conversion script!

I think the best bet would be (if this is possible) to have the delete 
handler look-ahead. If the item is a dir, and is later restored, then 
continuity must be kept, so a delete then becomes a MOVE to orphaned. A 
file can safely be deleted, as a SHARE/RECOVER/COMMIT can get at the 
last known revision.

RECOVER would then always be a MOVE from orphaned (and this is the same 
action as SHARE will do when the orphaned item is the only one in 
existence... further reinforcing the possibility of merging at least the 
core of the RECOVER and SHARE handlers).

-- 
Stephen Lee <Stephen.Lee at hexagonmetrology.com>
Software Engineer, Vision Group - Pro-Measure Leader
Wilcox Associates Inc. (U.K.)

-------------- next part --------------
Index: vss2svn.pl
===================================================================
--- vss2svn.pl	(revision 300)
+++ vss2svn.pl	(working copy)
@@ -551,6 +551,7 @@
     AND author = ?
 ORDER BY
     ABS(? - timestamp)
+LIMIT 1
 EOSQL
 
     my $sth = $gCfg{dbh}->prepare($sql);
Index: Vss2Svn/ActionHandler.pm
===================================================================
--- Vss2Svn/ActionHandler.pm	(revision 300)
+++ Vss2Svn/ActionHandler.pm	(working copy)
@@ -424,14 +424,17 @@
 
     if (!defined $row->{parentphys}) {
       # Check if this is an orphaned item
-      if (scalar @{$physinfo->{order}} == 1) {
-        $row->{parentphys} = $physinfo->{order}[0];
+      # or if there is otherwise only one active item path
+      my @parents = $self->_get_active_parents ($row->{physname});
+      if (scalar @parents == 1) {
+        $row->{parentphys} = $parents[0];
       } else {
-        # Don't know from where to move. Share it there instead
+        $self->{errmsg} .= "Don't know from where to move $physname. Sharing instead.\n";
         $row->{parentphys} = $row->{info};
         $row->{info} = undef;
         $self->{action} = 'SHARE';
-        return $self->_share_handler();
+        $self->_share_handler();
+        return 0;
       }
     }
 
Index: Vss2Svn/Dumpfile.pm
===================================================================
--- Vss2Svn/Dumpfile.pm	(revision 300)
+++ Vss2Svn/Dumpfile.pm	(working copy)
@@ -400,7 +400,20 @@
             . "missing recover; skipping");
         return 0;
     }
-    
+
+    my $success = $self->{repository}->exists_parent ($newpath);
+    if(!defined($success)) {
+        $self->add_error("Attempt to move item '$itempath' to '$newpath' at "
+            . "revision $data->{revision_id}, but path consistency failure at dest");
+        return 0;
+    }
+    elsif ($success == 0) {
+        $self->add_error("Parent path missing while trying to move "
+            . "item '$itempath' to '$newpath' at "
+            . "revision $data->{revision_id}: adding missing parents");
+        $self->_create_svn_path ($nodes, $newpath);
+    }
+        
     my $node = Vss2Svn::Dumpfile::Node->new();
     $node->set_initial_props($newpath, $data);
     $node->{action} = 'add';


More information about the vss2svn-users mailing list