Bulk fetch changeset files.

This commit is contained in:
Matt Burke
2012-06-06 16:08:37 -04:00
parent 8aa4b2cefb
commit 38f9ca2844
7 changed files with 98 additions and 5 deletions
+8
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Sep.Git.Tfs.Core.TfsInterop;
@@ -455,6 +456,13 @@ namespace Sep.Git.Tfs.VsCommon
_workspace.Get(new ChangesetVersionSpec(changeset), GetOptions.Overwrite | GetOptions.GetAll);
}
public void GetSpecificVersion(IChangeset changeset)
{
var requests = from change in changeset.Changes
select new GetRequest(new ItemSpec(change.Item.ServerItem, RecursionType.None, change.Item.DeletionId), changeset.ChangesetId);
_workspace.Get(requests.ToArray(), GetOptions.Overwrite);
}
public string OwnerName
{
get { return _workspace.OwnerName; }
+14 -4
View File
@@ -296,11 +296,21 @@ namespace Sep.Git.Tfs.Core
private LogEntry Apply(string lastCommit, ITfsChangeset changeset)
{
LogEntry result = null;
WithTemporaryIndex(() => Tfs.WithWorkspace(WorkingDirectory, this, changeset.Summary, workspace =>
if (globals.Experimental)
{
GitIndexInfo.Do(Repository, index => result = changeset.Apply(lastCommit, index/*, workspace*/));
result.Tree = Repository.CommandOneline("write-tree");
}));
WithTemporaryIndex(() => Tfs.WithWorkspace(WorkingDirectory, this, changeset.Summary, workspace =>
{
GitIndexInfo.Do(Repository, index => result = changeset.Apply(lastCommit, index, workspace));
result.Tree = Repository.CommandOneline("write-tree");
}));
}
else
{
WithTemporaryIndex(() =>
GitIndexInfo.Do(Repository, index => result = changeset.Apply(lastCommit, index)));
WithTemporaryIndex(() =>
result.Tree = Repository.CommandOneline("write-tree"));
}
if(!String.IsNullOrEmpty(lastCommit)) result.CommitParents.Add(lastCommit);
return result;
}
+1
View File
@@ -5,6 +5,7 @@ namespace Sep.Git.Tfs.Core
public interface ITfsChangeset
{
TfsChangesetInfo Summary { get; }
LogEntry Apply(string lastCommit, GitIndexInfo index, ITfsWorkspace workspace);
LogEntry Apply(string lastCommit, GitIndexInfo index);
LogEntry CopyTree(GitIndexInfo index, ITfsWorkspace workspace);
IEnumerable<TfsTreeEntry> GetTree();
+9 -1
View File
@@ -1,4 +1,5 @@
using System;
using Sep.Git.Tfs.Core.TfsInterop;
namespace Sep.Git.Tfs.Core
{
@@ -12,8 +13,15 @@ namespace Sep.Git.Tfs.Core
/// Evaluates check-in policies and checks in all pending changes.
/// </summary>
long Checkin();
/// <summary>
/// Populates the workspace with a snapshot, as of the given changeset.
/// </summary>
void Get(int changesetId);
/// <summary>
/// Gets the files changed in a given changeset.
/// </summary>
void Get(IChangeset changeset);
string GetLocalPath(string path);
void Add(string path);
void Edit(string path);
+60
View File
@@ -22,6 +22,17 @@ namespace Sep.Git.Tfs.Core
_stdout = stdout;
}
public LogEntry Apply(string lastCommit, GitIndexInfo index, ITfsWorkspace workspace)
{
var initialTree = Summary.Remote.Repository.GetObjects(lastCommit);
workspace.Get(_changeset);
foreach (var change in Sort(_changeset.Changes))
{
Apply(change, index, workspace, initialTree);
}
return MakeNewLogEntry();
}
public LogEntry Apply(string lastCommit, GitIndexInfo index)
{
var initialTree = Summary.Remote.Repository.GetObjects(lastCommit);
@@ -56,6 +67,30 @@ namespace Sep.Git.Tfs.Core
}
}
private void Apply(IChange change, GitIndexInfo index, ITfsWorkspace workspace, IDictionary<string, GitObject> initialTree)
{
// If you make updates to a dir in TF, the changeset includes changes for all the children also,
// and git doesn't really care if you add or delete empty dirs.
if (change.Item.ItemType == TfsItemType.File)
{
var pathInGitRepo = GetPathInGitRepo(change.Item.ServerItem, initialTree);
if (pathInGitRepo == null || Summary.Remote.ShouldSkip(pathInGitRepo))
return;
if (change.ChangeType.IncludesOneOf(TfsChangeType.Rename))
{
Rename(change, pathInGitRepo, index, workspace, initialTree);
}
else if (change.ChangeType.IncludesOneOf(TfsChangeType.Delete))
{
Delete(pathInGitRepo, index, initialTree);
}
else
{
Update(change, pathInGitRepo, index, workspace, initialTree);
}
}
}
private string GetPathInGitRepo(string tfsPath, IDictionary<string, GitObject> initialTree)
{
var pathInGitRepo = Summary.Remote.GetPathInGitRepo(tfsPath);
@@ -77,6 +112,19 @@ namespace Sep.Git.Tfs.Core
}
}
private void Rename(IChange change, string pathInGitRepo, GitIndexInfo index, ITfsWorkspace workspace, IDictionary<string, GitObject> initialTree)
{
var oldPath = GetPathInGitRepo(GetPathBeforeRename(change.Item), initialTree);
if (oldPath != null)
{
Delete(oldPath, index, initialTree);
}
if (!change.ChangeType.IncludesOneOf(TfsChangeType.Delete))
{
Update(change, pathInGitRepo, index, workspace, initialTree);
}
}
private IEnumerable<IChange> Sort(IEnumerable<IChange> changes)
{
return changes.OrderBy(change => Rank(change.ChangeType));
@@ -126,6 +174,18 @@ namespace Sep.Git.Tfs.Core
}
}
private void Update(IChange change, string pathInGitRepo, GitIndexInfo index, ITfsWorkspace workspace, IDictionary<string, GitObject> initialTree)
{
if (change.Item.DeletionId == 0)
{
index.Update(
GetMode(change, initialTree, pathInGitRepo),
pathInGitRepo,
workspace.GetLocalPath(pathInGitRepo)
);
}
}
public IEnumerable<TfsTreeEntry> GetTree()
{
var treeInfo = Summary.Remote.Repository.GetObjects();
+1
View File
@@ -14,6 +14,7 @@ namespace Sep.Git.Tfs.Core.TfsInterop
int PendRename(string pathFrom, string pathTo);
void ForceGetFile(string path, int changeset);
void GetSpecificVersion(int changeset);
void GetSpecificVersion(IChangeset changeset);
string OwnerName { get; }
}
}
+5
View File
@@ -158,6 +158,11 @@ namespace Sep.Git.Tfs.Core
_workspace.GetSpecificVersion(changesetId);
}
public void Get(IChangeset changeset)
{
_workspace.GetSpecificVersion(changeset);
}
private IEnumerable<IWorkItemCheckinInfo> GetWorkItemInfos()
{
return GetWorkItemInfosHelper<IWorkItemCheckinInfo>(_tfsHelper.GetWorkItemInfos);