public override void OnExecute(CommandEventArgs e) { List<SvnItem> items = new List<SvnItem>(e.Selection.GetSelectedSvnItems(true)); e.GetService<IProgressRunner>().RunModal("Running Cleanup", delegate(object sender, ProgressWorkerArgs a) { HybridCollection<string> wcs = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); foreach (SvnItem item in items) { if (!item.IsVersioned) continue; SvnWorkingCopy wc = item.WorkingCopy; if (wc != null && !wcs.Contains(wc.FullPath)) wcs.Add(wc.FullPath); } SvnCleanUpArgs args = new SvnCleanUpArgs(); args.ThrowOnError = false; foreach (string path in wcs) a.Client.CleanUp(path, args); }); }
public override void Reload(IEnumerable <string> paths) { if (paths == null) { throw new ArgumentNullException("paths"); } StopMonitor(); // Make sure we have no further locks while reloading! HybridCollection <string> changed = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); changed.AddRange(paths); IProjectFileMapper mapper = _tracker.GetService <IProjectFileMapper>(); if (!string.IsNullOrEmpty(mapper.SolutionFilename) && changed.Contains(mapper.SolutionFilename)) { // Ok; we are going to reload the solution itself _tracker.SaveAllDocumentsExcept(changed); // Make sure everything that is dirty is saved // let's remove all documents that are in the solution from the changed list foreach (string file in mapper.GetAllFilesOfAllProjects()) { changed.Remove(file); } // The solution was just removed; add it back changed.Add(mapper.SolutionFilename); } for (int i = 0; i < changed.Count; i++) { string ch = changed[i]; SccDocumentData dd; if (_tracker._docMap.TryGetValue(ch, out dd)) { if (!dd.Reload(true)) { string parentDocument = _tracker.GetParentDocument(dd); if (string.IsNullOrEmpty(parentDocument)) { parentDocument = mapper.SolutionFilename; } if (!string.IsNullOrEmpty(parentDocument) && !changed.Contains(parentDocument)) { if (!_locked.Contains(parentDocument)) { // The parent is not on our changed or locked list.. so make sure it is saved _tracker.SaveDocument(parentDocument); } changed.Add(parentDocument); } } } } }
private static void PerformUpdate(CommandEventArgs e, ProgressWorkerArgs wa, SvnRevision rev, bool allowUnversionedObstructions, bool updateExternals, bool setDepthInfinity, IEnumerable <UpdateGroup> groups, out SvnUpdateResult updateResult) { SvnUpdateArgs ua = new SvnUpdateArgs(); ua.Revision = rev; ua.AllowObstructions = allowUnversionedObstructions; ua.IgnoreExternals = !updateExternals; ua.KeepDepth = setDepthInfinity; updateResult = null; HybridCollection <string> handledExternals = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); ua.Notify += delegate(object ss, SvnNotifyEventArgs ee) { if (ee.Action == SvnNotifyAction.UpdateExternal) { if (!handledExternals.Contains(ee.FullPath)) { handledExternals.Add(ee.FullPath); } } }; e.Context.GetService <IConflictHandler>().RegisterConflictHandler(ua, wa.Synchronizer); foreach (UpdateGroup group in groups) { if (handledExternals.Contains(group.WorkingCopyRoot)) { continue; } group.Nodes.Sort(StringComparer.OrdinalIgnoreCase); // Currently Subversion runs update per item passed and in // Subversion 1.6 passing each item separately is actually // a tiny bit faster than passing them all at once. // (sleep_for_timestamp fails its fast route) foreach (string path in group.Nodes) { if (handledExternals.Contains(path)) { continue; } SvnUpdateResult result; wa.Client.Update(path, ua, out result); if (updateResult == null) { updateResult = result; // Return the primary update as version for output } } } }
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); } } }
/// <summary> /// Schedules a dirty check for the specified document /// </summary> /// <param name="item">The item.</param> public void ScheduleDirtyCheck(SvnItem item) { if (item == null) { throw new ArgumentNullException("path"); } if (!item.IsVersioned || item.IsModified || DocumentTracker.NoDirtyCheck(item)) { return; // Not needed } lock (_lock) { if (_dirtyCheck == null) { _dirtyCheck = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); } if (!_dirtyCheck.Contains(item.FullPath)) { _dirtyCheck.Add(item.FullPath); } PostIdle(); } }
public override void OnExecute(CommandEventArgs e) { List <SvnItem> items = new List <SvnItem>(e.Selection.GetSelectedSvnItems(true)); e.GetService <IProgressRunner>().RunModal(CommandStrings.CleaningWorkingCopy, delegate(object sender, ProgressWorkerArgs a) { HybridCollection <string> wcs = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); foreach (SvnItem item in items) { if (!item.IsVersioned) { continue; } SvnWorkingCopy wc = item.WorkingCopy; if (wc != null && !wcs.Contains(wc.FullPath)) { wcs.Add(wc.FullPath); } } SvnCleanUpArgs args = new SvnCleanUpArgs(); args.ThrowOnError = false; foreach (string path in wcs) { a.Client.CleanUp(path, args); } }); }
public ProjectListFilter(IAnkhServiceProvider context, IEnumerable <SccProject> projects) { if (context == null) { throw new ArgumentNullException("context"); } if (projects == null) { throw new ArgumentNullException("projects"); } _mapper = context.GetService <IProjectFileMapper>(); List <SccProject> projectList = new List <SccProject>(projects); files.AddRange(_mapper.GetAllFilesOf(projectList)); foreach (SccProject p in projectList) { ISccProjectInfo pi = _mapper.GetProjectInfo(p); if (pi == null) { continue; // Ignore solution and non scc projects } string dir = pi.ProjectDirectory; if (!string.IsNullOrEmpty(dir) && !folders.Contains(dir)) { folders.Add(dir); } } }
/// <summary> /// Returns a reference to a DynamicAccessor for the requested type represented by <seealso cref="IDynamicAccessor"/>. /// </summary> /// <param name="type">The for to get the DynamicAccessor</param> /// <returns><see cref="DynamicAccessor"/></returns> public static IDynamicAccessor GetDynamicAccessor(Type type) { if (!_DynamicAccessors.Contains(type)) { _DynamicAccessors.Add(type, new DynamicAccessor(type)); } return(_DynamicAccessors[type]); }
/// <summary> /// Returns a reference to a Latebinder for the requested type represented by <seealso cref="ILateBinder"/>. /// </summary> /// <param name="type">The for to get the Latebinder</param> /// <returns><see cref="LateBinder"/></returns> public static ILateBinder GetLateBinder(Type type) { if (!_latebinders.Contains(type)) { _latebinders.Add(type, new LateBinder(type)); } return(_latebinders[type]); }
public SccDocumentLock(OpenDocumentTracker tracker, HybridCollection <string> locked, HybridCollection <string> ignoring, HybridCollection <string> readOnly) { ThreadHelper.ThrowIfNotOnUIThread(); if (tracker == null) { throw new ArgumentNullException("tracker"); } else if (locked == null) { throw new ArgumentNullException("locked"); } else if (ignoring == null) { throw new ArgumentNullException("ignoring"); } else if (readOnly == null) { throw new ArgumentNullException("readOnly"); } _tracker = tracker; _locked = locked; _ignoring = ignoring; _readonly = readOnly; _fsIgnored = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); _changedPaths = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); _monitor = new Dictionary <uint, string>(); _altMonitor = new Dictionary <string, FileInfo>(); _change = tracker.GetService <IVsFileChangeEx>(typeof(SVsFileChangeEx)); foreach (string file in locked) { // This files auto reload could not be suspended by calling Ignore on the document // We must therefore stop posting messages to it by stopping it in the change monitor // But to be able to tell if there are changes.. We keep some stats ourselves if (!ignoring.Contains(file) && VSErr.Succeeded(_change.IgnoreFile(0, file, 1))) { _fsIgnored.Add(file); FileInfo info = new FileInfo(file); info.Refresh(); if (info.Exists) { GC.KeepAlive(info.LastWriteTime); GC.KeepAlive(info.CreationTime); GC.KeepAlive(info.Length); } _altMonitor.Add(file, info); } } }
public bool IsPropertyValid(string propertyName) { //Remove the validation errors before validation _validationErrors.Remove(propertyName); PropertyValidators validators = GetValidators(_target.GetType()); RunValidators(validators[propertyName]); return(!_validationErrors.Contains(propertyName)); }
void OnSvnItemsChanged(object sender, SvnItemsEventArgs e) { lock (_toRefresh) { if (_fullRefresh || !_solutionOpen) { return; } foreach (SvnItem item in e.ChangedItems) { if (!_toRefresh.Contains(item.FullPath)) { _toRefresh.Add(item.FullPath); } } ScheduleRefresh(); } }
internal void ReloadModified() { ThreadHelper.ThrowIfNotOnUIThread(); if (_monitor == null || _change == null) { return; } foreach (string file in _monitor.Values) { _change.SyncFile(file); } foreach (KeyValuePair <string, FileInfo> item in new List <KeyValuePair <string, FileInfo> >(_altMonitor)) { string file = item.Key; FileInfo from = item.Value; FileInfo to = new FileInfo(file); if (from.Exists && to.Exists && ((from.LastWriteTime != to.LastWriteTime) || (from.Length != to.Length) || (from.CreationTime != to.CreationTime))) { if (!_changedPaths.Contains(file)) { _changedPaths.Add(file); _altMonitor[file] = to; } } } List <string> changed = new List <string>(_changedPaths); _changedPaths.Clear(); Reload(changed); }
private static PropertyValidators GetValidators(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!_typeValidators.Contains(type)) { //Create a new collection to hold the validators for this type PropertyValidators validators = new PropertyValidators(); //Get a list of properties on this type PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic); foreach (PropertyInfo property in properties) { //Get a list of attributes deriving from ValidatorAttributeBase ValidatorAttributeBase[] validatorAttributes = (ValidatorAttributeBase[])property.GetCustomAttributes(typeof(ValidatorAttributeBase), true); //Create a new list to hold the attributes for this property List <ValidatorAttributeBase> attributeList = new List <ValidatorAttributeBase>(validatorAttributes); //Sort the attributes according to the sequence property attributeList.Sort( delegate(ValidatorAttributeBase attribute1, ValidatorAttributeBase attribute2) { return(attribute1.Sequence.CompareTo(attribute2.Sequence)); }); //Create the validators for this property List <ValidatorBase> list = attributeList.ConvertAll <ValidatorBase>( delegate(ValidatorAttributeBase attribute) { return(attribute.CreateValidator(property.GetType(), property.Name)); }); if (list.Count > 0) { //Add the validators to this property validators.Add(property.Name, list); } } //Store the validators for this type _typeValidators.Add(type, validators); } //Return the list of validators for the requested type return(_typeValidators[type]); }
IEnumerator <KeyValuePair <string, string> > IEnumerable <KeyValuePair <string, string> > .GetEnumerator() { using (RegistryKey key = OpenFifoKey(true)) { int nSize; int nPos; if (!RegistryUtils.TryGetIntValue(key, "_size", out nSize) || nSize < 1) { nSize = _defaultSize; } // This gives a very tiny race condition if used at the same time in // two VS instances. // We ignore this as it is just UI helper code and a user can't edit // two windows at the same time if (!RegistryUtils.TryGetIntValue(key, "_pos", out nPos) || (nPos < 0) || (nPos >= nSize)) { nPos = 0; } HybridCollection <string> hs = new HybridCollection <string>(); hs.AddRange(key.GetValueNames()); for (int i = 0; i < nSize; i++) { int n = nPos - i; while (n < 0) { n += nSize; } string s = "#" + n.ToString(CultureInfo.InvariantCulture); if (hs.Contains(s)) { string v = key.GetValue(s) as string; if (v != null && (_allowWhiteSpace || !string.IsNullOrEmpty(v))) { yield return(new KeyValuePair <string, string>(s, v)); } } } } }
private void ItemRefresh(string file) { SvnItem item = Cache[file]; file = item.FullPath; // Use existing normalization bool inProject = item.InSolution; bool inExtra = _extraFiles.Contains(file); PendingChange pc; if (!inProject && !inExtra) { _pendingChanges.Remove(file); return; } else if (inProject && inExtra) { _extraFiles.Remove(file); } if (item == null) { return; } if (_pendingChanges.TryGetValue(file, out pc)) { if (pc.Refresh(RefreshContext, item)) { if (pc.IsClean) { _pendingChanges.Remove(file); _extraFiles.Remove(file); } else { RaiseChanged(pc); } } } else if (PendingChange.CreateIfPending(RefreshContext, item, out pc)) { _pendingChanges.Add(pc); } }
public PendingCommitState(IAnkhServiceProvider context, IEnumerable <PendingChange> changes) : base(context) { if (changes == null) { throw new ArgumentNullException("changes"); } _changes.UniqueAddRange(changes); foreach (PendingChange pc in _changes) { if (!_commitPaths.Contains(pc.FullPath)) { _commitPaths.Add(pc.FullPath); } } }
/// <summary> /// The node may be just removed from the project. Check later. /// Some projects delete the file before (C#) and some after (C++) calling OnProjectFileRemoved /// /// And when renaming a C# project (VS11 Beta) we sometimes even get a delete before a rename. /// </summary> /// <param name="path"></param> protected override void AddDelayedDelete(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } if (_delayedDelete == null) { _delayedDelete = new HybridCollection <string>(); } if (!_delayedDelete.Contains(path)) { _delayedDelete.Add(path); } RegisterForSccCleanup(); }
public bool ShowChange(PendingChange pc) { if (files.Contains(pc.FullPath)) { return(true); } if (!_mapper.ContainsPath(pc.FullPath)) { foreach (string f in folders) { if (pc.IsBelowPath(f)) { // Path is not contained in any other project but below one of the project roots return(true); } } } return(false); }
static void LoadUris(HybridCollection <Uri> uris, RegistryKey rk) { foreach (string name in rk.GetValueNames()) { string value = rk.GetValue(name) as string; if (value != null && !value.EndsWith("/")) { value += "/"; } Uri uri; if (value != null && Uri.TryCreate(value, UriKind.Absolute, out uri)) { if (!uris.Contains(uri)) { uris.Add(uri); } } } }
/// <summary> /// Accesses a specified set of files and asks all implementers of this method to release any locks that may exist on those files. /// </summary> /// <param name="grfRequiredAccess">[in] A value from the <see cref="T:Microsoft.VisualStudio.Shell.Interop.__HANDSOFFMODE"></see> enumeration, indicating the type of access requested. This can be used to optimize the locks that actually need to be released.</param> /// <param name="cFiles">[in] The number of files in the rgpszMkDocuments array.</param> /// <param name="rgpszMkDocuments">[in] If there are any locks on this array of file names, the caller wants them to be released.</param> /// <returns> /// If the method succeeds, it returns <see cref="F:Microsoft.VisualStudio.VSErr.S_OK"></see>. If it fails, it returns an error code. /// </returns> public int HandsOffFiles(uint grfRequiredAccess, int cFiles, string[] rgpszMkDocuments) { if (_collectHints && rgpszMkDocuments != null) { // Some projects call HandsOffFiles of files they want to add. Use that to collect extra origin information foreach (string file in rgpszMkDocuments) { if (!SccProvider.IsSafeSccPath(file)) { continue; } string fullFile = SvnTools.GetNormalizedFullPath(file); if (!_fileHints.Contains(fullFile)) { _fileHints.Add(fullFile); } } } return(VSErr.S_OK); }
public void ScheduleAddFile(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } lock (_lock) { if (_maybeAdd == null) { _maybeAdd = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); } if (!_maybeAdd.Contains(path)) { _maybeAdd.Add(path); } PostDirty(true); } }
/// <summary> /// Gets the selected files; yielding for each result to allow delay loading /// </summary> /// <param name="recursive"></param> /// <returns></returns> IEnumerable <string> InternalGetSelectedFiles(bool recursive) { HybridCollection <string> foundFiles = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); foreach (SelectionItem i in GetSelectedItems(recursive)) { string[] files; if (SelectionUtils.GetSccFiles(i, out files, true, true, null)) { foreach (string file in files) { if (!foundFiles.Contains(file)) { foundFiles.Add(file); yield return(file); } } } } }
public DocumentLock LockDocuments(IEnumerable <string> paths, DocumentLockType lockType) { if (paths == null) { throw new ArgumentNullException("paths"); } HybridCollection <string> locked = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); HybridCollection <string> ignoring = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); HybridCollection <string> readOnly = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); foreach (string path in paths) { SccDocumentData dd; if (_docMap.TryGetValue(path, out dd)) { if (!locked.Contains(path)) { locked.Add(path); } if (!ignoring.Contains(path) && dd.IgnoreFileChanges(true)) { ignoring.Add(path); } if (lockType >= DocumentLockType.ReadOnly && !readOnly.Contains(path) && !dd.IsReadOnly()) { // Don't set read-only twice!!! if (dd.SetReadOnly(true)) { readOnly.Add(path); } } } } return(new SccDocumentLock(this, locked, ignoring, readOnly)); }
public bool SaveAllDocumentsExcept(IEnumerable <string> paths) { if (paths == null) { throw new ArgumentNullException("paths"); } HybridCollection <string> openDocs = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); HybridCollection <string> dontSave = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); openDocs.UniqueAddRange(_docMap.Keys); dontSave.UniqueAddRange(paths); bool ok = true; foreach (string name in openDocs) { SccDocumentData data; if (dontSave.Contains(name)) { continue; } if (!_docMap.TryGetValue(name, out data)) { continue; // File closed through saving another one } if (!data.SaveDocument(RunningDocumentTable)) { ok = false; } } return(ok); }
static void LoadUris(HybridCollection<Uri> uris, RegistryKey rk) { foreach (string name in rk.GetValueNames()) { string value = rk.GetValue(name) as string; if (value != null && !value.EndsWith("/")) value += "/"; Uri uri; if (value != null && Uri.TryCreate(value, UriKind.Absolute, out uri)) { if (!uris.Contains(uri)) uris.Add(uri); } } }
public IEnumerable <Uri> GetRepositoryUris(bool forBrowse) { HybridCollection <Uri> uris = new HybridCollection <Uri>(); if (ProjectRootUri != null) { uris.Add(ProjectRootUri); } // Global keys (over all versions) using (RegistryKey rk = Config.OpenGlobalKey("Repositories")) { if (rk != null) { LoadUris(uris, rk); } } // Per hive using (RegistryKey rk = Config.OpenInstanceKey("Repositories")) { if (rk != null) { LoadUris(uris, rk); } } // Per user + Per hive using (RegistryKey rk = Config.OpenUserInstanceKey("Repositories")) { if (rk != null) { LoadUris(uris, rk); } } // Finally add the last used list from TortoiseSVN try { using (RegistryKey rk = Registry.CurrentUser.OpenSubKey( "SOFTWARE\\TortoiseSVN\\History\\repoURLS", RegistryKeyPermissionCheck.ReadSubTree)) { if (rk != null) { LoadUris(uris, rk); } } } catch (SecurityException) { /* Ignore no read only access; stupid sysadmins */ } IAnkhConfigurationService configSvc = GetService <IAnkhConfigurationService>(); if (configSvc != null) { foreach (string u in configSvc.GetRecentReposUrls()) { Uri uri; if (u != null && Uri.TryCreate(u, UriKind.Absolute, out uri)) { if (!uris.Contains(uri)) { uris.Add(uri); } } } } return(uris); }
void OnPendingChangesListFlushed(object sender, PendingChangeEventArgs e) { if (_listItems.Count > 0) { _checkedItems = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); foreach (PendingCommitItem pci in _listItems.Values) { if (pci.Checked && !_checkedItems.Contains(pci.FullPath)) _checkedItems.Add(pci.FullPath); } _listItems.Clear(); pendingCommits.ClearItems(); } }
/// <summary> /// Provides ToolTip text based on the source control data for a specific node in the project's hierarchy Solution Explorer. /// </summary> /// <param name="hierarchy">[in] Owner hierarchy of node (null if it is a solution).</param> /// <param name="itemidNode">[in] The ID of the node for which the ToolTip is requested.</param> /// <param name="pbstrTooltipText">[out] ToolTip text.</param> /// <returns> /// If the method succeeds, it returns <see cref="F:Microsoft.VisualStudio.VSErr.S_OK"></see>. If it fails, it returns an error code. /// </returns> protected override string GetGlyphTipText(SccHierarchy hierarchy, uint itemidNode) { if (Walker == null || StatusCache == null) { return(null); } HybridCollection <string> files = new HybridCollection <string>(StringComparer.OrdinalIgnoreCase); int n = 0; foreach (string file in Walker.GetSccFiles(hierarchy.Hierarchy, itemidNode, ProjectWalkDepth.Empty, null)) { if (files.Contains(file) || !SvnItem.IsValidPath(file)) { continue; } files.Add(file); SccProjectFile spf; if (ProjectMap.TryGetFile(file, out spf)) { foreach (string subfile in spf.FirstReference.GetSubFiles()) { if (!files.Contains(subfile)) { files.Add(subfile); } } } } StringBuilder sb = new StringBuilder(); string format = (files.Count > 0) ? "{0}: {1}" : "{1}"; int i = 0; foreach (string file in files) { SvnItem item = StatusCache[file]; if (i >= n) // This is a subitem! { if (item.IsModified) { sb.AppendFormat(format, item.Name, Resources.ToolTipModified).AppendLine(); } } if (item.IsConflicted) { sb.AppendFormat(format, item.Name, Resources.ToolTipConflict).AppendLine(); } if (item.IsObstructed) { sb.AppendFormat(format, item.Name, item.IsFile ? Resources.ToolTipFileObstructed : Resources.ToolTipDirObstructed).AppendLine(); } if (!item.Exists && item.IsVersioned && !item.IsDeleteScheduled) { sb.AppendFormat(format, item.Name, Resources.ToolTipDoesNotExist).AppendLine(); } if (item.IsLocked) { sb.AppendFormat(format, item.Name, Resources.ToolTipLocked).AppendLine(); } i++; if (sb.Length > 2048) { break; } } if (sb.Length > 0) { return(sb.ToString().Trim()); // We added newlines } return(null); }
public override void Reload(IEnumerable<string> paths) { if (paths == null) throw new ArgumentNullException("paths"); StopMonitor(); // Make sure we have no further locks while reloading! HybridCollection<string> changed = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); changed.AddRange(paths); IProjectFileMapper mapper = _tracker.GetService<IProjectFileMapper>(); if (!string.IsNullOrEmpty(mapper.SolutionFilename) && changed.Contains(mapper.SolutionFilename)) { // Ok; we are going to reload the solution itself _tracker.SaveAllDocumentsExcept(changed); // Make sure everything that is dirty is saved // let's remove all documents that are in the solution from the changed list foreach (string file in mapper.GetAllFilesOfAllProjects()) { changed.Remove(file); } // The solution was just removed; add it back changed.Add(mapper.SolutionFilename); } for (int i = 0; i < changed.Count; i++) { string ch = changed[i]; SccDocumentData dd; if (_tracker._docMap.TryGetValue(ch, out dd)) { if (!dd.Reload(true, false)) { string parentDocument = _tracker.GetParentDocument(dd); if (string.IsNullOrEmpty(parentDocument)) parentDocument = mapper.SolutionFilename; if (!string.IsNullOrEmpty(parentDocument) && !changed.Contains(parentDocument)) { if (!_locked.Contains(parentDocument)) { // The parent is not on our changed or locked list.. so make sure it is saved _tracker.SaveDocument(parentDocument); } changed.Add(parentDocument); } } } } }
public override void OnExecute(CommandEventArgs e) { if (e.Argument != null) { ShowUpdate(e); return; } int interval = 24 * 6; // 6 days IAnkhConfigurationService config = e.GetService<IAnkhConfigurationService>(); if (config.Instance.DisableUpdateCheck) return; using (RegistryKey rk = config.OpenUserInstanceKey("UpdateCheck")) { object value = rk.GetValue("Interval"); if (value is int) { interval = (int)value; if (interval <= 0) return; } } Version version = GetCurrentVersion(e.Context); Version vsVersion = e.GetService<IAnkhSolutionSettings>().VisualStudioVersion; Version osVersion = Environment.OSVersion.Version; StringBuilder sb = new StringBuilder(); sb.Append("http://svc.ankhsvn.net/svc/"); if (IsDevVersion()) sb.Append("dev/"); sb.Append("update-info/"); sb.Append(version.ToString(2)); sb.Append(".xml"); sb.Append("?av="); sb.Append(version); sb.Append("&vs="); sb.Append(vsVersion); sb.Append("&os="); sb.Append(osVersion); if (IsDevVersion()) sb.Append("&dev=1"); sb.AppendFormat(CultureInfo.InvariantCulture, "&iv={0}", interval); int x = 0; // Create some hashcode that is probably constant and unique for all users // using the same IP address, but not translatable to a single user try { foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) { string type = ni.NetworkInterfaceType.ToString(); if (type.Contains("Ethernet") || type.Contains("Wireless")) x ^= ni.GetPhysicalAddress().GetHashCode(); } } catch { } sb.AppendFormat(CultureInfo.InvariantCulture, "&xx={0}&pc={1}", x, Environment.ProcessorCount); try { using (RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP")) { if (rk != null) { sb.Append("&dn="); Regex re = new Regex("^[vV]([0-9]+\\.[0-9]+)(\\.[0-9]+)*", RegexOptions.Singleline); bool first = true; HybridCollection<string> vers = new HybridCollection<string>(); foreach (string s in rk.GetSubKeyNames()) { Match m = re.Match(s); if (m.Success) { string v = m.Groups[1].Value; if (vers.Contains(v)) continue; vers.Add(v); if (first) first = false; else sb.Append(','); sb.Append(v); } } } } } catch { } Uri updateUri = new Uri(sb.ToString()); WebRequest wr = WebRequest.Create(updateUri); HttpWebRequest hwr = wr as HttpWebRequest; if (hwr != null) { hwr.AllowAutoRedirect = true; hwr.AllowWriteStreamBuffering = true; hwr.UserAgent = string.Format("AnkhSVN/{0} VisualStudio/{1} Windows/{2}", version, vsVersion, osVersion); } wr.BeginGetResponse(OnResponse, wr); }
public override void OnExecute(CommandEventArgs e) { GitItem theItem = null; string path; GitRef currentBranch = null; string projectRoot = e.GetService<IVisualGitSolutionSettings>().ProjectRoot; if (e.Command == VisualGitCommand.SolutionSwitchDialog) path = projectRoot; else if (e.Command == VisualGitCommand.SwitchProject) { IProjectFileMapper mapper = e.GetService<IProjectFileMapper>(); path = null; foreach (GitProject item in e.Selection.GetSelectedProjects(true)) { IGitProjectInfo pi = mapper.GetProjectInfo(item); if (pi == null) continue; path = pi.ProjectDirectory; break; } if (string.IsNullOrEmpty(path)) return; } else if (e.Command == VisualGitCommand.LogSwitchToRevision) { IGitLogItem item = EnumTools.GetSingle(e.Selection.GetSelection<IGitLogItem>()); if (item == null) return; path = item.RepositoryRoot; currentBranch = new GitRef(item.Revision); } else { foreach (GitItem item in e.Selection.GetSelectedGitItems(false)) { if (item.IsVersioned) { theItem = item; break; } return; } path = theItem.FullPath; } IFileStatusCache statusCache = e.GetService<IFileStatusCache>(); GitItem pathItem = statusCache[path]; if (currentBranch == null) { using (var client = e.GetService<IGitClientPool>().GetNoUIClient()) { currentBranch = client.GetCurrentBranch(pathItem.FullPath); } if (currentBranch == null) return; // Should never happen on a real workingcopy } GitRef target; bool force = false; if (e.Argument is string) { target = new GitRef((string)e.Argument); } else using (SwitchDialog dlg = new SwitchDialog()) { dlg.GitOrigin = new GitOrigin(pathItem); dlg.Context = e.Context; dlg.LocalPath = GitTools.GetRepositoryRoot(path); dlg.SwitchToBranch = currentBranch; if (dlg.ShowDialog(e.Context) != DialogResult.OK) return; target = dlg.SwitchToBranch; force = dlg.Force; } // 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); IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>(); 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()) { GitSwitchArgs args = new GitSwitchArgs(); GitException exception = null; e.GetService<IProgressRunner>().RunModal( "Changing Current Branch", delegate(object sender, ProgressWorkerArgs a) { args.Force = force; // TODO: Decide whether it is necessary for the switch // command to report conflicts. #if NOT_IMPLEMENTED e.GetService<IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer); #endif try { a.Client.Switch(path, target, args); } catch (GitException ex) { exception = ex; } }); if (exception != null) { e.GetService<IVisualGitErrorHandler>().OnWarning(exception); } } }
public bool SaveAllDocumentsExcept(IEnumerable<string> paths) { if (paths == null) throw new ArgumentNullException("paths"); HybridCollection<string> pathsCol = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); pathsCol.UniqueAddRange(paths); bool ok = true; foreach (SccDocumentData data in _docMap.Values) { if (!pathsCol.Contains(data.Name)) { if (!data.SaveDocument(RunningDocumentTable)) ok = false; } } return ok; }
public void OnExecute(CommandEventArgs e) { ILogControl logWindow = e.Selection.GetActiveControl<ILogControl>(); IProgressRunner progressRunner = e.GetService<IProgressRunner>(); if (logWindow == null) return; IGitLogItem logItem = EnumTools.GetSingle(e.Selection.GetSelection<IGitLogItem>()); if (logItem == null) return; GitResetType type; using (var dialog = new ResetBranchDialog()) { dialog.Revision = logItem.Revision; dialog.RepositoryPath = logItem.RepositoryRoot; if (dialog.ShowDialog(e.Context) != DialogResult.OK) return; type = dialog.ResetType; } // Revert to revision, is revert everything after var revision = new GitRevisionRange(GitRevision.Working, logItem.Revision); IVisualGitOpenDocumentTracker tracker = e.GetService<IVisualGitOpenDocumentTracker>(); HybridCollection<string> nodes = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); foreach (GitOrigin o in logWindow.Origins) { foreach (string file in tracker.GetDocumentsBelow(o.Target.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()) { progressRunner.RunModal("Reverting", delegate(object sender, ProgressWorkerArgs ee) { foreach (GitOrigin item in logWindow.Origins) { var args = new GitResetArgs(); ee.Client.Reset( logItem.RepositoryRoot, logItem.Revision, type, args ); } }); } }
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) { ILastChangeInfo ci = e.GetService<ILastChangeInfo>(); if (ci != null) ci.SetLastChange(null, null); SvnRevision rev; bool allowUnversionedObstructions = false; bool updateExternals = true; bool setDepthInfinity = true; IAnkhSolutionSettings settings = e.GetService<IAnkhSolutionSettings>(); IFileStatusCache cache = e.GetService<IFileStatusCache>(); 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 (SvnProject p in GetSelectedProjects(e)) { ISvnProjectInfo 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); Dictionary<string, List<string>> groups = new Dictionary<string, List<string>>(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; } List<string> inWc; if (!groups.TryGetValue(wc.FullPath, out inWc)) { inWc = new List<string>(); groups.Add(wc.FullPath, inWc); } inWc.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.SetLastChange("Updated to:", updateResult.Revision.ToString()); } } }
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); // 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.Depth = SvnDepth.Empty; ra.AddExpectedError(SvnErrorCode.SVN_ERR_WC_NOT_DIRECTORY); // Parent revert invalidated this change foreach (SvnItem item in toRevert) { a.Client.Revert(item.FullPath, ra); } }); } }
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 void SerializeSccExcludeData(System.IO.Stream store, bool writeData) { ClearSolutionInfo(); // Force the right data string baseDir = SolutionDirectory; if (writeData) { if (_sccExcluded.Count == 0) { return; } using (BinaryWriter bw = new BinaryWriter(store)) { bw.Write(_sccExcluded.Count); foreach (string path in _sccExcluded) { if (baseDir != null) { bw.Write(SvnItem.MakeRelative(baseDir, path)); } else { bw.Write(path); } } } } else { if (store.Length == 0) { return; } using (BinaryReader br = new BinaryReader(store)) { int count = br.ReadInt32(); while (count-- > 0) { string path = br.ReadString(); try { if (baseDir != null) { path = SvnTools.GetNormalizedFullPath(Path.Combine(baseDir, path)); } else { path = SvnTools.GetNormalizedFullPath(path); } if (!_sccExcluded.Contains(path)) { _sccExcluded.Add(path); } } catch { } } } } }
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) { GitPullArgs args = new GitPullArgs(); string repositoryRoot; var repositoryRoots = new HashSet<string>(FileSystemUtil.StringComparer); foreach (var projectRoot in GetAllRoots(e)) { if ( GitTools.TryGetRepositoryRoot(projectRoot.FullPath, out repositoryRoot) && !repositoryRoots.Contains(repositoryRoot) ) repositoryRoots.Add(repositoryRoot); } if (repositoryRoots.Count > 1) { throw new InvalidOperationException("Pulling of multiple repository roots is not supported"); } repositoryRoot = repositoryRoots.Single(); if (e.Command == VisualGitCommand.PendingChangesPullEx) { if (!QueryParameters(e, repositoryRoot, args)) return; } else { args.MergeStrategy = GitMergeStrategy.DefaultForBranch; } GitPullResult result = null; ProgressRunnerArgs pa = new ProgressRunnerArgs(); pa.CreateLog = true; pa.TransportClientArgs = args; // 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); IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>(); foreach (string file in documentTracker.GetDocumentsBelow(repositoryRoot)) { 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()) { GitException exception = null; e.GetService<IProgressRunner>().RunModal(CommandStrings.PullingSolution, pa, delegate(object sender, ProgressWorkerArgs a) { e.GetService<IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer); try { a.Client.Pull(repositoryRoot, args, out result); } catch (GitException ex) { exception = ex; } }); if (exception != null) { e.GetService<IVisualGitErrorHandler>().OnWarning(exception); } } }
public override void OnExecute(CommandEventArgs e) { List<GitItem> toRevert = new List<GitItem>(); HybridCollection<string> contained = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); HybridCollection<string> checkedItems = null; foreach (GitItem i in e.Selection.GetSelectedGitItems(false)) { if (contained.Contains(i.FullPath)) continue; contained.Add(i.FullPath); if (i.IsModified || (i.IsVersioned && i.IsDocumentDirty) || i.IsConflicted) toRevert.Add(i); } Predicate<GitItem> initialCheckedFilter = null; if (toRevert.Count > 0) { checkedItems = new HybridCollection<string>(contained, StringComparer.OrdinalIgnoreCase); initialCheckedFilter = delegate(GitItem item) { return checkedItems.Contains(item.FullPath); }; } foreach (GitItem i in e.Selection.GetSelectedGitItems(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()); } } IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>(); ICollection<string> revertPaths = GitItem.GetPaths(toRevert); documentTracker.SaveDocuments(revertPaths); // 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) { GitRevertItemArgs ra = new GitRevertItemArgs(); ra.Depth = GitDepth.Empty; List<string> toRevertPaths = new List<string>(); foreach (GitItem item in toRevert) { toRevertPaths.Add(item.FullPath); } foreach (GitItem item in toRevert) { try { a.Client.RevertItem(toRevertPaths, ra); } catch (GitNoRepositoryException) { // Ignore path no repository exceptions. } } }); } }
public IEnumerable<Uri> GetRepositoryUris(bool forBrowse) { HybridCollection<Uri> uris = new HybridCollection<Uri>(); if (ProjectRootUri != null) uris.Add(ProjectRootUri); // Global keys (over all versions) using (RegistryKey rk = Config.OpenGlobalKey("Repositories")) { if (rk != null) LoadUris(uris, rk); } // Per hive using (RegistryKey rk = Config.OpenInstanceKey("Repositories")) { if (rk != null) LoadUris(uris, rk); } // Per user + Per hive using (RegistryKey rk = Config.OpenUserInstanceKey("Repositories")) { if (rk != null) LoadUris(uris, rk); } // Finally add the last used list from TortoiseSVN try { using (RegistryKey rk = Registry.CurrentUser.OpenSubKey( "SOFTWARE\\TortoiseSVN\\History\\repoURLS", RegistryKeyPermissionCheck.ReadSubTree)) { if (rk != null) LoadUris(uris, rk); } } catch (SecurityException) { /* Ignore no read only access; stupid sysadmins */ } IAnkhConfigurationService configSvc = Context.GetService<IAnkhConfigurationService>(); if (configSvc != null) { foreach (string u in configSvc.GetRecentReposUrls()) { Uri uri; if (u != null && Uri.TryCreate(u, UriKind.Absolute, out uri)) { if (!uris.Contains(uri)) uris.Add(uri); } } } return uris; }
public DocumentLock LockDocuments(IEnumerable<string> paths, DocumentLockType lockType) { if (paths == null) throw new ArgumentNullException("paths"); HybridCollection<string> locked = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); HybridCollection<string> ignoring = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); HybridCollection<string> readOnly = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); foreach (string path in paths) { SccDocumentData dd; if (_docMap.TryGetValue(path, out dd)) { if (!locked.Contains(path)) locked.Add(path); if (!ignoring.Contains(path) && dd.IgnoreFileChanges(true)) ignoring.Add(path); if (lockType >= DocumentLockType.ReadOnly && !readOnly.Contains(path) && !dd.IsReadOnly()) { // Don't set read-only twice!!! if (dd.SetReadOnly(true)) readOnly.Add(path); } } } return new SccDocumentLock(this, locked, ignoring, readOnly); }
private static void PerformUpdate(CommandEventArgs e, ProgressWorkerArgs wa, SvnRevision rev, bool allowUnversionedObstructions, bool updateExternals, bool setDepthInfinity, IEnumerable<List<string>> groups, out SvnUpdateResult updateResult) { SvnUpdateArgs ua = new SvnUpdateArgs(); ua.Revision = rev; ua.AllowObstructions = allowUnversionedObstructions; ua.IgnoreExternals = !updateExternals; ua.KeepDepth = setDepthInfinity; updateResult = null; HybridCollection<string> handledExternals = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); ua.Notify += delegate(object ss, SvnNotifyEventArgs ee) { if (ee.Action == SvnNotifyAction.UpdateExternal) { if (!handledExternals.Contains(ee.FullPath)) handledExternals.Add(ee.FullPath); } }; e.Context.GetService<IConflictHandler>().RegisterConflictHandler(ua, wa.Synchronizer); foreach (List<string> group in groups) { // Currently Subversion runs update per item passed and in // Subversion 1.6 passing each item separately is actually // a tiny bit faster than passing them all at once. // (sleep_for_timestamp fails its fast route) foreach (string path in group) { if (handledExternals.Contains(path)) continue; SvnUpdateResult result; wa.Client.Update(path, ua, out result); if (updateResult == null) updateResult = result; // Return the primary update as version for output } } }
public SccDocumentLock(OpenDocumentTracker tracker, HybridCollection<string> locked, HybridCollection<string> ignoring, HybridCollection<string> readOnly) { if (tracker == null) throw new ArgumentNullException("tracker"); else if (locked == null) throw new ArgumentNullException("locked"); else if (ignoring == null) throw new ArgumentNullException("ignoring"); else if (readOnly == null) throw new ArgumentNullException("readOnly"); _tracker = tracker; _locked = locked; _ignoring = ignoring; _readonly = readOnly; _fsIgnored = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); _changedPaths = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); _monitor = new Dictionary<uint, string>(); _altMonitor = new Dictionary<string, FileInfo>(); _change = tracker.GetService<IVsFileChangeEx>(typeof(SVsFileChangeEx)); foreach (string file in locked) { // This files auto reload could not be suspended by calling Ignore on the document // We must therefore stop posting messages to it by stopping it in the change monitor // But to be able to tell if there are changes.. We keep some stats ourselves if (!ignoring.Contains(file) && ErrorHandler.Succeeded(_change.IgnoreFile(0, file, 1))) { _fsIgnored.Add(file); FileInfo info = new FileInfo(file); info.Refresh(); if (info.Exists) { GC.KeepAlive(info.LastWriteTime); GC.KeepAlive(info.CreationTime); GC.KeepAlive(info.Length); } _altMonitor.Add(file, info); } } }
/// <see cref="VisualGit.Commands.ICommandHandler.OnExecute" /> public void OnExecute(CommandEventArgs e) { List<GitItem> gitItems = new List<GitItem>(); IFileStatusCache cache = e.GetService<IFileStatusCache>(); GitRevision revision = null; string repositoryPath = null; switch (e.Command) { case VisualGitCommand.LogMergeThisRevision: ILogControl logWindow = e.Selection.GetActiveControl<ILogControl>(); IProgressRunner progressRunner = e.GetService<IProgressRunner>(); if (logWindow == null) return; IGitLogItem logItem = EnumTools.GetSingle(e.Selection.GetSelection<IGitLogItem>()); if (logItem == null) return; revision = logItem.Revision; repositoryPath = logItem.RepositoryRoot; break; case VisualGitCommand.ItemMerge: // TODO: Check for solution and/or project selection to use the folder instead of the file foreach (GitItem item in e.Selection.GetSelectedGitItems(false)) { gitItems.Add(item); } break; case VisualGitCommand.ProjectMerge: foreach (GitProject p in e.Selection.GetSelectedProjects(false)) { IProjectFileMapper pfm = e.GetService<IProjectFileMapper>(); IGitProjectInfo info = pfm.GetProjectInfo(p); if (info != null && info.ProjectDirectory != null) { gitItems.Add(cache[info.ProjectDirectory]); } } break; case VisualGitCommand.SolutionMerge: gitItems.Add(cache[e.GetService<IVisualGitSolutionSettings>().ProjectRoot]); break; default: throw new InvalidOperationException(); } if (repositoryPath == null) { Debug.Assert(gitItems.Count > 0); repositoryPath = GitTools.GetRepositoryRoot(gitItems[0].FullPath); } GitRef mergeBranch; var args = new GitMergeArgs(); using (var dialog = new MergeDialog()) { dialog.Context = e.Context; dialog.Revision = revision; dialog.RepositoryPath = repositoryPath; if (gitItems.Count > 0) dialog.GitItem = gitItems[0]; dialog.Args = args; if (dialog.ShowDialog(e.Context) != DialogResult.OK) return; mergeBranch = dialog.MergeBranch; } // 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); IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>(); foreach (string file in documentTracker.GetDocumentsBelow(repositoryPath)) { 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()) { GitException exception = null; e.GetService<IProgressRunner>().RunModal( "Changing Current Branch", delegate(object sender, ProgressWorkerArgs a) { e.GetService<IConflictHandler>().RegisterConflictHandler(args, a.Synchronizer); try { a.Client.Merge(repositoryPath, mergeBranch, args); } catch (GitException ex) { exception = ex; } }); if (exception != null) { e.GetService<IVisualGitErrorHandler>().OnWarning(exception); } } }
static void Resolve(CommandEventArgs e, GitAccept accept) { HybridCollection<string> paths = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase); foreach (GitItem item in e.Selection.GetSelectedGitItems(true)) { if (!item.IsConflicted) continue; if (!paths.Contains(item.FullPath)) paths.Add(item.FullPath); } IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>(); documentTracker.SaveDocuments(paths); // Make sure all files are saved before updating/merging! using (DocumentLock lck = documentTracker.LockDocuments(paths, DocumentLockType.NoReload)) using (lck.MonitorChangesForReload()) using (GitClient client = e.GetService<IGitClientPool>().GetNoUIClient()) { GitResolveArgs a = new GitResolveArgs(); a.Depth = GitDepth.Empty; foreach (string p in paths) { client.Resolve(p, accept, a); } } }
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); }); } } } }