Skip to content

Commit

Permalink
TfsHelper can now map multiple paths in a workspace, remotes now map …
Browse files Browse the repository at this point in the history
…all paths for all subtrees

Signed-off-by: Gordon Burgett <gordon.burgett@gmail.com>
  • Loading branch information
gburgett committed Apr 9, 2013
1 parent c8300df commit fc1365d
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 19 deletions.
28 changes: 25 additions & 3 deletions GitTfs.VsCommon/TfsHelper.Common.cs
Expand Up @@ -195,10 +195,31 @@ private ITfsChangeset BuildTfsChangeset(Changeset changeset, GitTfsRemote remote
return tfsChangeset;
}

public void WithWorkspace(string localDirectory, IGitTfsRemote remote, IEnumerable<Tuple<string, string>> mappings, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action)
{
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)
.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();
}
}

public void WithWorkspace(string localDirectory, IGitTfsRemote remote, TfsChangesetInfo versionToFetch, Action<ITfsWorkspace> action)
{
Trace.WriteLine("Setting up a TFS workspace at " + localDirectory);
var workspace = GetWorkspace(localDirectory, remote.TfsRepositoryPath);
var workspace = GetWorkspace(new WorkingFolder(localDirectory, remote.TfsRepositoryPath));
try
{
var tfsWorkspace = _container.With("localDirectory").EqualTo(localDirectory)
Expand All @@ -215,12 +236,13 @@ public void WithWorkspace(string localDirectory, IGitTfsRemote remote, TfsChange
}
}

private Workspace GetWorkspace(string localDirectory, string repositoryPath)
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)
{
Expand Down
52 changes: 37 additions & 15 deletions GitTfs/Commands/Subtree.cs
Expand Up @@ -90,26 +90,48 @@ public int DoAdd(string tfsUrl, string tfsRepositoryPath)

var fetch = Squash ? this._quickFetch : this._fetch;


//create a remote for the new subtree
string remoteId = "subtree/" + Prefix;
IGitTfsRemote remote;
if (_globals.Repository.HasRemote(remoteId))
IGitTfsRemote remote = _globals.Repository.CreateTfsRemote(new RemoteInfo
{
remote = _globals.Repository.ReadTfsRemote(remoteId);
}
else
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)
{
//create a remote for the new subtree
remote = _globals.Repository.CreateTfsRemote(new RemoteInfo
try
{
Id = remoteId,
Url = tfsUrl,
Repository = tfsRepositoryPath,
RemoteOptions = _remoteOptions,
});
_stdout.WriteLine("-> new remote " + remote.Id);
}

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)
Expand Down
14 changes: 14 additions & 0 deletions GitTfs/Core/GitRepository.cs
Expand Up @@ -475,5 +475,19 @@ public void Reset(string sha, ResetOptions resetOptions)
{
_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));
}
}
}
11 changes: 10 additions & 1 deletion GitTfs/Core/GitTfsRemote.cs
Expand Up @@ -546,7 +546,16 @@ private void WithWorkspace(TfsChangesetInfo parentChangeset, Action<ITfsWorkspac
// 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)
Expand Down
5 changes: 5 additions & 0 deletions GitTfs/Core/IGitRepository.cs
Expand Up @@ -38,5 +38,10 @@ public interface IGitRepository : IGitHelpers
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 changes: 11 additions & 0 deletions GitTfs/Core/TfsInterop/ITfsHelper.cs
Expand Up @@ -33,5 +33,16 @@ public interface ITfsHelper
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);
}
}

0 comments on commit fc1365d

Please sign in to comment.