public bool ShouldEnableSecondItemDiff(FileStatusItem item, bool isSecondRevision) { // Git reference in this revision or work tree file existing on the file system return(item is not null && !item.Item.IsSubmodule && (isSecondRevision ? !item.Item.IsDeleted : !item.Item.IsNew)); }
public FileStatusItem CreateFileStatusItem(string name, GitRevision rev) { var gis = new GitItemStatus { IsNew = true, Name = name }; var fsi = new FileStatusItem(null, rev, gis); return(fsi); }
public void RememberFile_GetGitCommit_SecondWorkTree() { var rev = new GitRevision(ObjectId.Random()); var workTree = new GitRevision(ObjectId.WorkTreeId); var name = "WorkTreeFile"; var item = new FileStatusItem( firstRev: rev, secondRev: workTree, item: new GitItemStatus(name)); _rememberFileContextMenuController.GetGitCommit(null, item, true).Should().Be(name); }
public void RememberFile_GetGitCommit_CommitNoOld(bool isSecondRev) { var id = ObjectId.Random(); var rev = new GitRevision(id); const string newName = "newName"; var item = new FileStatusItem( firstRev: rev, secondRev: rev, item: new GitItemStatus(name: newName)); var expected = $"{id}:{newName}"; _rememberFileContextMenuController.GetGitCommit(null, item, isSecondRev).Should().Be(expected); }
public void RememberFile_ShouldEnableSecondRemember_WorkTree(bool isSubmodule, bool isDeleted, bool isSecondRev, bool result) { var rev = new GitRevision(ObjectId.Random()); var item = new FileStatusItem( firstRev: rev, secondRev: new GitRevision(ObjectId.WorkTreeId), item: new GitItemStatus("file1") { IsSubmodule = isSubmodule, IsDeleted = isDeleted }); _rememberFileContextMenuController.ShouldEnableSecondItemDiff(item, isSecondRev).Should().Be(result); }
public void RememberFile_GetGitCommit_null() { var rev = new GitRevision(ObjectId.Random()); var workTree = new GitRevision(ObjectId.WorkTreeId); _rememberFileContextMenuController.GetGitCommit(null, null, false).Should().BeNull(); var item = new FileStatusItem( firstRev: null, secondRev: rev, item: new GitItemStatus("file")); _rememberFileContextMenuController.GetGitCommit(null, item, false).Should().BeNull(); }
public void RememberFile_GetGitCommit_Index_GetBlob() { var rev = new GitRevision(ObjectId.Random()); var index = new GitRevision(ObjectId.IndexId); const string name = "File"; var item = new FileStatusItem( firstRev: rev, secondRev: index, item: new GitItemStatus { Name = name, TreeGuid = null }); _rememberFileContextMenuController.GetGitCommit(GetFileBlobHash, item, true).Should().Be(ObjectId.IndexId.ToString()); }
public void RememberFile_GetGitCommit_Index_Tree() { var rev = new GitRevision(ObjectId.Random()); var index = new GitRevision(ObjectId.IndexId); const string name = "File"; var item = new FileStatusItem( firstRev: rev, secondRev: index, item: new GitItemStatus(name) { TreeGuid = ObjectId.Random() }); _rememberFileContextMenuController.GetGitCommit(null, item, true).Should().Be(item.Item.TreeGuid?.ToString()); }
/// <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 (!string.IsNullOrWhiteSpace(item?.Item?.ErrorMessage)) { // Present error (e.g. parsing Git) return(fileViewer.ViewTextAsync(item.Item.Name, item.Item.ErrorMessage)); } if (item?.Item == null || item.SecondRevision?.ObjectId == null) { if (!string.IsNullOrWhiteSpace(defaultText)) { return(fileViewer.ViewTextAsync(item?.Item?.Name, defaultText)); } fileViewer.Clear(); return(Task.CompletedTask); } var firstId = item.FirstRevision?.ObjectId ?? item.SecondRevision.FirstParentGuid; openWithDiffTool ??= OpenWithDiffTool; if (item.Item.IsNew || firstId == null || FileHelper.IsImage(item.Item.Name)) { // View blob guid from revision, or file for worktree return(fileViewer.ViewGitItemRevisionAsync(item.Item, item.SecondRevision.ObjectId, openWithDiffTool)); } string selectedPatch = GetSelectedPatch(fileViewer, firstId, item.SecondRevision.ObjectId, item.Item); return(item.Item.IsSubmodule || selectedPatch == null ? fileViewer.ViewTextAsync(item.Item.Name, text : selectedPatch ?? defaultText, openWithDifftool : openWithDiffTool) : fileViewer.ViewPatchAsync(item.Item.Name, text: selectedPatch, openWithDifftool: openWithDiffTool)); void OpenWithDiffTool() { fileViewer.Module.OpenWithDifftool( item.Item.Name, item.Item.OldName, firstId?.ToString(), item.SecondRevision.ToString(), "", item.Item.IsTracked); }
// Executes GET requsts for all files private static ActionResult GetHandler(IFileHandler handler) { IFileStatus status = new FileStatus(); using (FilesModel db = new FilesModel()) { foreach (var row in db.Files) { string url = handler.Context.Request.Url.OriginalString + "?fileName=" + row.Id.ToString(); IFileStatusItem file = new FileStatusItem() { ContentType = row.Type, DeleteType = "DELETE", FileName = row.Name, FileSize = row.Size, OriginalName = row.Original, Progress = "100", Success = true, ThumbnailUrl = row.Preview, // Set an identifier for GET and DELETE requests DeleteUrl = url, FileUrl = url }; status.Files.Add(file); } } handler.FileStatus = status; // Create client plugin specific result and return an ActionResult IBackloadResult result = handler.Services.Core.CreatePluginResult(); return(ResultCreator.Create((IFileStatusResult)result)); }
/// <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); }
private void UpdateSelectedFileViewers(bool force = false) { var selectedRevisions = FileChanges.GetSelectedRevisions(); if (selectedRevisions.Count == 0) { return; } GitRevision revision = selectedRevisions[0]; var children = FileChanges.GetRevisionChildren(revision.ObjectId); var fileName = revision.Name; if (string.IsNullOrEmpty(fileName)) { fileName = FileName; } SetTitle(fileName); if (revision.IsArtificial) { tabControl1.SelectedTab = DiffTab; CommitInfoTabPage.Parent = null; BlameTab.Parent = null; ViewTab.Parent = null; } else { if (CommitInfoTabPage.Parent == null) { tabControl1.TabPages.Insert(0, CommitInfoTabPage); } if (ViewTab.Parent == null) { var index = tabControl1.TabPages.IndexOf(DiffTab); Debug.Assert(index != -1, "TabControl should contain diff tab page"); tabControl1.TabPages.Insert(index + 1, ViewTab); } if (BlameTab.Parent == null) { var index = tabControl1.TabPages.IndexOf(ViewTab); Debug.Assert(index != -1, "TabControl should contain view tab page"); tabControl1.TabPages.Insert(index + 1, BlameTab); } } if (tabControl1.SelectedTab == BlameTab) { Blame.LoadBlame(revision, children, fileName, FileChanges, BlameTab, Diff.Encoding, force: force); } else if (tabControl1.SelectedTab == ViewTab) { View.Encoding = Diff.Encoding; var file = new GitItemStatus { IsTracked = true, Name = fileName, IsSubmodule = GitModule.IsValidGitWorkingDir(_fullPathResolver.Resolve(fileName)) }; View.ViewGitItemRevisionAsync(file, revision.ObjectId); } else if (tabControl1.SelectedTab == DiffTab) { var file = new GitItemStatus { IsTracked = true, Name = fileName, IsSubmodule = GitModule.IsValidGitWorkingDir(_fullPathResolver.Resolve(fileName)) }; var revisions = FileChanges.GetSelectedRevisions(); var item = new FileStatusItem(firstRev: revisions.Skip(1).LastOrDefault(), secondRev: revisions.FirstOrDefault(), file); Diff.ViewChangesAsync(item, defaultText: "You need to select at least one revision to view diff."); } else if (tabControl1.SelectedTab == CommitInfoTabPage) { CommitDiff.SetRevision(revision.ObjectId, fileName); } if (_buildReportTabPageExtension == null) { _buildReportTabPageExtension = new BuildReportTabPageExtension(() => Module, tabControl1, _buildReportTabCaption.Text); } _buildReportTabPageExtension.FillBuildReport(selectedRevisions.Count == 1 ? revision : null); }
public string GetGitCommit([CanBeNull] Func <string, ObjectId, ObjectId> getFileBlobHash, [CanBeNull] FileStatusItem item, bool isSecondRevision) { if (item is null) { return(null); } var name = (!isSecondRevision && !string.IsNullOrWhiteSpace(item.Item.OldName) ? item.Item.OldName : item.Item.Name) ?.ToPosixPath(); var id = (isSecondRevision ? item.SecondRevision : item.FirstRevision)?.ObjectId; if (string.IsNullOrWhiteSpace(name) || id is null) { return(null); } if (id == ObjectId.WorkTreeId) { // A file system file return(name); } if (id == ObjectId.IndexId) { // Must be referenced by blob - no commit. File name presented in difftool will be blob or the other file return(item.Item.TreeGuid is not null ? item.Item.TreeGuid.ToString() : getFileBlobHash?.Invoke(name, id)?.ToString()); } // commit:path return($"{id}:{name}"); }
public bool ShouldEnableSecondItemDiff(FileStatusItem item) => ShouldEnableSecondItemDiff(item, isSecondRevision: false) || ShouldEnableSecondItemDiff(item, isSecondRevision: true);
public bool ShouldEnableFirstItemDiff(FileStatusItem item, bool isSecondRevision) { // First item must be a git reference existing in the revision, i.e. other than work tree return(ShouldEnableSecondItemDiff(item, isSecondRevision: isSecondRevision) && (isSecondRevision ? item.SecondRevision : item.FirstRevision)?.ObjectId != ObjectId.WorkTreeId); }
// Executes GET requsts for all files private static ActionResult GetHandler(IFileHandler handler) { IFileStatus status = new FileStatus(); using (FilesModel db = new FilesModel()) { foreach (var row in db.Files) { string url = handler.Context.Request.Url.OriginalString + "?fileName=" + row.Id.ToString(); IFileStatusItem file = new FileStatusItem() { ContentType = row.Type, DeleteType = "DELETE", FileName = row.Name, FileSize = row.Size, OriginalName = row.Original, Progress = "100", Success = true, ThumbnailUrl = row.Preview, // Set an identifier for GET and DELETE requests DeleteUrl = url, FileUrl = url }; status.Files.Add(file); } } handler.FileStatus = status; // Create client plugin specific result and return an ActionResult IBackloadResult result = handler.Services.Core.CreatePluginResult(); return ResultCreator.Create((IFileStatusResult)result); }