Example #1
0
        public void PegTests()
        {
            SvnSandBox sbox           = new SvnSandBox(this);
            Uri        CollabReposUri = sbox.CreateRepository(SandBoxRepository.MergeScenario);

            string dir = sbox.Wc;

            SvnUpdateResult result;

            Assert.That(Client.CheckOut(new SvnUriTarget(new Uri(CollabReposUri, "trunk")), dir, out result));

            long head = result.Revision;

            Assert.That(result.Revision, Is.EqualTo(head));

            Assert.That(Client.Switch(dir, new SvnUriTarget(new Uri(CollabReposUri, "branches/a")), out result));
            Assert.That(result.Revision, Is.EqualTo(head));

            Assert.That(Client.Switch(dir, new SvnUriTarget(new Uri(CollabReposUri, "branches/c"), head - 3), out result));
            Assert.That(result.Revision, Is.EqualTo(head - 3));

            SvnSwitchArgs sa = new SvnSwitchArgs();

            sa.Revision = head - 4;
            Assert.That(Client.Switch(dir, new SvnUriTarget(new Uri(CollabReposUri, "branches/b"), head - 5), sa, out result));
            Assert.That(result.Revision, Is.EqualTo(head - 4));

            sa          = new SvnSwitchArgs();
            sa.Revision = head - 7;
            Assert.That(Client.Switch(dir, new SvnUriTarget(new Uri(CollabReposUri, "branches/a")), sa, out result));
            Assert.That(result.Revision, Is.EqualTo(head - 7));
        }
