static string GetSelectedPatch( FileViewer fileViewer, ObjectId firstId, ObjectId selectedId, GitItemStatus file) { if (firstId == ObjectId.CombinedDiffId) { var diffOfConflict = fileViewer.Module.GetCombinedDiffContent(selectedId, file.Name, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); return(string.IsNullOrWhiteSpace(diffOfConflict) ? Strings.UninterestingDiffOmitted : diffOfConflict); } if (file.IsSubmodule && file.GetSubmoduleStatusAsync() is not null) { // Patch already evaluated var status = ThreadHelper.JoinableTaskFactory.Run(file.GetSubmoduleStatusAsync); return(status is not null ? LocalizationHelpers.ProcessSubmoduleStatus(fileViewer.Module, status) : $"Failed to get status for submodule \"{file.Name}\""); } var patch = GetItemPatch(fileViewer.Module, file, firstId, selectedId, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); return(file.IsSubmodule ? LocalizationHelpers.ProcessSubmodulePatch(fileViewer.Module, file.Name, patch) : patch?.Text);
static string?GetSelectedPatch( FileViewer fileViewer, ObjectId firstId, ObjectId selectedId, GitItemStatus file) { if (firstId == ObjectId.CombinedDiffId) { var diffOfConflict = fileViewer.Module.GetCombinedDiffContent(selectedId, file.Name, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); return(string.IsNullOrWhiteSpace(diffOfConflict) ? TranslatedStrings.UninterestingDiffOmitted : diffOfConflict); } if (file.IsSubmodule) { #pragma warning disable VSTHRD103 // Call async methods when in an async method var status = ThreadHelper.JoinableTaskFactory.Run(file.GetSubmoduleStatusAsync !); #pragma warning restore VSTHRD103 // Call async methods when in an async method return(status is not null ? LocalizationHelpers.ProcessSubmoduleStatus(fileViewer.Module, status) : $"Failed to get status for submodule \"{file.Name}\""); } var patch = GetItemPatch(fileViewer.Module, file, firstId, selectedId, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); return(file.IsSubmodule ? LocalizationHelpers.ProcessSubmodulePatch(fileViewer.Module, file.Name, patch) : patch?.Text);
public static string GetSelectedPatch(this FileViewer diffViewer, string firstRevision, string secondRevision, GitItemStatus file) { if (!file.IsTracked) { var fullPath = Path.Combine(diffViewer.Module.WorkingDir, file.Name); if (Directory.Exists(fullPath) && GitModule.IsValidGitWorkingDir(fullPath)) { // git-status does not detect details for untracked and git-diff --no-index will not give info return(LocalizationHelpers.GetSubmoduleText(diffViewer.Module, file.Name.TrimEnd('/'), "")); } } if (file.IsSubmodule && file.SubmoduleStatus != null) { return(LocalizationHelpers.ProcessSubmoduleStatus(diffViewer.Module, file.SubmoduleStatus.Result)); } PatchApply.Patch patch = GetItemPatch(diffViewer.Module, file, firstRevision, secondRevision, diffViewer.GetExtraDiffArguments(), diffViewer.Encoding); if (patch == null) { return(string.Empty); } if (file.IsSubmodule) { return(LocalizationHelpers.ProcessSubmodulePatch(diffViewer.Module, file.Name, patch)); } return(patch.Text); }
static async Task <string?> GetSelectedPatchAsync( FileViewer fileViewer, ObjectId firstId, ObjectId selectedId, GitItemStatus file, CancellationToken cancellationToken) { if (firstId == ObjectId.CombinedDiffId) { var diffOfConflict = fileViewer.Module.GetCombinedDiffContent(selectedId, file.Name, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); cancellationToken.ThrowIfCancellationRequested(); return(string.IsNullOrWhiteSpace(diffOfConflict) ? TranslatedStrings.UninterestingDiffOmitted : diffOfConflict); } var task = file.GetSubmoduleStatusAsync(); if (file.IsSubmodule && task is not null) { // Patch already evaluated var status = await task; cancellationToken.ThrowIfCancellationRequested(); return(status is not null ? LocalizationHelpers.ProcessSubmoduleStatus(fileViewer.Module, status) : $"Failed to get status for submodule \"{file.Name}\""); } var patch = await GetItemPatchAsync(fileViewer.Module, file, firstId, selectedId, fileViewer.GetExtraDiffArguments(), fileViewer.Encoding); cancellationToken.ThrowIfCancellationRequested(); return(file.IsSubmodule ? LocalizationHelpers.ProcessSubmodulePatch(fileViewer.Module, file.Name, patch) : patch?.Text);
public static string GetSelectedPatch(this FileViewer diffViewer, string firstRevision, string secondRevision, GitItemStatus file) { if (firstRevision == null) { return(null); } //to simplify if-ology if (GitRevision.IsArtificial(secondRevision) && firstRevision != GitRevision.UnstagedGuid) { string temp = firstRevision; firstRevision = secondRevision; secondRevision = temp; } if (IsItemUntracked(file, firstRevision, secondRevision)) { var fullPath = Path.Combine(diffViewer.Module.WorkingDir, file.Name); if (Directory.Exists(fullPath) && GitModule.IsValidGitWorkingDir(fullPath)) { return(LocalizationHelpers.GetSubmoduleText(diffViewer.Module, file.Name.TrimEnd('/'), "")); } return(FileReader.ReadFileContent(fullPath, diffViewer.Encoding)); } if (file.IsSubmodule && file.SubmoduleStatus != null) { return(LocalizationHelpers.ProcessSubmoduleStatus(diffViewer.Module, file.SubmoduleStatus.Result)); } PatchApply.Patch patch = GetItemPatch(diffViewer.Module, file, firstRevision, secondRevision, diffViewer.GetExtraDiffArguments(), diffViewer.Encoding); if (patch == null) { return(string.Empty); } if (file.IsSubmodule) { return(LocalizationHelpers.ProcessSubmodulePatch(diffViewer.Module, file.Name, patch)); } return(patch.Text); }
private static string GetSelectedPatch( [NotNull] this FileViewer diffViewer, [CanBeNull] ObjectId firstRevision, [CanBeNull] ObjectId secondRevision, [NotNull] GitItemStatus file) { if (!file.IsTracked) { var fullPath = Path.Combine(diffViewer.Module.WorkingDir, file.Name); if (Directory.Exists(fullPath) && GitModule.IsValidGitWorkingDir(fullPath)) { // git-status does not detect details for untracked and git-diff --no-index will not give info return(LocalizationHelpers.GetSubmoduleText(diffViewer.Module, file.Name.TrimEnd('/'), "")); } } if (file.IsSubmodule && file.GetSubmoduleStatusAsync() != null) { return(LocalizationHelpers.ProcessSubmoduleStatus(diffViewer.Module, ThreadHelper.JoinableTaskFactory.Run(() => file.GetSubmoduleStatusAsync()))); } Patch patch = GetItemPatch(diffViewer.Module, file, firstRevision, secondRevision, diffViewer.GetExtraDiffArguments(), diffViewer.Encoding); if (patch == null) { return(string.Empty); } if (file.IsSubmodule) { return(LocalizationHelpers.ProcessSubmodulePatch(diffViewer.Module, file.Name, patch)); } return(patch.Text); }
/// <summary> /// View the changes between the revisions, if possible as a diff /// </summary> /// <param name="fileViewer">Current FileViewer</param> /// <param name="item">The FileStatusItem to present changes for</param> /// <param name="defaultText">default text if no diff is possible</param> /// <param name="openWithDiffTool">The difftool command to open with</param> /// <returns>Task to view</returns> public static Task ViewChangesAsync(this FileViewer fileViewer, [CanBeNull] FileStatusItem item, [NotNull] string defaultText = "", [CanBeNull] Action openWithDiffTool = null) { if (item?.Item?.IsStatusOnly ?? false) { // Present error (e.g. parsing Git) return(fileViewer.ViewTextAsync(item.Item.Name, item.Item.ErrorMessage)); } if (item?.Item is null || item.SecondRevision?.ObjectId is null) { if (!string.IsNullOrWhiteSpace(defaultText)) { return(fileViewer.ViewTextAsync(item?.Item?.Name, defaultText)); } fileViewer.Clear(); return(Task.CompletedTask); } var firstId = item.FirstRevision?.ObjectId ?? item.SecondRevision.FirstParentId; openWithDiffTool ??= OpenWithDiffTool; if (item.Item.IsNew || firstId is null || FileHelper.IsImage(item.Item.Name)) { // View blob guid from revision, or file for worktree return(fileViewer.ViewGitItemRevisionAsync(item.Item, item.SecondRevision.ObjectId, openWithDiffTool)); } if (item.Item.IsRangeDiff) { // This command may take time, give an indication of what is going on // The sha are incorrect if baseA/baseB is set, to simplify the presentation fileViewer.ViewText("range-diff.sh", $"git range-diff {firstId}...{item.SecondRevision.ObjectId}"); string output = fileViewer.Module.GetRangeDiff( firstId, item.SecondRevision.ObjectId, item.BaseA, item.BaseB, fileViewer.GetExtraDiffArguments(isRangeDiff: true)); // Try set highlighting from first found filename var match = new Regex(@"\n\s*(@@|##)\s+(?<file>[^#:\n]+)").Match(output ?? ""); var filename = match.Groups["file"].Success ? match.Groups["file"].Value : item.Item.Name; return(fileViewer.ViewRangeDiffAsync(filename, output ?? defaultText)); } string selectedPatch = GetSelectedPatch(fileViewer, firstId, item.SecondRevision.ObjectId, item.Item) ?? defaultText; return(item.Item.IsSubmodule ? fileViewer.ViewTextAsync(item.Item.Name, text: selectedPatch, openWithDifftool: openWithDiffTool) : fileViewer.ViewPatchAsync(item, text: selectedPatch, openWithDifftool: openWithDiffTool)); void OpenWithDiffTool() { fileViewer.Module.OpenWithDifftool( item.Item.Name, item.Item.OldName, firstId?.ToString(), item.SecondRevision.ToString(), isTracked: item.Item.IsTracked); }
public static string GetSelectedPatch(this FileViewer diffViewer, RevisionGrid grid, GitItemStatus file) { IList <GitRevision> revisions = grid.GetSelectedRevisions(); if (revisions.Count == 0) { return(null); } string firstRevision = revisions[0].Guid; var secondRevision = revisions.Count == 2 ? revisions[1].Guid : null; //to simplify if-ology if (GitRevision.IsArtificial(secondRevision) && firstRevision != GitRevision.UncommittedWorkingDirGuid) { firstRevision = secondRevision; secondRevision = revisions[0].Guid; } string extraDiffArgs = null; if (firstRevision == GitRevision.UncommittedWorkingDirGuid) //working dir changes { if (secondRevision == null || secondRevision == GitRevision.IndexGuid) { if (file.IsTracked) { return(ProcessDiffText(GitModule.Current.GetCurrentChanges(file.Name, file.OldName, false, diffViewer.GetExtraDiffArguments(), diffViewer.Encoding), file.IsSubmodule)); } return(FileReader.ReadFileContent(GitModule.CurrentWorkingDir + file.Name, diffViewer.Encoding)); } else { firstRevision = secondRevision; secondRevision = string.Empty; } } if (firstRevision == GitRevision.IndexGuid) //index { if (secondRevision == null) { return(ProcessDiffText(GitModule.Current.GetCurrentChanges(file.Name, file.OldName, true, diffViewer.GetExtraDiffArguments(), diffViewer.Encoding), file.IsSubmodule)); } //rev1 vs index firstRevision = secondRevision; secondRevision = string.Empty; extraDiffArgs = string.Join(" ", extraDiffArgs, "--cached"); } Debug.Assert(!GitRevision.IsArtificial(firstRevision), string.Join(" ", firstRevision, secondRevision)); if (secondRevision == null) { secondRevision = firstRevision + "^"; } PatchApply.Patch patch = GitModule.Current.GetSingleDiff(firstRevision, secondRevision, file.Name, file.OldName, string.Join(" ", diffViewer.GetExtraDiffArguments(), extraDiffArgs), diffViewer.Encoding); if (patch == null) { return(string.Empty); } return(ProcessDiffText(patch.Text, file.IsSubmodule)); }
/// <summary> /// View the changes between the revisions, if possible as a diff. /// </summary> /// <param name="fileViewer">Current FileViewer.</param> /// <param name="item">The FileStatusItem to present changes for.</param> /// <param name="defaultText">default text if no diff is possible.</param> /// <param name="openWithDiffTool">The difftool command to open with.</param> /// <returns>Task to view.</returns> public static async Task ViewChangesAsync(this FileViewer fileViewer, FileStatusItem?item, CancellationToken cancellationToken, string defaultText = "", Action?openWithDiffTool = null) { if (item?.Item.IsStatusOnly ?? false) { // Present error (e.g. parsing Git) await fileViewer.ViewTextAsync(item.Item.Name, item.Item.ErrorMessage ?? ""); return; } if (item?.Item is null || item.SecondRevision?.ObjectId is null) { if (!string.IsNullOrWhiteSpace(defaultText)) { await fileViewer.ViewTextAsync(item?.Item?.Name, defaultText); return; } fileViewer.Clear(); return; } var firstId = item.FirstRevision?.ObjectId ?? item.SecondRevision.FirstParentId; openWithDiffTool ??= OpenWithDiffTool; if (item.Item.IsNew || firstId is null || (!item.Item.IsDeleted && FileHelper.IsImage(item.Item.Name))) { // View blob guid from revision, or file for worktree await fileViewer.ViewGitItemAsync(item, openWithDiffTool); return; } if (item.Item.IsRangeDiff) { // Git range-diff has cubic runtime complexity and can be slow and memory consuming, // give an indication of what is going on string range = item.BaseA is null || item.BaseB is null ? $"{firstId}...{item.SecondRevision.ObjectId}" : $"{item.BaseA}..{firstId} {item.BaseB}..{item.SecondRevision.ObjectId}"; await fileViewer.ViewTextAsync("range-diff.sh", $"git range-diff {range}"); string output = fileViewer.Module.GetRangeDiff( firstId, item.SecondRevision.ObjectId, item.BaseA, item.BaseB, fileViewer.GetExtraDiffArguments(isRangeDiff: true)); // Try set highlighting from first found filename Match match = new Regex(@"\n\s*(@@|##)\s+(?<file>[^#:\n]+)").Match(output ?? ""); string filename = match.Groups["file"].Success ? match.Groups["file"].Value : item.Item.Name; cancellationToken.ThrowIfCancellationRequested(); await fileViewer.ViewRangeDiffAsync(filename, output ?? defaultText); return; } string selectedPatch = (await GetSelectedPatchAsync(fileViewer, firstId, item.SecondRevision.ObjectId, item.Item)) ?? defaultText; cancellationToken.ThrowIfCancellationRequested(); if (item.Item.IsSubmodule) { await fileViewer.ViewTextAsync(item.Item.Name, text : selectedPatch, openWithDifftool : openWithDiffTool); } else { await fileViewer.ViewPatchAsync(item, text : selectedPatch, openWithDifftool : openWithDiffTool); } return; void OpenWithDiffTool() { fileViewer.Module.OpenWithDifftool( item.Item.Name, item.Item.OldName, firstId?.ToString(), item.SecondRevision.ToString(), isTracked: item.Item.IsTracked); }