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);
        }
Beispiel #3
0
            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);
            }
Beispiel #4
0
        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);
        }