TfsHelper can now map multiple paths in a workspace, remotes now map all paths for all subtrees

Signed-off-by: Gordon Burgett <gordon.burgett@gmail.com>
This commit is contained in:
Gordon Burgett
2013-04-09 09:01:14 -05:00
parent c8300dfa13
commit fc1365d8fa
6 changed files with 107 additions and 24 deletions
+27 -5
View File
@@ -195,10 +195,11 @@ namespace Sep.Git.Tfs.VsCommon
return tfsChangeset;
}
public void WithWorkspace(string localDirectory, IGitTfsRemote remote, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action)
public void WithWorkspace(string localDirectory, IGitTfsRemote remote, IEnumerable<Tuple<string, string>> mappings, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action)
{
Trace.WriteLine("Setting up a TFS workspace at " + localDirectory);
var workspace = GetWorkspace(localDirectory, remote.TfsRepositoryPath);
Trace.WriteLine("Setting up a TFS workspace for multiple remotes");
var folders = mappings.Select(x => new WorkingFolder(Path.Combine(localDirectory, x.Item1), x.Item2)).ToArray();
var workspace = GetWorkspace(folders);
try
{
var tfsWorkspace = _container.With("localDirectory").EqualTo(localDirectory)
@@ -215,12 +216,33 @@ namespace Sep.Git.Tfs.VsCommon
}
}
private Workspace GetWorkspace(string localDirectory, string repositoryPath)
public void WithWorkspace(string localDirectory, IGitTfsRemote remote, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action)
{
Trace.WriteLine("Setting up a TFS workspace at " + localDirectory);
var workspace = GetWorkspace(new WorkingFolder(localDirectory, remote.TfsRepositoryPath));
try
{
var tfsWorkspace = _container.With("localDirectory").EqualTo(localDirectory)
.With("remote").EqualTo(remote)
.With("contextVersion").EqualTo(versionToFetch)
.With("workspace").EqualTo(_bridge.Wrap<WrapperForWorkspace, Workspace>(workspace))
.With("tfsHelper").EqualTo(this)
.GetInstance<TfsWorkspace>();
action(tfsWorkspace);
}
finally
{
workspace.Delete();
}
}
private Workspace GetWorkspace(params WorkingFolder[] folders)
{
var workspace = VersionControl.CreateWorkspace(GenerateWorkspaceName());
try
{
workspace.CreateMapping(new WorkingFolder(repositoryPath, localDirectory));
foreach(WorkingFolder folder in folders)
workspace.CreateMapping(folder);
}
catch (MappingConflictException e)
{
+40 -18
View File
@@ -90,26 +90,48 @@ namespace Sep.Git.Tfs.Commands
var fetch = Squash ? this._quickFetch : this._fetch;
string remoteId = "subtree/" + Prefix;
IGitTfsRemote remote;
if (_globals.Repository.HasRemote(remoteId))
{
remote = _globals.Repository.ReadTfsRemote(remoteId);
}
else
{
//create a remote for the new subtree
remote = _globals.Repository.CreateTfsRemote(new RemoteInfo
{
Id = remoteId,
Url = tfsUrl,
Repository = tfsRepositoryPath,
RemoteOptions = _remoteOptions,
});
_stdout.WriteLine("-> new remote " + remote.Id);
}
//create a remote for the new subtree
string remoteId = "subtree/" + Prefix;
IGitTfsRemote remote = _globals.Repository.CreateTfsRemote(new RemoteInfo
{
Id = remoteId,
Url = tfsUrl,
Repository = tfsRepositoryPath,
RemoteOptions = _remoteOptions,
});
_stdout.WriteLine("-> new remote " + remote.Id);
var tfsUri = new Uri(tfsUrl);
IGitTfsRemote owner = _globals.Repository.ReadAllTfsRemotes().FirstOrDefault(x => !x.Id.StartsWith("subtree/") && tfsUri.Equals(x.TfsUrl));
if (owner == null)
{
try
{
owner = _globals.Repository.CreateTfsRemote(new RemoteInfo
{
Id = "origin",
Url = tfsUrl,
Repository = "",
RemoteOptions = _remoteOptions
});
}
catch (Exception)
{
//need to clean up our subtree
try
{
_globals.Repository.DeleteTfsRemote(remote);
}
catch
{
}
throw;
}
}
int result = fetch.Run(remote.Id);
if (result == GitTfsExitCodes.OK)
+14
View File
@@ -475,5 +475,19 @@ namespace Sep.Git.Tfs.Core
{
_repository.Reset(resetOptions, sha);
}
/// <summary>
/// Gets all configured "subtree" remotes which point to the same Tfs URL as the given remote.
/// If the given remote is itself a subtree, an empty enumerable is returned.
/// </summary>
public IEnumerable<IGitTfsRemote> GetSubtrees(IGitTfsRemote owner)
{
//a subtree remote cannot have subtrees itself.
if (owner.Id.StartsWith("subtree/"))
return Enumerable.Empty<IGitTfsRemote>();
var uri = new Uri(owner.TfsUrl);
return ReadAllTfsRemotes().Where(x => x.Id.StartsWith("subtree/") && uri.Equals(x.TfsUrl));
}
}
}
+10 -1
View File
@@ -546,7 +546,16 @@ namespace Sep.Git.Tfs.Core
// with it.
Tfs.CleanupWorkspaces(DefaultWorkingDirectory);
Tfs.WithWorkspace(WorkingDirectory, this, parentChangeset, action);
//are there any subtrees?
var subtrees = globals.Repository.GetSubtrees(this);
if (subtrees.Any())
{
Tfs.WithWorkspace(WorkingDirectory, this, subtrees.Select(x => new Tuple<string, string>(x.Id.Substring("subtree/".Length), x.TfsRepositoryPath)), parentChangeset, action);
}
else
{
Tfs.WithWorkspace(WorkingDirectory, this, parentChangeset, action);
}
}
private long Checkin(string head, string parent, ITfsWorkspace workspace, CheckinOptions options)
+5
View File
@@ -38,5 +38,10 @@ namespace Sep.Git.Tfs.Core
void CreateNote(string sha, string content, string owner, string emailOwner, DateTime creationDate);
void MoveRemote(string oldRemoteName, string newRemoteName);
void Reset(string sha, ResetOptions resetOptions);
/// <summary>
/// Gets all configured "subtree" remotes which point to the same Tfs URL as the given remote.
/// If the given remote is itself a subtree, an empty enumerable is returned.
/// </summary>
IEnumerable<IGitTfsRemote> GetSubtrees(IGitTfsRemote owner);
}
}
+11
View File
@@ -33,5 +33,16 @@ namespace Sep.Git.Tfs.Core.TfsInterop
IEnumerable<IBranchObject> GetBranches();
void EnsureAuthenticated();
void CreateBranch(string sourcePath, string targetPath, int changesetId, string comment = null);
/// <summary>
/// Creates and maps a workspace for the given remote with the given local -> server directory mappings, at the given Tfs version,
/// and then performs the action.
/// </summary>
/// <param name="localDirectory">The local base directory containing all the mappings</param>
/// <param name="remote">The owning remote</param>
/// <param name="mappings">The workspace mappings to create. Item1 is the relative path from the localDirectory, and Item2 is the TfsRepositoryPath</param>
/// <param name="versionToFetch">The TFS version to fetch from the server</param>
/// <param name="action">The action to perform</param>
void WithWorkspace(string localDirectory, IGitTfsRemote remote, IEnumerable<Tuple<string, string>> mappings, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action);
}
}