Example #2
0
        public override void OnExecute(CommandEventArgs e)
        {
            SvnItem theItem = null;
            string  path;
            bool    allowObstructions = false;

            string projectRoot = e.GetService <IAnkhSolutionSettings>().ProjectRoot;

            if (e.Command == AnkhCommand.SolutionSwitchDialog)
            {
                path = projectRoot;
            }
            else if (e.Command == AnkhCommand.SwitchProject)
            {
                IProjectFileMapper mapper = e.GetService <IProjectFileMapper>();
                path = null;

                foreach (SccProject item in e.Selection.GetSelectedProjects(true))
                {
                    ISccProjectInfo pi = mapper.GetProjectInfo(item);

                    if (pi == null)
                    {
                        continue;
                    }

                    path = pi.ProjectDirectory;
                    break;
                }

                if (string.IsNullOrEmpty(path))
                {
                    return;
                }
            }
            else
            {
                foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false))
                {
                    if (item.IsVersioned)
                    {
                        theItem = item;
                        break;
                    }
                    return;
                }
                path = theItem.FullPath;
            }

            ISvnStatusCache statusCache = e.GetService <ISvnStatusCache>();

            SvnItem pathItem = statusCache[path];
            Uri     uri      = pathItem.Uri;

            if (uri == null)
            {
                return; // Should never happen on a real workingcopy
            }
            SvnUriTarget target;
            SvnRevision  revision = SvnRevision.None;

            if (e.Argument is string)
            {
                target   = SvnUriTarget.FromString((string)e.Argument, true);
                revision = (target.Revision != SvnRevision.None) ? target.Revision : SvnRevision.Head;
            }
            else if (e.Argument is Uri)
            {
                target = (Uri)e.Argument;
            }
            else
            {
                using (SwitchDialog dlg = new SwitchDialog())
                {
                    dlg.Context = e.Context;

                    dlg.LocalPath      = path;
                    dlg.RepositoryRoot = e.GetService <ISvnStatusCache>()[path].WorkingCopy.RepositoryRoot;
                    dlg.SwitchToUri    = uri;
                    dlg.Revision       = SvnRevision.Head;

                    if (dlg.ShowDialog(e.Context) != DialogResult.OK)
                    {
                        return;
                    }

                    target            = dlg.SwitchToUri;
                    revision          = dlg.Revision;
                    allowObstructions = dlg.AllowUnversionedObstructions;
                }
            }

            // Get a list of all documents below the specified paths that are open in editors inside VS
            HybridCollection <string> lockPaths       = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase);
            IAnkhOpenDocumentTracker  documentTracker = e.GetService <IAnkhOpenDocumentTracker>();

            foreach (string file in documentTracker.GetDocumentsBelow(path))
            {
                if (!lockPaths.Contains(file))
                {
                    lockPaths.Add(file);
                }
            }

            documentTracker.SaveDocuments(lockPaths); // Make sure all files are saved before merging!

            using (DocumentLock lck = documentTracker.LockDocuments(lockPaths, DocumentLockType.NoReload))
                using (lck.MonitorChangesForReload())
                {
                    Uri newRepositoryRoot = null;
                    e.GetService <IProgressRunner>().RunModal(CommandStrings.SwitchingTitle,
                                                              delegate(object sender, ProgressWorkerArgs a)
                    {
                        SvnSwitchArgs args     = new SvnSwitchArgs();
                        args.AllowObstructions = allowObstructions;
                        args.AddExpectedError(SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH);

                        if (revision != SvnRevision.None)
                        {
                            args.Revision = revision;
                        }

                        e.GetService <IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer);
                        if (!a.Client.Switch(path, target, args))
                        {
                            if (args.LastException.SvnErrorCode != SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH)
                            {
                                return;
                            }

                            // source/target repository is different, check if we can fix this by relocating
                            SvnInfoEventArgs iea;
                            if (a.Client.GetInfo(target, out iea))
                            {
                                if (pathItem.WorkingCopy.RepositoryId != iea.RepositoryId)
                                {
                                    e.Context.GetService <IAnkhDialogOwner>()
                                    .MessageBox.Show("Cannot switch to different repository because the repository UUIDs are different",
                                                     "Cannot switch", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                }
                                else if (pathItem.WorkingCopy.RepositoryRoot != iea.RepositoryRoot)
                                {
                                    newRepositoryRoot = iea.RepositoryRoot;
                                }
                                else if (pathItem.WorkingCopy.RepositoryId == Guid.Empty)
                                {
                                    // No UUIDs and RepositoryRoot equal. Throw/show error?

                                    throw args.LastException;
                                }
                            }
                        }
                    });

                    if (newRepositoryRoot != null && DialogResult.Yes == e.Context.GetService <IAnkhDialogOwner>()
                        .MessageBox.Show(string.Format("The repository root specified is different from the one in your " +
                                                       "working copy. Would you like to relocate '{0}' from '{1}' to '{2}'?",
                                                       pathItem.WorkingCopy.FullPath,
                                                       pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot),
                                         "Relocate", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                        // We can fix this by relocating
                        string wcRoot = pathItem.WorkingCopy.FullPath;
                        try
                        {
                            e.GetService <IProgressRunner>().RunModal(
                                CommandStrings.RelocatingTitle,
                                delegate(object sender, ProgressWorkerArgs a)
                            {
                                a.Client.Relocate(wcRoot, pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot);
                            });
                        }
                        finally
                        {
                            statusCache.MarkDirtyRecursive(wcRoot);
                            e.GetService <IFileStatusMonitor>().ScheduleGlyphUpdate(statusCache.GetCachedBelow(wcRoot));
                        }


                        if (DialogResult.Yes == e.Context.GetService <IAnkhDialogOwner>()
                            .MessageBox.Show(string.Format("Would you like to try to switch '{0}' to '{1}' again?",
                                                           path, target),
                                             "Switch", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                        {
                            // Try to switch again
                            e.GetService <IProgressRunner>().RunModal(
                                CommandStrings.SwitchingTitle,
                                delegate(object sender, ProgressWorkerArgs a)
                            {
                                SvnSwitchArgs args = new SvnSwitchArgs();

                                if (revision != SvnRevision.None)
                                {
                                    args.Revision = revision;
                                }

                                args.AllowObstructions = allowObstructions;

                                e.GetService <IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer);
                                a.Client.Switch(path, target, args);
                            });
                        }
                    }
                }
        }
Example #3
0
        public override void OnExecute(CommandEventArgs e)
        {
            SvnItem theItem = null;
            string path;
            bool allowObstructions = false;

            string projectRoot = e.GetService<IAnkhSolutionSettings>().ProjectRoot;

            if (e.Command == AnkhCommand.SolutionSwitchDialog)
                path = projectRoot;
            else if (e.Command == AnkhCommand.SwitchProject)
            {
                IProjectFileMapper mapper = e.GetService<IProjectFileMapper>();
                path = null;

                foreach (SvnProject item in e.Selection.GetSelectedProjects(true))
                {
                    ISvnProjectInfo pi = mapper.GetProjectInfo(item);

                    if (pi == null)
                        continue;

                    path = pi.ProjectDirectory;
                    break;
                }

                if (string.IsNullOrEmpty(path))
                    return;
            }
            else
            {
                foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false))
                {
                    if (item.IsVersioned)
                    {
                        theItem = item;
                        break;
                    }
                    return;
                }
                path = theItem.FullPath;
            }

            IFileStatusCache statusCache = e.GetService<IFileStatusCache>();

            SvnItem pathItem = statusCache[path];
            Uri uri = pathItem.Uri;

            if (uri == null)
                return; // Should never happen on a real workingcopy

            SvnUriTarget target;
            SvnRevision revision = SvnRevision.None;

            if (e.Argument is string)
            {
                target = SvnUriTarget.FromString((string)e.Argument, true);
                revision = (target.Revision != SvnRevision.None) ? target.Revision : SvnRevision.Head;
            }
            else if (e.Argument is Uri)
                target = (Uri)e.Argument;
            else
                using (SwitchDialog dlg = new SwitchDialog())
                {
                    dlg.Context = e.Context;

                    dlg.LocalPath = path;
                    dlg.RepositoryRoot = e.GetService<IFileStatusCache>()[path].WorkingCopy.RepositoryRoot;
                    dlg.SwitchToUri = uri;
                    dlg.Revision = SvnRevision.Head;

                    if (dlg.ShowDialog(e.Context) != DialogResult.OK)
                        return;

                    target = dlg.SwitchToUri;
                    revision = dlg.Revision;
                    allowObstructions = dlg.AllowUnversionedObstructions;
                }

            // Get a list of all documents below the specified paths that are open in editors inside VS
            HybridCollection<string> lockPaths = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase);
            IAnkhOpenDocumentTracker documentTracker = e.GetService<IAnkhOpenDocumentTracker>();

            foreach (string file in documentTracker.GetDocumentsBelow(path))
            {
                if (!lockPaths.Contains(file))
                    lockPaths.Add(file);
            }

            documentTracker.SaveDocuments(lockPaths); // Make sure all files are saved before merging!

            using (DocumentLock lck = documentTracker.LockDocuments(lockPaths, DocumentLockType.NoReload))
            using (lck.MonitorChangesForReload())
            {
                Uri newRepositoryRoot = null;
                e.GetService<IProgressRunner>().RunModal(
                    "Switching",
                    delegate(object sender, ProgressWorkerArgs a)
                    {
                        SvnSwitchArgs args = new SvnSwitchArgs();
                        args.AllowObstructions = allowObstructions;
                        args.AddExpectedError(SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH);

                        if (revision != SvnRevision.None)
                            args.Revision = revision;

                        e.GetService<IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer);
                        if (!a.Client.Switch(path, target, args))
                        {
                            if (args.LastException.SvnErrorCode != SvnErrorCode.SVN_ERR_WC_INVALID_SWITCH)
                                return;

                            // source/target repository is different, check if we can fix this by relocating
                            SvnInfoEventArgs iea;
                            if (a.Client.GetInfo(target, out iea))
                            {
                                if (pathItem.WorkingCopy.RepositoryId != iea.RepositoryId)
                                {
                                    e.Context.GetService<IAnkhDialogOwner>()
                                        .MessageBox.Show("Cannot switch to different repository because the repository UUIDs are different",
                                        "Cannot switch", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                }
                                else if (pathItem.WorkingCopy.RepositoryRoot != iea.RepositoryRoot)
                                {
                                    newRepositoryRoot = iea.RepositoryRoot;
                                }
                                else if (pathItem.WorkingCopy.RepositoryId == Guid.Empty)
                                {
                                    // No UUIDs and RepositoryRoot equal. Throw/show error?

                                    throw args.LastException;
                                }
                            }
                        }
                    });

                if (newRepositoryRoot != null && DialogResult.Yes == e.Context.GetService<IAnkhDialogOwner>()
                   .MessageBox.Show(string.Format("The repository root specified is different from the one in your " +
                   "working copy. Would you like to relocate from '{0}' to '{1}'?",
                   pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot),
                   "Relocate", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    // We can fix this by relocating
                    try
                    {
                        e.GetService<IProgressRunner>().RunModal(
                            "Relocating",
                            delegate(object sender, ProgressWorkerArgs a)
                            {
                                a.Client.Relocate(path, pathItem.WorkingCopy.RepositoryRoot, newRepositoryRoot);
                            });
                    }
                    finally
                    {
                        statusCache.MarkDirtyRecursive(path);
                        e.GetService<IFileStatusMonitor>().ScheduleGlyphUpdate(SvnItem.GetPaths(statusCache.GetCachedBelow(path)));
                    }

                    if (DialogResult.Yes == e.Context.GetService<IAnkhDialogOwner>()
                        .MessageBox.Show(string.Format("Would you like to try to switch '{0}' to '{1}' again?",
                        path, target),
                        "Switch", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                        // Try to switch again
                        e.GetService<IProgressRunner>().RunModal(
                        "Switching",
                        delegate(object sender, ProgressWorkerArgs a)
                        {
                            SvnSwitchArgs args = new SvnSwitchArgs();

                            if (revision != SvnRevision.None)
                                args.Revision = revision;

                            args.AllowObstructions = allowObstructions;

                            e.GetService<IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer);
                            a.Client.Switch(path, target, args);
                        });
                    }
                }
            }
        }