static void Resolve(CommandEventArgs e, SvnAccept accept) { HybridCollection <string> paths = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); foreach (SvnItem item in e.Selection.GetSelectedSvnItems(true)) { if (!item.IsConflicted) { continue; } if (!paths.Contains(item.FullPath)) { paths.Add(item.FullPath); } } IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); documentTracker.SaveDocuments(paths); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(paths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) using (SvnClient client = e.GetService <ISvnClientPool>().GetNoUIClient()) { SvnResolveArgs a = new SvnResolveArgs(); a.Depth = SvnDepth.Empty; foreach (string p in paths) { client.Resolve(p, accept, a); } } }
private IDisposable MarkIgnoreRecursive(string newDir) { ThreadHelper.ThrowIfNotOnUIThread(); IAnkhOpenDocumentTracker dt = GetService <IAnkhOpenDocumentTracker>(); IVsFileChangeEx change = GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); if (dt == null || change == null) { return(null); } ICollection <string> files = dt.GetDocumentsBelow(newDir); if (files == null || files.Count == 0) { return(null); } foreach (string file in files) { Marshal.ThrowExceptionForHR(change.IgnoreFile(0, file, 1)); } return(new DelegateRunner( delegate() { ThreadHelper.ThrowIfNotOnUIThread(); foreach (string file in files) { change.SyncFile(file); change.IgnoreFile(0, file, 0); } })); }
public void Dispose() { if (_cookie != 0) { uint ck = _cookie; _cookie = 0; IVsFileChangeEx fx = GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); if (fx != null) { if (!_monitorDir) { fx.UnadviseFileChange(ck); } else { fx.UnadviseDirChange(ck); } } } if (_odt != null) { _odt.IgnoreChanges(_toMonitor, false); _odt = null; } }
public override void OnExecute(CommandEventArgs e) { List <SvnItem> toResolve = new List <SvnItem>(); foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false)) { if (item.IsCasingConflicted) { toResolve.Add(item); } } try { foreach (SvnItem item in toResolve) { string svnPath = GetSvnCasing(item); string actualPath = SvnTools.GetTruePath(item.FullPath); if (svnPath == null || actualPath == null) { continue; // not found } if (!string.Equals(svnPath, actualPath, StringComparison.OrdinalIgnoreCase)) { continue; // More than casing rename } string svnName = Path.GetFileName(svnPath); string actualName = Path.GetFileName(actualPath); if (svnName == actualName) { continue; // Can't fix directories! } IAnkhOpenDocumentTracker odt = e.GetService <IAnkhOpenDocumentTracker>(); using (odt.LockDocument(svnPath, DocumentLockType.NoReload)) using (odt.LockDocument(actualPath, DocumentLockType.NoReload)) { try { // Try the actual rename File.Move(actualPath, svnPath); } catch { } try { // And try to fix the project+document system VsShellUtilities.RenameDocument(e.Context, actualPath, svnPath); } catch { } } } } finally { e.GetService <IFileStatusMonitor>().ScheduleSvnStatus(SvnItem.GetPaths(toResolve)); } }
/// <see cref="Ankh.Commands.ICommandHandler.OnExecute" /> public void OnExecute(CommandEventArgs e) { List <SvnItem> svnItems = new List <SvnItem>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); switch (e.Command) { case AnkhCommand.ItemMerge: // TODO: Check for solution and/or project selection to use the folder instead of the file foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false)) { svnItems.Add(item); } break; case AnkhCommand.ProjectMerge: foreach (SccProject p in e.Selection.GetSelectedProjects(false)) { IProjectFileMapper pfm = e.GetService <IProjectFileMapper>(); ISccProjectInfo info = pfm.GetProjectInfo(p); if (info != null && info.ProjectDirectory != null) { svnItems.Add(cache[info.ProjectDirectory]); } } break; case AnkhCommand.SolutionMerge: svnItems.Add(cache[e.GetService <IAnkhSolutionSettings>().ProjectRoot]); break; default: throw new InvalidOperationException(); } IEnumerable <string> selectedFiles = e.Selection.GetSelectedFiles(true); IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); using (DocumentLock lck = tracker.LockDocuments(selectedFiles, DocumentLockType.ReadOnly)) using (lck.MonitorChangesForReload()) using (MergeWizard dialog = new MergeWizard(e.Context, svnItems[0])) { DialogResult result = dialog.ShowDialog(e.Context); //result = uiService.ShowDialog(dialog); if (result == DialogResult.OK) { using (MergeResultsDialog mrd = new MergeResultsDialog()) { mrd.MergeActions = dialog.MergeActions; mrd.ResolvedMergeConflicts = dialog.ResolvedMergeConflicts; mrd.ShowDialog(e.Context); } } } }
public DiffToolMonitor(IAnkhServiceProvider context, string monitor, bool monitorDir, int[] resolvedExitCodes) : base(context) { ThreadHelper.ThrowIfNotOnUIThread(); if (string.IsNullOrEmpty(monitor)) { throw new ArgumentNullException("monitor"); } else if (!SvnItem.IsValidPath(monitor)) { throw new ArgumentOutOfRangeException("monitor"); } _monitorDir = monitorDir; _toMonitor = monitor; IVsFileChangeEx fx = GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); _cookie = 0; if (fx == null) { } else if (!_monitorDir) { if (!VSErr.Succeeded(fx.AdviseFileChange(monitor, (uint)(_VSFILECHANGEFLAGS.VSFILECHG_Time | _VSFILECHANGEFLAGS.VSFILECHG_Size | _VSFILECHANGEFLAGS.VSFILECHG_Add | _VSFILECHANGEFLAGS.VSFILECHG_Del | _VSFILECHANGEFLAGS.VSFILECHG_Attr), this, out _cookie))) { _cookie = 0; } } else { if (!VSErr.Succeeded(fx.AdviseDirChange(monitor, 1, this, out _cookie))) { _cookie = 0; } } IAnkhOpenDocumentTracker odt = GetService <IAnkhOpenDocumentTracker>(); if (odt != null) { if (odt.IgnoreChanges(_toMonitor, true)) { _odt = odt; } } if (resolvedExitCodes != null) { _resolvedExitCodes = (int[])resolvedExitCodes.Clone(); } }
/// <summary> /// Save all documents in the selection /// </summary> /// <param name="state">The state.</param> /// <returns></returns> private bool PreCommit_SaveDirty(PendingCommitState state) { IAnkhOpenDocumentTracker tracker = state.GetService <IAnkhOpenDocumentTracker>(); if (!tracker.SaveDocuments(state.CommitPaths)) { state.MessageBox.Show(PccStrings.FailedToSaveBeforeCommit, "", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); return(false); } return(true); }
public void Dispose() { _disposed = true; IAnkhOpenDocumentTracker tracker = GetService <IAnkhOpenDocumentTracker>(typeof(IAnkhOpenDocumentTracker)); if (tracker != null) { tracker.DoDispose(this); } HookFileChanges(false); }
private void SetDirty() { ThreadHelper.ThrowIfNotOnUIThread(); if (!_loaded) return; // The project is just loading.. don't set it dirty else if (string.IsNullOrEmpty(ProjectFile)) return; // No file to set dirty IAnkhOpenDocumentTracker dt = _context.GetService<IAnkhOpenDocumentTracker>(); dt.CheckDirty(ProjectFile); }
public override void RefreshList() { Context.GetService <ISvnStatusCache>().ClearCache(); IAnkhOpenDocumentTracker dt = Context.GetService <IAnkhOpenDocumentTracker>(); if (dt != null) { dt.RefreshDirtyState(); } Manager.FullRefresh(true); }
private void SetDirty() { if (!_loaded) { return; // The project is just loading.. don't set it dirty } else if (string.IsNullOrEmpty(ProjectFile)) { return; // No file to set dirty } IAnkhOpenDocumentTracker dt = _context.GetService <IAnkhOpenDocumentTracker>(); dt.CheckDirty(ProjectFile); }
public void Dispose() { ThreadHelper.ThrowIfNotOnUIThread(); _disposed = true; IAnkhOpenDocumentTracker tracker = GetService <IAnkhOpenDocumentTracker>(typeof(IAnkhOpenDocumentTracker)); if (tracker != null) { tracker.DoDispose(this); } HookFileChanges(false); }
void UpdateDocumentInfo() { IAnkhOpenDocumentTracker dt = _context.GetService <IAnkhOpenDocumentTracker>(); if (dt == null) { // We /must/ make the state not dirty SetState(GitItemState.None, GitItemState.DocumentDirty); return; } if (dt.IsDocumentDirty(FullPath, true)) { SetState(GitItemState.DocumentDirty, GitItemState.None); } else { SetState(GitItemState.None, GitItemState.DocumentDirty); } }
public override void OnExecute(CommandEventArgs e) { // Refresh all global states on the selected files // * File Status Cache // * Glyph cache (in VS Projects) // * Pending changes // * Editor dirty state // Don't handle individual windows here, they can just override the refresh handler // See WorkingCopyExplorerControl.OnFrameCreated() for some examples on how to do that IFileStatusMonitor monitor = e.GetService <IFileStatusMonitor>(); monitor.ScheduleSvnStatus(e.Selection.GetSelectedFiles(true)); IAnkhOpenDocumentTracker dt = e.GetService <IAnkhOpenDocumentTracker>(); dt.RefreshDirtyState(); IPendingChangesManager pm = e.GetService <IPendingChangesManager>(); pm.Refresh((string)null); // Perform a full incremental refresh on the PC window }
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); }); } } } }
public override void OnExecute(CommandEventArgs e) { string argumentFile = e.Argument as string; List <SvnItem> selection = new List <SvnItem>(); if (string.IsNullOrEmpty(argumentFile)) { if (e.ShouldPrompt(true)) { selection.AddRange(e.Selection.GetSelectedSvnItems(true)); using (PendingChangeSelector pcs = new PendingChangeSelector()) { pcs.Text = CommandStrings.AddDialogTitle; pcs.PreserveWindowPlacement = true; pcs.LoadItems(selection, delegate(SvnItem item) { return(!item.IsVersioned && item.IsVersionable); }, delegate(SvnItem item) { if (item.IsIgnored) { return(false); } else if (item.IsSccExcluded) { return(false); } return(item.InSolution); }); if (pcs.ShowDialog(e.Context) != DialogResult.OK) { return; } selection.Clear(); selection.AddRange(pcs.GetSelectedItems()); } } else { foreach (SvnItem item in e.Selection.GetSelectedSvnItems(true)) { if (!item.IsVersioned && item.IsVersionable && !item.IsIgnored && item.InSolution) { selection.Add(item); } } } } else { selection.Add(e.GetService <ISvnStatusCache>()[argumentFile]); } ICollection <string> paths = SvnItem.GetPaths(selection); IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); documentTracker.SaveDocuments(paths); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(paths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) e.GetService <IProgressRunner>().RunModal(CommandStrings.AddTaskDialogTitle, delegate(object sender, ProgressWorkerArgs ee) { SvnAddArgs args = new SvnAddArgs(); args.Depth = SvnDepth.Empty; args.AddParents = true; foreach (SvnItem item in selection) { ee.Client.Add(item.FullPath, args); } }); }
static bool CheckoutWorkingCopyForSolution(CommandEventArgs e, ref bool confirmed) { using (SvnClient cl = e.GetService <ISvnClientPool>().GetClient()) using (AddToSubversion dialog = new AddToSubversion()) { dialog.PathToAdd = e.Selection.SolutionFilename; if (e.Argument is IAnkhSccService) { dialog.CommitAllVisible = false; dialog.CommitAllFiles = false; } else { dialog.CommitAllFiles = true; } if (dialog.ShowDialog(e.Context) != DialogResult.OK) { return(false); // Don't set as managed by AnkhSVN } confirmed = true; if (dialog.CommitAllFiles) { HybridCollection <string> allFiles = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); string logMessage; string wcPath = dialog.WorkingCopyDir; Uri reposUrl = dialog.RepositoryAddUrl; allFiles.UniqueAddRange(e.GetService <IProjectFileMapper>().GetAllFilesOfAllProjects(true)); using (CreateDirectoryDialog dlg = new CreateDirectoryDialog()) { dlg.Text = CommandStrings.ImportingTitle; dlg.NewDirectoryName = dialog.RepositoryAddUrl.ToString(); dlg.NewDirectoryReadonly = true; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return(false); } logMessage = dlg.LogMessage; } IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); documentTracker.SaveDocuments(allFiles); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(allFiles, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { e.GetService <IProgressRunner>().RunModal(CommandStrings.ImportingTitle, delegate(object sender, ProgressWorkerArgs a) { SvnImportArgs importArgs = new SvnImportArgs(); importArgs.LogMessage = logMessage; importArgs.Filter += delegate(object ieSender, SvnImportFilterEventArgs ie) { if (ie.NodeKind != SvnNodeKind.Directory) { ie.Filter = !allFiles.Contains(ie.FullPath); } else { bool filter = true; foreach (string p in allFiles) { if (SvnItem.IsBelowRoot(p, ie.FullPath)) { filter = false; break; } } if (filter) { ie.Filter = true; } } }; a.Client.Import(wcPath, reposUrl, importArgs); }); } } else { Collection <SvnInfoEventArgs> info; SvnInfoArgs ia = new SvnInfoArgs(); ia.ThrowOnError = false; if (!cl.GetInfo(dialog.RepositoryAddUrl, ia, out info)) { // Target uri doesn't exist in the repository, let's create if (!RemoteCreateDirectory(e, dialog.Text, dialog.RepositoryAddUrl, cl)) { return(false); // Create failed; bail out } } // Create working copy SvnCheckOutArgs coArg = new SvnCheckOutArgs(); coArg.AllowObstructions = true; cl.CheckOut(dialog.RepositoryAddUrl, dialog.WorkingCopyDir, coArg); // Add solutionfile so we can set properties (set managed) AddPathToSubversion(e, e.Selection.SolutionFilename); IAnkhSolutionSettings settings = e.GetService <IAnkhSolutionSettings>(); IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); IFileStatusMonitor monitor = e.GetService <IFileStatusMonitor>(); settings.ProjectRoot = SvnTools.GetNormalizedFullPath(dialog.WorkingCopyDir); if (monitor != null && mapper != null) { // Make sure all visible glyphs are updated to reflect a new working copy monitor.ScheduleSvnStatus(mapper.GetAllFilesOfAllProjects()); } } return(true); } }
public void OnExecute(CommandEventArgs e) { ILogControl logWindow = e.Selection.GetActiveControl <ILogControl>(); IProgressRunner progressRunner = e.GetService <IProgressRunner>(); if (logWindow == null) { return; } List <SvnRevisionRange> revisions = new List <SvnRevisionRange>(); if (e.Command == AnkhCommand.LogRevertTo) { ISvnLogItem item = EnumTools.GetSingle(e.Selection.GetSelection <ISvnLogItem>()); if (item == null) { return; } // Revert to revision, is revert everything after revisions.Add(new SvnRevisionRange(SvnRevision.Working, item.Revision)); } else { foreach (ISvnLogItem item in e.Selection.GetSelection <ISvnLogItem>()) { revisions.Add(new SvnRevisionRange(item.Revision, item.Revision - 1)); } } if (revisions.Count == 0) { return; } IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); HybridCollection <string> nodes = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); foreach (SvnOrigin o in logWindow.Origins) { SvnPathTarget pt = o.Target as SvnPathTarget; if (pt == null) { continue; } foreach (string file in tracker.GetDocumentsBelow(pt.FullPath)) { if (!nodes.Contains(file)) { nodes.Add(file); } } } if (nodes.Count > 0) { tracker.SaveDocuments(nodes); // Saves all open documents below all specified origins } using (DocumentLock dl = tracker.LockDocuments(nodes, DocumentLockType.NoReload)) using (dl.MonitorChangesForReload()) { SvnMergeArgs ma = new SvnMergeArgs(); progressRunner.RunModal(LogStrings.Reverting, delegate(object sender, ProgressWorkerArgs ee) { foreach (SvnOrigin item in logWindow.Origins) { SvnPathTarget target = item.Target as SvnPathTarget; if (target == null) { continue; } ee.Client.Merge(target.FullPath, target, revisions, ma); } }); } }
public override void OnExecute(CommandEventArgs e) { List <SvnItem> toRevert = new List <SvnItem>(); HybridCollection <string> contained = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); HybridCollection <string> checkedItems = null; foreach (SvnItem i in e.Selection.GetSelectedSvnItems(false)) { if (contained.Contains(i.FullPath)) { continue; } contained.Add(i.FullPath); if (i.IsModified || (i.IsVersioned && i.IsDocumentDirty) || i.IsConflicted) { toRevert.Add(i); } } Predicate <SvnItem> initialCheckedFilter = null; if (toRevert.Count > 0) { checkedItems = new HybridCollection <string>(contained, StringComparer.OrdinalIgnoreCase); initialCheckedFilter = delegate(SvnItem item) { return(checkedItems.Contains(item.FullPath)); }; } foreach (SvnItem i in e.Selection.GetSelectedSvnItems(true)) { if (contained.Contains(i.FullPath)) { continue; } contained.Add(i.FullPath); if (i.IsModified || (i.IsVersioned && i.IsDocumentDirty)) { toRevert.Add(i); } } if (e.PromptUser || (!e.DontPrompt && !Shift)) { using (PendingChangeSelector pcs = new PendingChangeSelector()) { pcs.Text = CommandStrings.RevertDialogTitle; pcs.PreserveWindowPlacement = true; pcs.LoadItems(toRevert, null, initialCheckedFilter); if (pcs.ShowDialog(e.Context) != DialogResult.OK) { return; } toRevert.Clear(); toRevert.AddRange(pcs.GetSelectedItems()); } } IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); ICollection <string> revertPaths = SvnItem.GetPaths(toRevert); documentTracker.SaveDocuments(revertPaths); // Revert items backwards to make sure we revert children before their ancestors toRevert.Sort(delegate(SvnItem i1, SvnItem i2) { bool add1 = i1.IsAdded || i1.IsReplaced; bool add2 = i2.IsAdded || i2.IsReplaced; if (add1 && !add2) { return(-1); } else if (add2 && !add1) { return(1); } else if (add1 && add2) { return(-StringComparer.OrdinalIgnoreCase.Compare(i1.FullPath, i2.FullPath)); } return(StringComparer.OrdinalIgnoreCase.Compare(i1.FullPath, i2.FullPath)); }); // perform the actual revert using (DocumentLock dl = documentTracker.LockDocuments(revertPaths, DocumentLockType.NoReload)) using (dl.MonitorChangesForReload()) { e.GetService <IProgressRunner>().RunModal(CommandStrings.Reverting, delegate(object sender, ProgressWorkerArgs a) { SvnRevertArgs ra = new SvnRevertArgs(); ra.AddExpectedError(SvnErrorCode.SVN_ERR_WC_NOT_DIRECTORY, SvnErrorCode.SVN_ERR_WC_INVALID_OPERATION_DEPTH); // Parent revert invalidated this change ra.Depth = SvnDepth.Empty; List <SvnItem> toRevertWithInfinity = new List <SvnItem>(); foreach (SvnItem item in toRevert) { if (!a.Client.Revert(item.FullPath, ra)) { switch (ra.LastException.SvnErrorCode) { case SvnErrorCode.SVN_ERR_WC_INVALID_OPERATION_DEPTH: toRevertWithInfinity.Add(item); break; } } } ra = new SvnRevertArgs(); ra.AddExpectedError(SvnErrorCode.SVN_ERR_WC_NOT_DIRECTORY); ra.Depth = SvnDepth.Infinity; foreach (SvnItem item in toRevertWithInfinity) { SvnStatusArgs sa = new SvnStatusArgs(); sa.RetrieveIgnoredEntries = false; sa.IgnoreExternals = true; sa.ThrowOnError = false; bool modifications = false; using (new SharpSvn.Implementation.SvnFsOperationRetryOverride(0)) { if (!a.Client.Status(item.FullPath, sa, delegate(object ss, SvnStatusEventArgs ee) { if (ee.FullPath == item.FullPath) { return; } if (ee.Conflicted || (ee.LocalPropertyStatus != SvnStatus.Normal && ee.LocalPropertyStatus != SvnStatus.None)) { ee.Cancel = modifications = true; } else { switch (ee.LocalNodeStatus) { case SvnStatus.None: case SvnStatus.Normal: case SvnStatus.Ignored: case SvnStatus.External: case SvnStatus.NotVersioned: break; default: ee.Cancel = modifications = true; break; } } })) { modifications = true; } } if (!modifications) { a.Client.Revert(item.FullPath, ra); } } }); } }
public override void OnExecute(CommandEventArgs e) { List <SvnItem> selectedFiles = new List <SvnItem>(); if (e.Command == AnkhCommand.DocumentShowChanges) { SvnItem item = e.Selection.ActiveDocumentSvnItem; if (item == null) { return; } selectedFiles.Add(item); } else { foreach (SvnItem item in e.Selection.GetSelectedSvnItems(false)) { if (!item.IsVersioned || (item.Status.LocalNodeStatus == SvnStatus.Added && !item.Status.IsCopied)) { continue; } if (e.Command == AnkhCommand.ItemCompareBase || e.Command == AnkhCommand.ItemShowChanges) { if (!(item.IsModified || item.IsDocumentDirty) || !item.IsLocalDiffAvailable // exclude if local diff is not available ) { continue; } } if (e.Command == AnkhCommand.DiffLocalItem && !NotDeletedFilter(item)) { continue; } selectedFiles.Add(item); } } SvnRevisionRange revRange = null; switch (e.Command) { case AnkhCommand.DiffLocalItem: break; // revRange null -> show selector case AnkhCommand.ItemCompareBase: case AnkhCommand.ItemShowChanges: case AnkhCommand.DocumentShowChanges: revRange = new SvnRevisionRange(SvnRevision.Base, SvnRevision.Working); break; case AnkhCommand.ItemCompareCommitted: revRange = new SvnRevisionRange(SvnRevision.Committed, SvnRevision.Working); break; case AnkhCommand.ItemCompareLatest: revRange = new SvnRevisionRange(SvnRevision.Head, SvnRevision.Working); break; case AnkhCommand.ItemComparePrevious: revRange = new SvnRevisionRange(SvnRevision.Previous, SvnRevision.Working); break; } if (e.PromptUser || selectedFiles.Count > 1 || revRange == null) { SvnRevision start = revRange == null ? SvnRevision.Base : revRange.StartRevision; SvnRevision end = revRange == null ? SvnRevision.Working : revRange.EndRevision; // should we show the path selector? if (e.PromptUser || !Shift) { using (CommonFileSelectorDialog dlg = new CommonFileSelectorDialog()) { dlg.Text = CommandStrings.CompareFilesTitle; dlg.Items = selectedFiles; dlg.RevisionStart = start; dlg.RevisionEnd = end; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return; } selectedFiles.Clear(); selectedFiles.AddRange(dlg.GetCheckedItems()); start = dlg.RevisionStart; end = dlg.RevisionEnd; } } revRange = new SvnRevisionRange(start, end); } if (revRange.EndRevision.RevisionType == SvnRevisionType.Working || revRange.StartRevision.RevisionType == SvnRevisionType.Working) { // Save only the files needed IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); if (tracker != null) { tracker.SaveDocuments(SvnItem.GetPaths(selectedFiles)); } } IAnkhDiffHandler diff = e.GetService <IAnkhDiffHandler>(); foreach (SvnItem item in selectedFiles) { AnkhDiffArgs da = new AnkhDiffArgs(); if ((item.Status.IsCopied || item.IsReplaced) && (!revRange.StartRevision.RequiresWorkingCopy || !revRange.EndRevision.RequiresWorkingCopy)) { // The file is copied, use its origins history instead of that of the new file SvnUriTarget copiedFrom = diff.GetCopyOrigin(item); // TODO: Maybe handle Previous/Committed as history if (copiedFrom != null && !revRange.StartRevision.RequiresWorkingCopy) { if (null == (da.BaseFile = diff.GetTempFile(copiedFrom, revRange.StartRevision, true))) { return; // Canceled } da.BaseTitle = diff.GetTitle(copiedFrom, revRange.StartRevision); } if (copiedFrom != null && !revRange.EndRevision.RequiresWorkingCopy) { if (null == (da.MineFile = diff.GetTempFile(copiedFrom, revRange.EndRevision, true))) { return; // Canceled } da.MineTitle = diff.GetTitle(copiedFrom, revRange.EndRevision); } } if (da.BaseFile == null) { if (null == (da.BaseFile = (revRange.StartRevision == SvnRevision.Working) ? item.FullPath : diff.GetTempFile(item, revRange.StartRevision, true))) { return; // Canceled } da.BaseTitle = diff.GetTitle(item, revRange.StartRevision); } if (da.MineFile == null) { if (null == (da.MineFile = (revRange.EndRevision == SvnRevision.Working) ? item.FullPath : diff.GetTempFile(item, revRange.EndRevision, true))) { return; // Canceled } da.MineTitle = diff.GetTitle(item, revRange.EndRevision); } if (!String.Equals(da.MineFile, item.FullPath, StringComparison.OrdinalIgnoreCase)) { da.ReadOnly = true; } diff.RunDiff(da); } }
/// <summary> /// Fixes up missing files by fixing their casing or deleting them /// </summary> /// <param name="state">The state.</param> /// <returns></returns> private bool PreCommit_HandleMissingFiles(PendingCommitState state) { foreach (string path in new List <string>(state.CommitPaths)) { SvnItem item = state.Cache[path]; if (item.Status.LocalNodeStatus != SvnStatus.Missing) { continue; } if (item.IsCasingConflicted) { string correctCasing = GetSvnCasing(item); string actualCasing = SvnTools.GetTruePath(item.FullPath); if (correctCasing == null || actualCasing == null || !string.Equals(correctCasing, actualCasing, StringComparison.OrdinalIgnoreCase)) { continue; // Nothing to fix here :( } string correctFile = Path.GetFileName(correctCasing); string actualFile = Path.GetFileName(actualCasing); if (correctFile == actualFile) { continue; // Casing issue is not in the file; can't fix :( } IAnkhOpenDocumentTracker odt = GetService <IAnkhOpenDocumentTracker>(); using (odt.LockDocument(correctCasing, DocumentLockType.NoReload)) using (odt.LockDocument(actualCasing, DocumentLockType.NoReload)) { try { File.Move(actualCasing, correctCasing); // Fix the name in the commit list state.CommitPaths[state.CommitPaths.IndexOf(path)] = actualCasing; } catch { } finally { item.MarkDirty(); GetService <IFileStatusMonitor>().ScheduleGlyphUpdate(item.FullPath); } } } else if (!item.Exists) { SvnDeleteArgs da = new SvnDeleteArgs(); da.KeepLocal = true; da.ThrowOnError = false; if (!state.Client.Delete(path, da)) { state.MessageBox.Show(da.LastException.Message, "", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return(false); } } } return(true); }
public override void OnExecute(CommandEventArgs e) { IAnkhServiceEvents ci = e.GetService <IAnkhServiceEvents>(); if (ci != null) { ci.OnLastChanged(new LastChangedEventArgs(null, null)); } SvnRevision rev; bool allowUnversionedObstructions = false; bool updateExternals = true; bool setDepthInfinity = true; IAnkhSolutionSettings settings = e.GetService <IAnkhSolutionSettings>(); ISvnStatusCache cache = e.GetService <ISvnStatusCache>(); IProjectFileMapper mapper = e.GetService <IProjectFileMapper>(); Uri reposRoot = null; if (IsHeadCommand(e.Command) || e.DontPrompt) { rev = SvnRevision.Head; } else if (IsSolutionCommand(e.Command)) { SvnItem projectItem = settings.ProjectRootSvnItem; Debug.Assert(projectItem != null, "Has item"); using (UpdateDialog ud = new UpdateDialog()) { ud.ItemToUpdate = projectItem; ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } else if (IsFolderCommand(e.Command)) { SvnItem dirItem = EnumTools.GetFirst(e.Selection.GetSelectedSvnItems(false)); Debug.Assert(dirItem != null && dirItem.IsDirectory && dirItem.IsVersioned); using (UpdateDialog ud = new UpdateDialog()) { ud.Text = CommandStrings.UpdateFolder; ud.FolderLabelText = CommandStrings.UpdateFolderLabel; ud.ItemToUpdate = dirItem; ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } else { // We checked there was only a single repository to select a revision // from in OnUpdate, so we can suffice with only calculate the path SvnItem si = null; SvnOrigin origin = null; foreach (SccProject p in GetSelectedProjects(e)) { ISccProjectInfo pi = mapper.GetProjectInfo(p); if (pi == null || pi.ProjectDirectory == null) { continue; } SvnItem item = cache[pi.ProjectDirectory]; if (!item.IsVersioned) { continue; } if (si == null && origin == null) { si = item; origin = new SvnOrigin(item); reposRoot = item.WorkingCopy.RepositoryRoot; } else { si = null; string urlPath1 = origin.Uri.AbsolutePath; string urlPath2 = item.Uri.AbsolutePath; int i = 0; while (i < urlPath1.Length && i < urlPath2.Length && urlPath1[i] == urlPath2[i]) { i++; } while (i > 0 && urlPath1[i - 1] != '/') { i--; } origin = new SvnOrigin(new Uri(origin.Uri, urlPath1.Substring(0, i)), origin.RepositoryRoot); } } Debug.Assert(origin != null); using (UpdateDialog ud = new UpdateDialog()) { ud.Text = CommandStrings.UpdateProject; if (si != null) { ud.ItemToUpdate = si; } else { ud.SvnOrigin = origin; ud.SetMultiple(true); } ud.Revision = SvnRevision.Head; if (ud.ShowDialog(e.Context) != DialogResult.OK) { return; } rev = ud.Revision; allowUnversionedObstructions = ud.AllowUnversionedObstructions; updateExternals = ud.UpdateExternals; setDepthInfinity = ud.SetDepthInfinty; } } Dictionary <string, SvnItem> itemsToUpdate = new Dictionary <string, SvnItem>(StringComparer.OrdinalIgnoreCase); SortedList <string, UpdateGroup> groups = new SortedList <string, UpdateGroup>(StringComparer.OrdinalIgnoreCase); // 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 (SvnItem item in GetAllUpdateRoots(e)) { // GetAllUpdateRoots can (and probably will) return duplicates! if (itemsToUpdate.ContainsKey(item.FullPath) || !item.IsVersioned) { continue; } SvnWorkingCopy wc = item.WorkingCopy; if (!IsHeadCommand(e.Command) && reposRoot != null) { // Specific revisions are only valid on a single repository! if (wc != null && wc.RepositoryRoot != reposRoot) { continue; } } UpdateGroup group; if (!groups.TryGetValue(wc.FullPath, out group)) { group = new UpdateGroup(wc.FullPath); groups.Add(wc.FullPath, group); } group.Nodes.Add(item.FullPath); itemsToUpdate.Add(item.FullPath, item); foreach (string file in documentTracker.GetDocumentsBelow(item.FullPath)) { if (!lockPaths.Contains(file)) { lockPaths.Add(file); } } } documentTracker.SaveDocuments(lockPaths); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(lockPaths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { SvnUpdateResult updateResult = null; ProgressRunnerArgs pa = new ProgressRunnerArgs(); pa.CreateLog = true; string title; if (IsSolutionCommand(e.Command)) { title = CommandStrings.UpdatingSolution; } else if (IsFolderCommand(e.Command)) { title = CommandStrings.UpdatingFolder; } else { title = CommandStrings.UpdatingProject; } e.GetService <IProgressRunner>().RunModal(title, pa, delegate(object sender, ProgressWorkerArgs a) { PerformUpdate(e, a, rev, allowUnversionedObstructions, updateExternals, setDepthInfinity, groups.Values, out updateResult); }); if (ci != null && updateResult != null && IsSolutionCommand(e.Command)) { ci.OnLastChanged(new LastChangedEventArgs(CommandStrings.UpdatedToTitle, updateResult.Revision.ToString())); } } }
public override void OnExecute(CommandEventArgs e) { List <SvnOrigin> targets = new List <SvnOrigin>(); SvnRevision startRev = SvnRevision.Zero; SvnRevision endRev = null; switch (e.Command) { case AnkhCommand.ItemAnnotate: endRev = SvnRevision.Working; foreach (SvnItem i in e.Selection.GetSelectedSvnItems(false)) { if (i.IsFile && i.IsVersioned && i.HasCopyableHistory) { targets.Add(new SvnOrigin(i)); } } break; case AnkhCommand.LogAnnotateRevision: foreach (ISvnLogChangedPathItem logItem in e.Selection.GetSelection <ISvnLogChangedPathItem>()) { targets.Add(logItem.Origin); endRev = logItem.Revision; } break; case AnkhCommand.SvnNodeAnnotate: foreach (ISvnRepositoryItem item in e.Selection.GetSelection <ISvnRepositoryItem>()) { targets.Add(item.Origin); endRev = item.Revision; } break; case AnkhCommand.DocumentAnnotate: //TryObtainBlock(e); targets.Add(new SvnOrigin(e.GetService <ISvnStatusCache>()[e.Selection.ActiveDocumentFilename])); endRev = SvnRevision.Working; break; } if (targets.Count == 0) { return; } bool ignoreEols = true; SvnIgnoreSpacing ignoreSpacing = SvnIgnoreSpacing.IgnoreSpace; bool retrieveMergeInfo = false; SvnOrigin target; if ((!e.DontPrompt && !Shift) || e.PromptUser) { using (AnnotateDialog dlg = new AnnotateDialog()) { dlg.SetTargets(targets); dlg.StartRevision = startRev; dlg.EndRevision = endRev; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return; } target = dlg.SelectedTarget; startRev = dlg.StartRevision; endRev = dlg.EndRevision; ignoreEols = dlg.IgnoreEols; ignoreSpacing = dlg.IgnoreSpacing; retrieveMergeInfo = dlg.RetrieveMergeInfo; } } else { SvnItem one = EnumTools.GetFirst(e.Selection.GetSelectedSvnItems(false)); if (one == null) { return; } target = new SvnOrigin(one); } if (startRev == SvnRevision.Working || endRev == SvnRevision.Working && target.Target is SvnPathTarget) { IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); if (tracker != null) { tracker.SaveDocument(((SvnPathTarget)target.Target).FullPath); } } DoBlame(e, target, startRev, endRev, ignoreEols, ignoreSpacing, retrieveMergeInfo); }
public override void OnExecute(CommandEventArgs e) { SvnRevision updateTo; List <string> files = new List <string>(); if (e.Command == AnkhCommand.UpdateItemSpecific || e.Command == AnkhCommand.UpdateProjectFileSpecific) { updateTo = SvnRevision.Head; List <SvnItem> items = new List <SvnItem>(); foreach (SvnItem item in e.Selection.GetSelectedSvnItems(true)) { if (item.IsFile && item.IsVersioned) { items.Add(item); } } using (CommonFileSelectorDialog dlg = new CommonFileSelectorDialog()) { dlg.Text = CommandStrings.UpdateFilesTitle; dlg.Items = items; dlg.RevisionStart = updateTo; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return; } files.AddRange(SvnItem.GetPaths(dlg.GetCheckedItems())); updateTo = dlg.RevisionStart; } } else { updateTo = SvnRevision.Head; List <SvnItem> dirs = new List <SvnItem>(); foreach (SvnItem item in e.Selection.GetSelectedSvnItems(true)) { if (!item.IsVersioned) { continue; } bool found = false; foreach (SvnItem p in dirs) { if (item.IsBelowPath(p) && p.WorkingCopy == item.WorkingCopy) { found = true; break; } } if (found) { continue; } files.Add(item.FullPath); if (item.IsDirectory) { dirs.Add(item); } } } IAnkhOpenDocumentTracker tracker = e.GetService <IAnkhOpenDocumentTracker>(); tracker.SaveDocuments(e.Selection.GetSelectedFiles(true)); using (DocumentLock lck = tracker.LockDocuments(files, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { SvnUpdateResult ur; ProgressRunnerArgs pa = new ProgressRunnerArgs(); pa.CreateLog = true; e.GetService <IProgressRunner>().RunModal(CommandStrings.UpdatingTitle, pa, delegate(object sender, ProgressWorkerArgs ee) { SvnUpdateArgs ua = new SvnUpdateArgs(); ua.Depth = SvnDepth.Infinity; ua.Revision = updateTo; e.GetService <IConflictHandler>(). RegisterConflictHandler(ua, ee.Synchronizer); ee.Client.Update(files, ua, out ur); }); } }
/// <summary> /// Returns false if the AddToSubversionDialog has been cancelled, true otherwise /// </summary> /// <param name="e"></param> /// <param name="projectInfo"></param> /// <param name="solutionReposRoot"></param> /// <param name="shouldMarkAsManaged"></param> /// <param name="storeReference"></param> /// <returns></returns> static bool CheckoutWorkingCopyForProject(CommandEventArgs e, SccProject project, ISccProjectInfo projectInfo, Uri solutionReposRoot, out bool shouldMarkAsManaged, out bool storeReference) { shouldMarkAsManaged = false; storeReference = false; using (SvnClient cl = e.GetService <ISvnClientPool>().GetClient()) using (AddProjectToSubversion dialog = new AddProjectToSubversion()) { dialog.Context = e.Context; dialog.PathToAdd = projectInfo.ProjectDirectory; dialog.RepositoryAddUrl = solutionReposRoot; if (e.Argument is IAnkhSccService) { dialog.CommitAllVisible = false; dialog.CommitAllFiles = false; } else { dialog.CommitAllFiles = true; } if (dialog.ShowDialog(e.Context) != DialogResult.OK) { return(false); // User cancelled the "Add to subversion" dialog, don't set as managed by Ankh } if (!dialog.CommitAllFiles) { Collection <SvnInfoEventArgs> info; SvnInfoArgs ia = new SvnInfoArgs(); ia.ThrowOnError = false; if (!cl.GetInfo(dialog.RepositoryAddUrl, ia, out info)) { // Target uri doesn't exist in the repository, let's create if (!RemoteCreateDirectory(e, dialog.Text, dialog.RepositoryAddUrl, cl)) { return(false); // Create failed; bail out } } // Create working copy SvnCheckOutArgs coArg = new SvnCheckOutArgs(); coArg.AllowObstructions = true; cl.CheckOut(dialog.RepositoryAddUrl, dialog.WorkingCopyDir, coArg); } else { // Cache some values before thread marshalling HybridCollection <string> projectFiles = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); string wcDir = dialog.WorkingCopyDir; Uri reposUrl = dialog.RepositoryAddUrl; string logMessage; projectFiles.UniqueAddRange(e.GetService <IProjectFileMapper>().GetAllFilesOf(project)); using (CreateDirectoryDialog dlg = new CreateDirectoryDialog()) { dlg.Text = CommandStrings.ImportingTitle; dlg.NewDirectoryName = reposUrl.ToString(); dlg.NewDirectoryReadonly = true; if (dlg.ShowDialog(e.Context) != DialogResult.OK) { return(false); } logMessage = dlg.LogMessage; } IAnkhOpenDocumentTracker documentTracker = e.GetService <IAnkhOpenDocumentTracker>(); documentTracker.SaveDocuments(projectFiles); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(projectFiles, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) { e.GetService <IProgressRunner>().RunModal(CommandStrings.ImportingTitle, delegate(object sender, ProgressWorkerArgs a) { SvnImportArgs importArgs = new SvnImportArgs(); importArgs.LogMessage = logMessage; importArgs.Filter += delegate(object ieSender, SvnImportFilterEventArgs ie) { if (ie.NodeKind != SvnNodeKind.Directory) { ie.Filter = !projectFiles.Contains(ie.FullPath); } else { bool filter = true; foreach (string p in projectFiles) { if (SvnItem.IsBelowRoot(p, ie.FullPath)) { filter = false; break; } } if (filter) { ie.Filter = true; } } }; a.Client.Import(wcDir, reposUrl, importArgs); }); } } shouldMarkAsManaged = dialog.MarkAsManaged; storeReference = dialog.WriteCheckOutInformation; } return(true); }