首页 > 解决方案 > Visual Studio 扩展 - 获取对 Git 历史记录中当前选定项目的引用

问题描述

由于此处提供的帮助,我设法将自定义按钮添加到 Git 历史上下文菜单中。

我继续在同一个分机上工作,但又被卡住了。单击我添加到上下文菜单的按钮后,我需要获取对单击时选择的提交的引用。这个想法是,然后我需要获取与该提交相关的代码更改。

在此处输入图像描述

我已经获得了对 ActiveWindow 的引用,该 ActiveWindow 的标题为“History - master”。这让我相信我很接近。但是,ActiveWindow.Selection 为空。所以我不确定下一步去哪里获得选定的提交。

这就是我用来获取 ActiveWindow 属性的方法。

EnvDTE80.DTE2 dte = ServiceProvider.GetService(typeof(DTE)) as EnvDTE80.DTE2;

有人知道如何获取对所选提交的引用吗?然后使用它来获取有关提交的信息,包括更改的文件?

我的问题看起来与这个类似,但针对的是 Git 而不是 TFS。

在此先感谢您的帮助!

标签: visual-studiovisual-studio-extensionsteam-explorergit-history

解决方案


花了很长时间,但我终于设法完成了选定的提交。它涉及反射,因为 git 扩展中使用的许多类型都是内部的。必须有更好的方法来做到这一点。

我能够检索的 IGitCommit 没有填充提交的更改。希望获得作为提交一部分的更改不是那么具有挑战性。

    private IGitCommit GetSelectedCommit()
    {
        ThreadHelper.ThrowIfNotOnUIThread();
        EnvDTE80.DTE2 dte = ServiceProvider.GetService(typeof(DTE)) as EnvDTE80.DTE2;
        // GUID found via dte.ActiveWindow.ObjectKind
        Guid gitHistoryWindowGuid = new Guid("116D2292-E37D-41CD-A077-EBACAC4C8CC4");
        IVsUIShell vsUIShell = (IVsUIShell)Package.GetGlobalService(typeof(SVsUIShell));
        int toolWindowReturn = vsUIShell.FindToolWindow((uint)__VSFINDTOOLWIN.FTW_fFrameOnly, ref gitHistoryWindowGuid, out IVsWindowFrame vsWindowFrame);
        WindowFrame windowFrame = (WindowFrame)vsWindowFrame;
        ToolWindowView toolWindowView = (ToolWindowView)windowFrame.FrameView;
        // panel is of innaccessible type Microsoft.VisualStudio.Platform.WindowManagement.WindowFrame.ContentHostingPanel
        // so use base System.Windows.Controls.Grid
        Grid contentHostingPanel = (Grid)toolWindowView.Content;
        // Type Microsoft.VisualStudio.Platform.WindowManagement.Controls.GenericPaneContentPresenter is internal
        // so use base ContentPresenter
        ContentPresenter genericPaneContentPresenter = contentHostingPanel.Children[1] as ContentPresenter;
        // Microsoft.VisualStudio.TeamFoundation.ToolWindowBase.ToolWindowBaseProxy is innaccessible
        // so use base ContentPresenter
        ContentPresenter toolWindowBaseProxy = (ContentPresenter)genericPaneContentPresenter.Content;
        // Is of type Microsoft.TeamFoundation.Git.Controls.History.HistoryView, 
        // but this class is defined as internal so using base UserControl.
        UserControl historyView = (UserControl)toolWindowBaseProxy.Content;
        // Is of type Microsoft.TeamFoundation.Git.Controls.History.HistoryViewModel, 
        // but this class is defined as internal so using base Microsoft.TeamFoundation.MVVM.ViewModelBase.
        ViewModelBase historyViewModel = (ViewModelBase)historyView.DataContext;
        // Use reflection to get at properties of internal type HistoryViewModel and ObservableCollection<GitHistoryItem>
        object gitHistoryItem = ((IList)historyViewModel.GetType().GetProperty("SelectedItems").GetValue(historyViewModel, null))[0];
        IGitCommit gitCommit = (IGitCommit)gitHistoryItem.GetType().GetProperty("Commit").GetValue(gitHistoryItem, null);
        return gitCommit;
    }

推荐阅读