Bulk fetch changeset files.
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user