public override void OnExecute(CommandEventArgs e) { PathSelectorResult result = ShowDialog(e); if (!result.Succeeded) return; GitRevisionRange revRange = new GitRevisionRange(result.RevisionStart, result.RevisionEnd); IVisualGitTempFileManager tempfiles = e.GetService<IVisualGitTempFileManager>(); string tempFile = tempfiles.GetTempFile(".patch"); IVisualGitSolutionSettings ss = e.GetService<IVisualGitSolutionSettings>(); string slndir = ss.ProjectRoot; string slndirP = slndir + "\\"; GitDiffArgs args = new GitDiffArgs(); args.IgnoreAncestry = true; args.NoDeleted = false; args.Depth = result.Depth; using (MemoryStream stream = new MemoryStream()) { e.Context.GetService<IProgressRunner>().RunModal("Diffing", delegate(object sender, ProgressWorkerArgs ee) { foreach (GitItem item in result.Selection) { GitWorkingCopy wc; if (!string.IsNullOrEmpty(slndir) && item.FullPath.StartsWith(slndirP, StringComparison.OrdinalIgnoreCase)) args.RelativeToPath = slndir; else if ((wc = item.WorkingCopy) != null) args.RelativeToPath = wc.FullPath; else args.RelativeToPath = null; ee.Client.Diff(item.FullPath, revRange, args, stream); } stream.Flush(); stream.Position = 0; }); using (StreamReader sr = new StreamReader(stream)) { File.WriteAllText(tempFile, sr.ReadToEnd(), Encoding.UTF8); VsShellUtilities.OpenDocument(e.Context, tempFile); } } }
void ExecuteDiff(CommandEventArgs e, ICollection<GitOrigin> targets, GitRevisionRange range) { if (targets.Count != 1) return; var target = EnumTools.GetSingle(targets); GitTarget diffTarget = target.Target; IVisualGitDiffHandler diff = e.GetService<IVisualGitDiffHandler>(); VisualGitDiffArgs da = new VisualGitDiffArgs(); string[] files = diff.GetTempFiles(diffTarget, range.StartRevision, range.EndRevision, true); if (files == null) return; da.BaseFile = files[0]; da.MineFile = files[1]; da.BaseTitle = diff.GetTitle(diffTarget, range.StartRevision); da.MineTitle = diff.GetTitle(diffTarget, range.EndRevision); da.ReadOnly = true; diff.RunDiff(da); }
public override void OnExecute(CommandEventArgs e) { List<GitItem> selectedFiles = new List<GitItem>(); bool selectionHasDeleted = false; if (e.Command == VisualGitCommand.DocumentShowChanges) { GitItem item = e.Selection.ActiveDocumentItem; if(item == null) return; selectedFiles.Add(item); } else foreach (GitItem item in e.Selection.GetSelectedGitItems(false)) { if (!item.IsVersioned || (item.Status.State == GitStatus.Added && !item.Status.IsCopied)) continue; if ( e.Command == VisualGitCommand.ItemCompareBase || e.Command == VisualGitCommand.ItemShowChanges) { if (!(item.IsModified || item.IsDocumentDirty) || !item.IsLocalDiffAvailable // exclude if local diff is not available ) continue; } if (e.Command == VisualGitCommand.DiffLocalItem) { selectionHasDeleted |= !NotDeletedFilter(item); } selectedFiles.Add(item); } GitRevisionRange revRange = null; switch (e.Command) { case VisualGitCommand.DiffLocalItem: break; // revRange null -> show selector case VisualGitCommand.ItemCompareBase: case VisualGitCommand.ItemShowChanges: case VisualGitCommand.DocumentShowChanges: revRange = new GitRevisionRange(GitRevision.Base, GitRevision.Working); break; case VisualGitCommand.ItemCompareCommitted: revRange = new GitRevisionRange(GitRevision.Committed, GitRevision.Working); break; case VisualGitCommand.ItemCompareLatest: revRange = new GitRevisionRange(GitRevision.Head, GitRevision.Working); break; case VisualGitCommand.ItemComparePrevious: revRange = new GitRevisionRange(GitRevision.Previous, GitRevision.Working); break; } if (e.PromptUser || selectedFiles.Count > 1 || revRange == null) { PathSelectorInfo info = new PathSelectorInfo("Select item for Diff", selectedFiles); info.SingleSelection = false; info.RevisionStart = revRange == null ? GitRevision.Base : revRange.StartRevision; info.RevisionEnd = revRange == null ? GitRevision.Working : revRange.EndRevision; if (selectionHasDeleted) { // do not allow selecting deleted items if the revision combination includes GitRevision.Working info.CheckableFilter += new PathSelectorInfo.SelectableFilter(delegate(GitItem item, GitRevision from, GitRevision to) { if (item != null && (from == GitRevision.Working || to == GitRevision.Working ) ) { return NotDeletedFilter(item); } return true; }); } info.EnableRecursive = false; info.Depth = GitDepth.Infinity; PathSelectorResult result; // should we show the path selector? if (e.PromptUser || !Shift) { IUIShell ui = e.GetService<IUIShell>(); result = ui.ShowPathSelector(info); if (!result.Succeeded) return; } else result = info.DefaultResult; selectedFiles.Clear(); selectedFiles.AddRange(result.Selection); revRange = new GitRevisionRange(result.RevisionStart, result.RevisionEnd); } if (revRange.EndRevision.RevisionType == GitRevisionType.Working || revRange.StartRevision.RevisionType == GitRevisionType.Working) { // Save only the files needed IVisualGitOpenDocumentTracker tracker = e.GetService<IVisualGitOpenDocumentTracker>(); if (tracker != null) tracker.SaveDocuments(GitItem.GetPaths(selectedFiles)); } IVisualGitDiffHandler diff = e.GetService<IVisualGitDiffHandler>(); foreach (GitItem item in selectedFiles) { VisualGitDiffArgs da = new VisualGitDiffArgs(); if (item.Status.IsCopied && (!revRange.StartRevision.RequiresWorkingCopy || !revRange.EndRevision.RequiresWorkingCopy)) { // The file is copied, use its origins history instead of that of the new file GitTarget 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 == GitRevision.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 == GitRevision.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); } }
public bool CreatePatch(IEnumerable<PendingChange> changes, PendingChangeCreatePatchArgs args) { using (PendingCommitState state = new PendingCommitState(Context, changes)) { if (!PreCommit_VerifySingleRoot(state)) // Verify single root 'first' return false; if (!PreCommit_SaveDirty(state)) return false; if (args.AddUnversionedFiles) { if (!PreCommit_AddNewFiles(state)) return false; if (!PreCommit_HandleMissingFiles(state)) return false; } state.FlushState(); if (!PreCommit_AddNeededParents(state)) return false; if (!PreCommit_VerifySingleRoot(state)) // Verify single root 'again' return false; } string relativeToPath = args.RelativeToPath; string relativeToPathP = relativeToPath.EndsWith("\\") ? relativeToPath : (relativeToPath + "\\"); string fileName = args.FileName; GitRevisionRange revRange = new GitRevisionRange(GitRevision.Base, GitRevision.Working); GitDiffArgs a = new GitDiffArgs(); a.IgnoreAncestry = true; a.NoDeleted = false; a.Depth = GitDepth.Empty; using (MemoryStream stream = new MemoryStream()) { GetService<IProgressRunner>().RunModal(PccStrings.DiffTitle, delegate(object sender, ProgressWorkerArgs e) { foreach (PendingChange pc in changes) { GitItem item = pc.GitItem; GitWorkingCopy wc; if (!string.IsNullOrEmpty(relativeToPath) && item.FullPath.StartsWith(relativeToPathP, StringComparison.OrdinalIgnoreCase)) a.RelativeToPath = relativeToPath; else if ((wc = item.WorkingCopy) != null) a.RelativeToPath = wc.FullPath; else a.RelativeToPath = null; e.Client.Diff(item.FullPath, revRange, a, stream); } stream.Flush(); stream.Position = 0; }); using (StreamReader sr = new StreamReader(stream)) { string line; // Parse to lines to resolve EOL issues using (StreamWriter sw = File.CreateText(fileName)) { while (null != (line = sr.ReadLine())) sw.WriteLine(line); } } } return true; }
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 ); } }); } }