Maslow
Maslow

Reputation: 18746

how do I determine what items are included pending check-ins programatically?

I can query PendingSets and candidate PendingSets, and there appears to be no way to tell between included pending changes, and excluded pending changes.

I have one file included in the included changes to check in via Visual Studio Team Explorer.

Using Tfs dlls to query I get that there are 112 pending, and 145 CandidatePending:

var tfsServer = Macros.TfsModule.GetTfsServerFromEnvironment();

var tfs =new Macros.TFS(tfsServer,"Development", null);
var vcs= tfs.Tfs.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>();
var searchBase=vcs.GetItem("$/");
//vcs.Dump();
var workspace = vcs.GetWorkspace(Environment.ExpandEnvironmentVariables("%devroot%"));

// vcs.QueryWorkspaces(null,null,null).Dump("workspaces");
var itemSpecs = new []{new ItemSpec(searchBase.ServerItem,RecursionType.Full)};

vcs.QueryPendingSets(itemSpecs, workspace.Name, workspace.OwnerName, false, true)
    .Select(ps=>new {Pending=ps.PendingChanges.Select(pc=>new{ pc.LocalOrServerItem,PendingChange=Util.OnDemand("PendingChange",()=> pc)}), ps.CandidatePendingChanges})
    .First()
    .Dump();

workspace.Dump();

The 112 value does line up with included+excluded. The 465 value lines up with the Detected add(s) value.

However I've been completely unable to figure out which changes are currently included. I've tried Tfs dll querying, and EnvDte for hours.

Can I programatically get the list of included changes currently (and even better, change the include/exclude list) ?

Upvotes: 0

Views: 1093

Answers (1)

Munir Husseini
Munir Husseini

Reputation: 489

It seems to me that the functionality you are requesting (getting/modifying the set included and excluded changes) is part of the "Pending Changes" window itself, not part of the TFS API. See this post for an example of how to interact with the "Pending Changes" window (partially via reflection). Maybe that is a considerable starting point for further exploration.

EDIT

I just explored this further and came up with the following code. It primarily utilizes the interface Microsoft.TeamFoundation.VersionControl.Controls.PendingChanges.IPendingChangesDataProvider, which is internal to the assembly Microsoft.TeamFoundation.VersionControl.Controls.dll.

using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.TeamFoundation.Controls;
using Microsoft.TeamFoundation.Controls.WPF.TeamExplorer;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace PrettyFlyForANamespace
{
    public class PendingChangesInclusion
    {
        private readonly Action<IList<PendingChange>> _includeChanges;
        private readonly Action<IList<PendingChange>> _excludeChanges;
        private readonly Func<IList<PendingChange>> _getIncludedChanges;
        private readonly Func<IList<PendingChange>> _getExcludedChanges;

        public IList<PendingChange> IncludedChanges
        {
            get
            {
                return _getIncludedChanges();
            }
        }

        public IList<PendingChange> ExcludedChanges
        {
            get
            {
                return _getExcludedChanges();
            }
        }

        public PendingChangesInclusion(ITeamExplorer teamExplorer)
        {
            var pendingChangesPage = (TeamExplorerPageBase)teamExplorer.NavigateToPage(new Guid(TeamExplorerPageIds.PendingChanges), null);

            var model = pendingChangesPage.Model;
            var p = model.GetType().GetProperty("DataProvider", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

            var dataProvider = p.GetValue(model); // IPendingChangesDataProvider is internal;
            var dataProviderType = dataProvider.GetType();

            p = dataProviderType.GetProperty("IncludedChanges", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            var m = p.GetMethod;
            _getIncludedChanges = (Func<IList<PendingChange>>)m.CreateDelegate(typeof(Func<IList<PendingChange>>), dataProvider);

            p = dataProviderType.GetProperty("ExcludedChanges", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            m = p.GetMethod;
            _getExcludedChanges = (Func<IList<PendingChange>>)m.CreateDelegate(typeof(Func<IList<PendingChange>>), dataProvider);

            m = dataProviderType.GetMethod("IncludeChanges", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            _includeChanges = (Action<IList<PendingChange>>)m.CreateDelegate(typeof(Action<IList<PendingChange>>), dataProvider);

            m = dataProviderType.GetMethod("ExcludeChanges", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
            _excludeChanges = (Action<IList<PendingChange>>)m.CreateDelegate(typeof(Action<IList<PendingChange>>), dataProvider);
        }

        public void IncludeChanges(IList<PendingChange> changes)
        {
            _includeChanges(changes);
        }

        public void ExcludeChanges(IList<PendingChange> changes)
        {
            _excludeChanges(changes);
        }
    }
}

If you want to call the code above from within a VS Package object, you can use the following code:

var teamExplorer = (ITeamExplorer)GetService(typeof(ITeamExplorer));
var psi = new PendingChangesInclusion(teamExplorer);

// To see if this works, include all excluded pending changes.
psi.IncludeChanges(psi.ExcludedChanges);

You will need to include the following assemblies using the "browse" dialog:

  • C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll
  • C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v4.5\Microsoft.TeamFoundation.Controls.dll
  • C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.VersionControl.Client.dll

Upvotes: 2

Related Questions