Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move/Rename/Remove problems and how I fixed them #62

Open
AxelWS opened this issue Sep 6, 2021 · 1 comment
Open

Move/Rename/Remove problems and how I fixed them #62

AxelWS opened this issue Sep 6, 2021 · 1 comment

Comments

@AxelWS
Copy link

AxelWS commented Sep 6, 2021

Hi to all who still have to migrate code from VSS.

I understand this repository is still open for discussions, so I'd like to discuss some fixes I did.
My code is based on branch axel-ws.

While importing some new VSS .ssa re-imported code I got an error about not being able to move a renamed file.
I changed "File.Delete(targetPath);" into "git.Remove(targetPath, false);" in "case VssActionType.Delete:" in method ReplayRevision to get around this because both changes should be ok to be in a single commit.

Also I got an error about an edited file being deleted in the same commit. Maybe in such a case one would like to split it into two commits, but I decided we are not interested in such temporary short-term changes and just do the above "git.Remove" with a "-f" to force the remove.

After importing I found that some files/folders were not moved properly and old duplicate files were left hanging around.

I did not fully understand why this happens, but I noted that things go very much differently depending on the order in which MoveFrom and MoveTo actions are replayed.
I enforced MoveFrom to be replayed before MoveTo by adding a few lines like these to RevisionAnalyzer.SortRevisions (on branch axel-ws):

        // MoveFrom must be done before MoveTo (if any)
        // There is not always a matching pair, especially if we work on a restored .ssa export.
        // Matching MoveFrom/MoveTo pairs move the same item, have (nearly?) the same time, and the same user.
        var moveToRevisions = sortedRevisions
            .Where(s => s.revision.Action.Type == VssActionType.MoveTo)
            .ToList();
        var moveFromRevisions = sortedRevisions
            .Where(s => s.revision.Action.Type == VssActionType.MoveFrom)
            .ToList();
        foreach (var moveFromRevision in moveFromRevisions)
        {
            string item = ((VssMoveFromAction) moveFromRevision.revision.Action).Name.PhysicalName;
            string user = moveFromRevision.revision.User;
            var matches = moveToRevisions
                .Where(s => item == ((VssMoveToAction)s.revision.Action).Name.PhysicalName && user == s.revision.User)
                .Where(s => Math.Abs((s.dateTime - moveFromRevision.dateTime).TotalSeconds) < 1.5)
                .ToList();
            Debug.Assert(matches.Count <= 1);
            foreach (SortableRevision moveToRevision in matches)
            {
                graph.AddOrderEdge(moveFromRevision, moveToRevision);
            }
        }

With this change, project move operations that have a MoveFrom action are consistently done via git.Move (or Directory.Move if they are empty).

After that I still got an error because a move operation expects the target folder to exist, so I added "Directory.CreateDirectory(targetDirectory);" before "git.Move" and "Directory.Move" in GitExporter.

Now the next import went much more smoothly, but still one folder was moved using the wrong project name in target path.
The project was added via MoveFrom action (because it was created in a project that was not contained in the imported .ssa) and the project was renamed later. There is already a fix "update name of item in case it was created on demand [...]" for this in VssPathMapper.AddItem, which seems to be missing in VssPathMapper.MoveProjectFrom.
I decided to treat MoveFrom just like an Add action, at least if there is no source path to move from. To do so I changed VssPathMapper.MoveProjectFrom to a single line "return (VssProjectInfo) AddItem(project, subproject);" and replaced "writeProject = true;" with "itemInfo = projectInfo; isAddAction = true;" in GitExporter.

If you know better fixes - preferably ones that are better tested than my fixes ;^) - please let us know.

@erezwanderman
Copy link

My way to handle such problems was to to set "Combine revisions within _ seconds, regardless of the comment." to 0.
I suspect it might cause the process to take much more time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants