private bool ShouldIncludeInFilter(IVsHierarchyItem hierarchyItem) { ThreadHelper.ThrowIfNotOnUIThread(); if (hierarchyItem == null) { return(false); } if (HierarchyUtilities.IsPhysicalFile(hierarchyItem.HierarchyIdentity) || HierarchyUtilities.IsProject(hierarchyItem.HierarchyIdentity)) { var absoluteFilePath = string.Empty; if (HierarchyUtilities.IsPhysicalFile(hierarchyItem.HierarchyIdentity)) { absoluteFilePath = hierarchyItem.CanonicalName; } else if (HierarchyUtilities.IsProject(hierarchyItem.HierarchyIdentity)) { var vsHierarchy = hierarchyItem.HierarchyIdentity.Hierarchy; vsHierarchy.ParseCanonicalName(hierarchyItem.CanonicalName, out uint itemId); vsHierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out object itemObject); if (itemObject is EnvDTE.Project project) { absoluteFilePath = project.FullName; } } if (!string.IsNullOrEmpty(absoluteFilePath)) { DiffResultItem diffResultItem = this.branchDiffWorker.GetItemFromChangeSet(this.changeSet, absoluteFilePath); if (diffResultItem != null) { // If the physical file in changeSet is under "External Dependencies" folder of a C++ project, always ignore. This file is a link, and already shows up elsewhere. if (HierarchyUtilities.IsPhysicalFile(hierarchyItem.HierarchyIdentity) && IsCPPExternalDependencyFile(hierarchyItem)) { return(false); } // Mark all Project nodes found in changeset, so we only enable "Open Diff With Base" button for these project nodes. if (HierarchyUtilities.IsProject(hierarchyItem.HierarchyIdentity)) { BranchDiffFilterProvider.TagManager.MarkProjAsChanged(hierarchyItem); } // If item renamed in working branch. Tag the old path so we find the Base branch version of file using the Old Path. if (!string.IsNullOrEmpty(diffResultItem.OldAbsoluteFilePath)) { BranchDiffFilterProvider.TagManager.SetOldFilePathOnRenamedItem(hierarchyItem, diffResultItem.OldAbsoluteFilePath); } return(true); } } } return(false); }
/// <summary> /// Finds the file from the given changeset, note that the changeset contains paths of solution items of vs which are always lowercase. /// </summary> /// <param name="gitChangeSet"></param> /// <param name="vsSolutionItemPath"></param> /// <returns>The DiffResultItem from the change set, or null if nothing found.</returns> public DiffResultItem GetFileFromChangeSet(HashSet <DiffResultItem> gitChangeSet, string vsSolutionItemPath) { var searchItemByAbsolutePath = new DiffResultItem { AbsoluteFilePath = vsSolutionItemPath.ToLowerInvariant() }; if (gitChangeSet.TryGetValue(searchItemByAbsolutePath, out DiffResultItem resultItem)) { return(resultItem); } return(null); }
private bool ShouldIncludeInFilter(IVsHierarchyItem hierarchyItem) { ThreadHelper.ThrowIfNotOnUIThread(); if (hierarchyItem == null) { return(false); } if (HierarchyUtilities.IsPhysicalFile(hierarchyItem.HierarchyIdentity) || HierarchyUtilities.IsProject(hierarchyItem.HierarchyIdentity)) { var absoluteFilePath = string.Empty; if (HierarchyUtilities.IsPhysicalFile(hierarchyItem.HierarchyIdentity)) { absoluteFilePath = hierarchyItem.CanonicalName; } else if (HierarchyUtilities.IsProject(hierarchyItem.HierarchyIdentity)) { hierarchyItem.HierarchyIdentity.Hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out var prjObject); if (prjObject is EnvDTE.Project project) { absoluteFilePath = project.FullName; } } if (!string.IsNullOrEmpty(absoluteFilePath)) { DiffResultItem diffResultItem = this.branchDiffWorker.GetItemFromChangeSet(this.changeSet, hierarchyItem.CanonicalName); if (diffResultItem != null) { // Tag the old path so we find the Base branch version of file using the Old Path (for files renamed in the working branch) if (!string.IsNullOrEmpty(diffResultItem.OldAbsoluteFilePath)) { BranchDiffFilterProvider.TagManager.SetOldFilePathOnRenamedItem( hierarchyItem.HierarchyIdentity.Hierarchy, hierarchyItem.CanonicalName, diffResultItem.OldAbsoluteFilePath); } return(true); } } } return(false); }
public HashSet <DiffResultItem> GetDiffedChangeSet(IGitRepository gitRepo, DiffBranchPair diffBranchPair) { var compareOptions = new CompareOptions { Algorithm = DiffAlgorithm.Minimal, IncludeUnmodified = false, }; // NB! Hard to make this "Diff" property and following code unit-testable... var branchDiffResult = gitRepo.Diff.Compare <TreeChanges>( diffBranchPair.BranchToDiffAgainst.Tip.Tree, diffBranchPair.WorkingBranch.Tip.Tree, compareOptions); // Can not include delete items, no way to show it in Solution Explorer // No special handling to Conflicts/Copied change kinds. var modifiedTreeChanges = branchDiffResult.Modified; var addedTreeChanges = branchDiffResult.Added; var renamedTreeChanges = branchDiffResult.Renamed; var allChanges = modifiedTreeChanges .Concat(addedTreeChanges) .Concat(renamedTreeChanges); HashSet <DiffResultItem> changedPathsSet = new HashSet <DiffResultItem>(); foreach (var treeEntryChange in allChanges) { // Issue with LibGit2Sharp: Paths returned are *-nix format, not windows directory format. var itemPathWithCorrectSeparator = treeEntryChange.Path.Replace("/", Constants.DirectorySeperator); var repoPathWithCorrectSeperator = gitRepo.WorkingDirectory.Replace("/", Constants.DirectorySeperator); var diffedObject = new DiffResultItem { AbsoluteFilePath = repoPathWithCorrectSeperator.ToLowerInvariant() + itemPathWithCorrectSeparator.ToLowerInvariant(), OldAbsoluteFilePath = treeEntryChange.Status == ChangeKind.Renamed ? treeEntryChange.OldPath.Replace("/", Constants.DirectorySeperator) : string.Empty, }; changedPathsSet.Add(diffedObject); } return(changedPathsSet); }