Fix line endings.

This commit is contained in:
Matt Burke
2011-07-14 00:03:10 -04:00
parent 49fc1b03cd
commit 50a7bfa2f0
8 changed files with 524 additions and 524 deletions
+80 -80
View File
@@ -1,80 +1,80 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Sep.Git.Tfs.Core.TfsInterop;
using Sep.Git.Tfs.Util;
using Sep.Git.Tfs.VsCommon;
using StructureMap;
namespace Sep.Git.Tfs.Vs2008
{
public class TfsHelper : TfsHelperBase
{
private TeamFoundationServer _server;
public TfsHelper(TextWriter stdout, TfsApiBridge bridge, IContainer container) : base(stdout, bridge, container)
{
}
public override string TfsClientLibraryVersion
{
get { return "" + typeof (TeamFoundationServer).Assembly.GetName().Version + " (MS)"; }
}
public override void EnsureAuthenticated()
{
if (string.IsNullOrEmpty(Url))
{
_server = null;
}
else
{
_server = String.IsNullOrEmpty(Username) || String.IsNullOrEmpty(Password)
? new TeamFoundationServer(Url, new NetworkCredential(Username, Password), new UICredentialsProvider())
: new TeamFoundationServer(Url, GetCredential());
_server.EnsureAuthenticated();
}
}
protected override T GetService<T>()
{
return (T) _server.GetService(typeof (T));
}
protected override string GetAuthenticatedUser()
{
return VersionControl.AuthenticatedUser;
}
public override bool CanShowCheckinDialog
{
get { return false; }
}
public override long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable<IWorkItemCheckedInfo> checkedInfos, string checkinComment)
{
throw new NotImplementedException();
}
}
public class ItemDownloadStrategy : IItemDownloadStrategy
{
private readonly TfsApiBridge _bridge;
public ItemDownloadStrategy(TfsApiBridge bridge)
{
_bridge = bridge;
}
public Stream DownloadFile(IItem item)
{
var tempfile = new TemporaryFile();
_bridge.Unwrap<Item>(item).DownloadFile(tempfile);
return tempfile.ToStream();
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Sep.Git.Tfs.Core.TfsInterop;
using Sep.Git.Tfs.Util;
using Sep.Git.Tfs.VsCommon;
using StructureMap;
namespace Sep.Git.Tfs.Vs2008
{
public class TfsHelper : TfsHelperBase
{
private TeamFoundationServer _server;
public TfsHelper(TextWriter stdout, TfsApiBridge bridge, IContainer container) : base(stdout, bridge, container)
{
}
public override string TfsClientLibraryVersion
{
get { return "" + typeof (TeamFoundationServer).Assembly.GetName().Version + " (MS)"; }
}
public override void EnsureAuthenticated()
{
if (string.IsNullOrEmpty(Url))
{
_server = null;
}
else
{
_server = String.IsNullOrEmpty(Username) || String.IsNullOrEmpty(Password)
? new TeamFoundationServer(Url, new NetworkCredential(Username, Password), new UICredentialsProvider())
: new TeamFoundationServer(Url, GetCredential());
_server.EnsureAuthenticated();
}
}
protected override T GetService<T>()
{
return (T) _server.GetService(typeof (T));
}
protected override string GetAuthenticatedUser()
{
return VersionControl.AuthenticatedUser;
}
public override bool CanShowCheckinDialog
{
get { return false; }
}
public override long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable<IWorkItemCheckedInfo> checkedInfos, string checkinComment)
{
throw new NotImplementedException();
}
}
public class ItemDownloadStrategy : IItemDownloadStrategy
{
private readonly TfsApiBridge _bridge;
public ItemDownloadStrategy(TfsApiBridge bridge)
{
_bridge = bridge;
}
public Stream DownloadFile(IItem item)
{
var tempfile = new TemporaryFile();
_bridge.Unwrap<Item>(item).DownloadFile(tempfile);
return tempfile.ToStream();
}
}
}
+25 -25
View File
@@ -2,8 +2,8 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Linq;
using System.Net;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
@@ -16,7 +16,7 @@ namespace Sep.Git.Tfs.VsCommon
{
public abstract class TfsHelperBase : ITfsHelper
{
private readonly TextWriter _stdout;
private readonly TextWriter _stdout;
private readonly TfsApiBridge _bridge;
private readonly IContainer _container;
@@ -27,14 +27,14 @@ namespace Sep.Git.Tfs.VsCommon
_container = container;
}
public abstract string TfsClientLibraryVersion { get; }
public string Url { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public abstract string TfsClientLibraryVersion { get; }
public string Url { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public abstract void EnsureAuthenticated();
private string[] _legacyUrls;
@@ -44,20 +44,20 @@ namespace Sep.Git.Tfs.VsCommon
{
get { return _legacyUrls ?? (_legacyUrls = new string[0]); }
set { _legacyUrls = value; }
}
protected NetworkCredential GetCredential()
{
var idx = Username.IndexOf('\\');
if (idx >= 0)
{
string domain = Username.Substring(0, idx);
string login = Username.Substring(idx + 1);
return new NetworkCredential(login, Password, domain);
}
return new NetworkCredential(Username, Password);
}
}
protected NetworkCredential GetCredential()
{
var idx = Username.IndexOf('\\');
if (idx >= 0)
{
string domain = Username.Substring(0, idx);
string login = Username.Substring(idx + 1);
return new NetworkCredential(login, Password, domain);
}
return new NetworkCredential(Username, Password);
}
protected abstract T GetService<T>();
protected VersionControlServer VersionControl
+4 -4
View File
@@ -13,14 +13,14 @@ namespace Sep.Git.Tfs.Commands
[RequiresValidGitRepository]
[Description("bootstrap [parent-commit]")]
public class Bootstrap : GitTfsCommand
{
private readonly RemoteOptions _remoteOptions;
{
private readonly RemoteOptions _remoteOptions;
private readonly Globals _globals;
private readonly TextWriter _stdout;
public Bootstrap(RemoteOptions remoteOptions, Globals globals, TextWriter stdout)
{
_remoteOptions = remoteOptions;
{
_remoteOptions = remoteOptions;
_globals = globals;
_stdout = stdout;
}
+7 -7
View File
@@ -194,13 +194,13 @@ namespace Sep.Git.Tfs.Core
public void UpdateRef(string commitHash, long changesetId)
{
throw new NotImplementedException();
}
public void EnsureTfsAuthenticated()
{
throw new NotImplementedException();
}
}
public void EnsureTfsAuthenticated()
{
throw new NotImplementedException();
}
#endregion
}
}
+400 -400
View File
@@ -1,400 +1,400 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using GitSharp.Core;
using Sep.Git.Tfs.Commands;
using StructureMap;
using FileMode = GitSharp.Core.FileMode;
namespace Sep.Git.Tfs.Core
{
public class GitRepository : GitHelpers, IGitRepository
{
private readonly IContainer _container;
private readonly Globals _globals;
private static readonly Regex configLineRegex = new Regex("^tfs-remote\\.(?<id>[^.]+)\\.(?<key>[^.=]+)=(?<value>.*)$");
private IDictionary<string, IGitTfsRemote> _cachedRemotes;
private Repository _repository;
public GitRepository(TextWriter stdout, string gitDir, IContainer container, Globals globals)
: base(stdout, container)
{
_container = container;
_globals = globals;
GitDir = gitDir;
_repository = new Repository(new DirectoryInfo(gitDir));
}
private string GitDir { get; set; }
public string WorkingCopyPath { get; set; }
public string WorkingCopySubdir { get; set; }
protected override Process Start(string[] command, Action<ProcessStartInfo> initialize)
{
return base.Start(command, initialize.And(SetUpPaths));
}
private void SetUpPaths(ProcessStartInfo gitCommand)
{
if (GitDir != null)
gitCommand.EnvironmentVariables["GIT_DIR"] = GitDir;
if (WorkingCopyPath != null)
gitCommand.WorkingDirectory = WorkingCopyPath;
if (WorkingCopySubdir != null)
gitCommand.WorkingDirectory = Path.Combine(gitCommand.WorkingDirectory, WorkingCopySubdir);
}
public IEnumerable<IGitTfsRemote> ReadAllTfsRemotes()
{
return GetTfsRemotes().Values;
}
public IGitTfsRemote ReadTfsRemote(string remoteId)
{
if (!HasRemote(remoteId))
throw new GitTfsException("Unable to locate git-tfs remote with id = " + remoteId)
.WithRecommendation("Try using `git tfs bootstrap` to auto-init TFS remotes.");
return GetTfsRemotes()[remoteId];
}
private IGitTfsRemote ReadTfsRemote(string tfsUrl, string tfsRepositoryPath, bool includeStubRemotes)
{
var allRemotes = GetTfsRemotes();
var matchingRemotes =
allRemotes.Values.Where(
remote => remote.Tfs.MatchesUrl(tfsUrl) && remote.TfsRepositoryPath == tfsRepositoryPath);
switch (matchingRemotes.Count())
{
case 0:
if (!includeStubRemotes)
throw new GitTfsException("Unable to locate a remote for <" + tfsUrl + ">" + tfsRepositoryPath)
.WithRecommendation("Try using `git tfs bootstrap` to auto-init TFS remotes.")
.WithRecommendation("Try setting a legacy-url for an existing remote.");
return new DerivedGitTfsRemote(tfsUrl, tfsRepositoryPath);
case 1:
return matchingRemotes.First();
default:
Trace.WriteLine("More than one remote matched!");
goto case 1;
}
}
private IDictionary<string, IGitTfsRemote> GetTfsRemotes()
{
return _cachedRemotes ?? (_cachedRemotes = ReadTfsRemotes());
}
private IDictionary<string, IGitTfsRemote> ReadTfsRemotes()
{
var remotes = new Dictionary<string, IGitTfsRemote>();
CommandOutputPipe(stdout => ParseRemoteConfig(stdout, remotes), "config", "-l");
return remotes;
}
public bool HasRemote(string remoteId)
{
return GetTfsRemotes().ContainsKey(remoteId);
}
public void CreateTfsRemote(string remoteId, TfsChangesetInfo tfsHead, RemoteOptions remoteOptions)
{
CreateTfsRemote(remoteId, tfsHead.Remote.TfsUrl, tfsHead.Remote.TfsRepositoryPath, remoteOptions);
ReadTfsRemote(remoteId).UpdateRef(tfsHead.GitCommit, tfsHead.ChangesetId);
}
public void CreateTfsRemote(string remoteId, string tfsUrl, string tfsRepositoryPath, RemoteOptions remoteOptions)
{
if (HasRemote(remoteId))
throw new GitTfsException("A remote with id \"" + remoteId + "\" already exists.");
if (remoteOptions != null)
{
if (remoteOptions.NoMetaData) SetTfsConfig(remoteId, "no-meta-data", 1);
if (remoteOptions.IgnoreRegex != null) SetTfsConfig(remoteId, "ignore-paths", remoteOptions.IgnoreRegex);
if (!string.IsNullOrEmpty(remoteOptions.Username)) SetTfsConfig(remoteId, "username", remoteOptions.Username);
if (!string.IsNullOrEmpty(remoteOptions.Password)) SetTfsConfig(remoteId, "password", remoteOptions.Password);
}
SetTfsConfig(remoteId, "url", tfsUrl);
SetTfsConfig(remoteId, "repository", tfsRepositoryPath);
SetTfsConfig(remoteId, "fetch", "refs/remotes/" + remoteId + "/master");
Directory.CreateDirectory(Path.Combine(this.GitDir, "tfs"));
_cachedRemotes = null;
}
private void SetTfsConfig(string remoteId, string subkey, object value)
{
this.SetConfig(_globals.RemoteConfigKey(remoteId, subkey), value);
}
private void ParseRemoteConfig(TextReader stdout, IDictionary<string, IGitTfsRemote> remotes)
{
string line;
while ((line = stdout.ReadLine()) != null)
{
TryParseRemoteConfigLine(line, remotes);
}
foreach (var gitTfsRemotePair in remotes)
{
var remote = gitTfsRemotePair.Value;
remote.EnsureTfsAuthenticated();
}
}
private void TryParseRemoteConfigLine(string line, IDictionary<string, IGitTfsRemote> remotes)
{
var match = configLineRegex.Match(line);
if (match.Success)
{
var key = match.Groups["key"].Value;
var value = match.Groups["value"].Value;
var remoteId = match.Groups["id"].Value;
var remote = remotes.ContainsKey(remoteId)
? remotes[remoteId]
: (remotes[remoteId] = BuildRemote(remoteId));
SetRemoteConfigValue(remote, key, value);
}
}
private IGitTfsRemote BuildRemote(string id)
{
var remote = _container.GetInstance<IGitTfsRemote>();
remote.Repository = this;
remote.Id = id;
return remote;
}
private void SetRemoteConfigValue(IGitTfsRemote remote, string key, string value)
{
switch (key)
{
case "url":
remote.TfsUrl = value;
break;
case "legacy-urls":
remote.Tfs.LegacyUrls = value.Split(',');
break;
case "repository":
remote.TfsRepositoryPath = value;
break;
case "ignore-paths":
remote.IgnoreRegexExpression = value;
break;
//case "fetch":
// remote.??? = value;
// break;
case "username":
remote.TfsUsername = value;
break;
case "password":
remote.TfsPassword = value;
break;
}
}
public GitCommit GetCommit(string commitish)
{
return _container.With(_repository.MapCommit(commitish)).GetInstance<GitCommit>();
}
public IEnumerable<TfsChangesetInfo> GetParentTfsCommits(string head)
{
return GetParentTfsCommits(head, false);
}
public IEnumerable<TfsChangesetInfo> GetParentTfsCommits(string head, bool includeStubRemotes)
{
var tfsCommits = new List<TfsChangesetInfo>();
try
{
CommandOutputPipe(stdout => FindTfsCommits(stdout, tfsCommits, includeStubRemotes),
"log", "--no-color", "--pretty=medium", head);
}
catch (GitCommandException e)
{
Trace.WriteLine("An error occurred while loading head " + head + " (maybe it doesn't exist?): " + e);
}
return from commit in tfsCommits
group commit by commit.Remote
into remotes
select remotes.OrderBy(commit => -commit.ChangesetId).First();
}
private void FindTfsCommits(TextReader stdout, ICollection<TfsChangesetInfo> tfsCommits, bool includeStubRemotes)
{
string currentCommit = null;
string line;
var commitRegex = new Regex("commit (" + GitTfsConstants.Sha1 + ")");
while (null != (line = stdout.ReadLine()))
{
var match = commitRegex.Match(line);
if (match.Success)
{
currentCommit = match.Groups[1].Value;
continue;
}
var changesetInfo = TryParseChangesetInfo(line, currentCommit, includeStubRemotes);
if (changesetInfo != null)
{
tfsCommits.Add(changesetInfo);
currentCommit = null;
}
}
//stdout.Close();
}
private TfsChangesetInfo TryParseChangesetInfo(string gitTfsMetaInfo, string commit, bool includeStubRemotes)
{
var match = GitTfsConstants.TfsCommitInfoRegex.Match(gitTfsMetaInfo);
if (match.Success)
{
var commitInfo = _container.GetInstance<TfsChangesetInfo>();
commitInfo.Remote = ReadTfsRemote(match.Groups["url"].Value, match.Groups["repository"].Value, includeStubRemotes);
commitInfo.ChangesetId = Convert.ToInt32(match.Groups["changeset"].Value);
commitInfo.GitCommit = commit;
return commitInfo;
}
return null;
}
public IDictionary<string, GitObject> GetObjects(string commit)
{
var entries = GetObjects();
if (commit != null)
{
ParseEntries(entries, Command("ls-tree", "-r", "-z", commit), commit);
ParseEntries(entries, Command("ls-tree", "-r", "-d", "-z", commit), commit);
}
return entries;
}
public Dictionary<string, GitObject> GetObjects()
{
return new Dictionary<string, GitObject>(StringComparer.InvariantCultureIgnoreCase);
}
public string GetCommitMessage(string head, string parentCommitish)
{
string message = string.Empty;
using (var logMessage = CommandOutputPipe("log", parentCommitish + ".." + head))
{
string line;
while (null != (line = logMessage.ReadLine()))
{
if (!line.StartsWith(" "))
continue;
message += line.TrimStart() + Environment.NewLine;
}
}
return message;
}
private void ParseEntries(IDictionary<string, GitObject> entries, string treeInfo, string commit)
{
foreach (var treeEntry in treeInfo.Split('\0'))
{
var gitObject = MakeGitObject(commit, treeEntry);
if (gitObject != null)
{
entries[gitObject.Path] = gitObject;
}
}
}
private GitObject MakeGitObject(string commit, string treeInfo)
{
var treeRegex =
new Regex(@"\A(?<mode>\d{6}) (?<type>blob|tree) (?<sha>" + GitTfsConstants.Sha1 + @")\t(?<path>.*)");
var match = treeRegex.Match(treeInfo);
return !match.Success ? null : new GitObject
{
Mode = match.Groups["mode"].Value,
Sha = match.Groups["sha"].Value,
ObjectType = match.Groups["type"].Value,
Path = match.Groups["path"].Value,
Commit = commit
};
}
public IEnumerable<IGitChangedFile> GetChangedFiles(string from, string to)
{
using (var diffOutput = CommandOutputPipe("diff-tree", "-r", "-M", from, to))
{
string line;
while (null != (line = diffOutput.ReadLine()))
{
var change = GitChangeInfo.Parse(line);
if (FileMode.GitLink == change.NewMode)
continue;
yield return BuildGitChangedFile(change);
}
}
}
private IGitChangedFile BuildGitChangedFile(GitChangeInfo change)
{
return change.ToGitChangedFile(_container.With((IGitRepository)this));
}
public string GetChangeSummary(string from, string to)
{
string summary = "";
CommandOutputPipe(stdout => summary = stdout.ReadToEnd(),
"diff-tree", "--shortstat", "-M", from, to);
return summary;
}
public bool WorkingCopyHasUnstagedOrUncommitedChanges
{
get
{
string pendingChanges = "";
CommandOutputPipe(stdout => pendingChanges = stdout.ReadToEnd(),
"diff-index", "--name-status", "-M", "HEAD");
return !string.IsNullOrEmpty(pendingChanges);
}
}
public void GetBlob(string sha, string outputFile)
{
Directory.CreateDirectory(Path.GetDirectoryName(outputFile));
CommandOutputPipe(stdout => Copy(stdout, outputFile), "cat-file", "-p", sha);
}
private void Copy(TextReader stdout, string file)
{
var stdoutStream = ((StreamReader)stdout).BaseStream;
using (var destination = File.Create(file))
{
stdoutStream.CopyTo(destination);
}
}
public string HashAndInsertObject(string filename)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(new FileInfo(filename));
return objectId.Name;
}
public string HashAndInsertObject(Stream file)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(file.Length, file);
return objectId.Name;
}
public string HashAndInsertObject(Stream file, long length)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(length, file);
return objectId.Name;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using GitSharp.Core;
using Sep.Git.Tfs.Commands;
using StructureMap;
using FileMode = GitSharp.Core.FileMode;
namespace Sep.Git.Tfs.Core
{
public class GitRepository : GitHelpers, IGitRepository
{
private readonly IContainer _container;
private readonly Globals _globals;
private static readonly Regex configLineRegex = new Regex("^tfs-remote\\.(?<id>[^.]+)\\.(?<key>[^.=]+)=(?<value>.*)$");
private IDictionary<string, IGitTfsRemote> _cachedRemotes;
private Repository _repository;
public GitRepository(TextWriter stdout, string gitDir, IContainer container, Globals globals)
: base(stdout, container)
{
_container = container;
_globals = globals;
GitDir = gitDir;
_repository = new Repository(new DirectoryInfo(gitDir));
}
private string GitDir { get; set; }
public string WorkingCopyPath { get; set; }
public string WorkingCopySubdir { get; set; }
protected override Process Start(string[] command, Action<ProcessStartInfo> initialize)
{
return base.Start(command, initialize.And(SetUpPaths));
}
private void SetUpPaths(ProcessStartInfo gitCommand)
{
if (GitDir != null)
gitCommand.EnvironmentVariables["GIT_DIR"] = GitDir;
if (WorkingCopyPath != null)
gitCommand.WorkingDirectory = WorkingCopyPath;
if (WorkingCopySubdir != null)
gitCommand.WorkingDirectory = Path.Combine(gitCommand.WorkingDirectory, WorkingCopySubdir);
}
public IEnumerable<IGitTfsRemote> ReadAllTfsRemotes()
{
return GetTfsRemotes().Values;
}
public IGitTfsRemote ReadTfsRemote(string remoteId)
{
if (!HasRemote(remoteId))
throw new GitTfsException("Unable to locate git-tfs remote with id = " + remoteId)
.WithRecommendation("Try using `git tfs bootstrap` to auto-init TFS remotes.");
return GetTfsRemotes()[remoteId];
}
private IGitTfsRemote ReadTfsRemote(string tfsUrl, string tfsRepositoryPath, bool includeStubRemotes)
{
var allRemotes = GetTfsRemotes();
var matchingRemotes =
allRemotes.Values.Where(
remote => remote.Tfs.MatchesUrl(tfsUrl) && remote.TfsRepositoryPath == tfsRepositoryPath);
switch (matchingRemotes.Count())
{
case 0:
if (!includeStubRemotes)
throw new GitTfsException("Unable to locate a remote for <" + tfsUrl + ">" + tfsRepositoryPath)
.WithRecommendation("Try using `git tfs bootstrap` to auto-init TFS remotes.")
.WithRecommendation("Try setting a legacy-url for an existing remote.");
return new DerivedGitTfsRemote(tfsUrl, tfsRepositoryPath);
case 1:
return matchingRemotes.First();
default:
Trace.WriteLine("More than one remote matched!");
goto case 1;
}
}
private IDictionary<string, IGitTfsRemote> GetTfsRemotes()
{
return _cachedRemotes ?? (_cachedRemotes = ReadTfsRemotes());
}
private IDictionary<string, IGitTfsRemote> ReadTfsRemotes()
{
var remotes = new Dictionary<string, IGitTfsRemote>();
CommandOutputPipe(stdout => ParseRemoteConfig(stdout, remotes), "config", "-l");
return remotes;
}
public bool HasRemote(string remoteId)
{
return GetTfsRemotes().ContainsKey(remoteId);
}
public void CreateTfsRemote(string remoteId, TfsChangesetInfo tfsHead, RemoteOptions remoteOptions)
{
CreateTfsRemote(remoteId, tfsHead.Remote.TfsUrl, tfsHead.Remote.TfsRepositoryPath, remoteOptions);
ReadTfsRemote(remoteId).UpdateRef(tfsHead.GitCommit, tfsHead.ChangesetId);
}
public void CreateTfsRemote(string remoteId, string tfsUrl, string tfsRepositoryPath, RemoteOptions remoteOptions)
{
if (HasRemote(remoteId))
throw new GitTfsException("A remote with id \"" + remoteId + "\" already exists.");
if (remoteOptions != null)
{
if (remoteOptions.NoMetaData) SetTfsConfig(remoteId, "no-meta-data", 1);
if (remoteOptions.IgnoreRegex != null) SetTfsConfig(remoteId, "ignore-paths", remoteOptions.IgnoreRegex);
if (!string.IsNullOrEmpty(remoteOptions.Username)) SetTfsConfig(remoteId, "username", remoteOptions.Username);
if (!string.IsNullOrEmpty(remoteOptions.Password)) SetTfsConfig(remoteId, "password", remoteOptions.Password);
}
SetTfsConfig(remoteId, "url", tfsUrl);
SetTfsConfig(remoteId, "repository", tfsRepositoryPath);
SetTfsConfig(remoteId, "fetch", "refs/remotes/" + remoteId + "/master");
Directory.CreateDirectory(Path.Combine(this.GitDir, "tfs"));
_cachedRemotes = null;
}
private void SetTfsConfig(string remoteId, string subkey, object value)
{
this.SetConfig(_globals.RemoteConfigKey(remoteId, subkey), value);
}
private void ParseRemoteConfig(TextReader stdout, IDictionary<string, IGitTfsRemote> remotes)
{
string line;
while ((line = stdout.ReadLine()) != null)
{
TryParseRemoteConfigLine(line, remotes);
}
foreach (var gitTfsRemotePair in remotes)
{
var remote = gitTfsRemotePair.Value;
remote.EnsureTfsAuthenticated();
}
}
private void TryParseRemoteConfigLine(string line, IDictionary<string, IGitTfsRemote> remotes)
{
var match = configLineRegex.Match(line);
if (match.Success)
{
var key = match.Groups["key"].Value;
var value = match.Groups["value"].Value;
var remoteId = match.Groups["id"].Value;
var remote = remotes.ContainsKey(remoteId)
? remotes[remoteId]
: (remotes[remoteId] = BuildRemote(remoteId));
SetRemoteConfigValue(remote, key, value);
}
}
private IGitTfsRemote BuildRemote(string id)
{
var remote = _container.GetInstance<IGitTfsRemote>();
remote.Repository = this;
remote.Id = id;
return remote;
}
private void SetRemoteConfigValue(IGitTfsRemote remote, string key, string value)
{
switch (key)
{
case "url":
remote.TfsUrl = value;
break;
case "legacy-urls":
remote.Tfs.LegacyUrls = value.Split(',');
break;
case "repository":
remote.TfsRepositoryPath = value;
break;
case "ignore-paths":
remote.IgnoreRegexExpression = value;
break;
//case "fetch":
// remote.??? = value;
// break;
case "username":
remote.TfsUsername = value;
break;
case "password":
remote.TfsPassword = value;
break;
}
}
public GitCommit GetCommit(string commitish)
{
return _container.With(_repository.MapCommit(commitish)).GetInstance<GitCommit>();
}
public IEnumerable<TfsChangesetInfo> GetParentTfsCommits(string head)
{
return GetParentTfsCommits(head, false);
}
public IEnumerable<TfsChangesetInfo> GetParentTfsCommits(string head, bool includeStubRemotes)
{
var tfsCommits = new List<TfsChangesetInfo>();
try
{
CommandOutputPipe(stdout => FindTfsCommits(stdout, tfsCommits, includeStubRemotes),
"log", "--no-color", "--pretty=medium", head);
}
catch (GitCommandException e)
{
Trace.WriteLine("An error occurred while loading head " + head + " (maybe it doesn't exist?): " + e);
}
return from commit in tfsCommits
group commit by commit.Remote
into remotes
select remotes.OrderBy(commit => -commit.ChangesetId).First();
}
private void FindTfsCommits(TextReader stdout, ICollection<TfsChangesetInfo> tfsCommits, bool includeStubRemotes)
{
string currentCommit = null;
string line;
var commitRegex = new Regex("commit (" + GitTfsConstants.Sha1 + ")");
while (null != (line = stdout.ReadLine()))
{
var match = commitRegex.Match(line);
if (match.Success)
{
currentCommit = match.Groups[1].Value;
continue;
}
var changesetInfo = TryParseChangesetInfo(line, currentCommit, includeStubRemotes);
if (changesetInfo != null)
{
tfsCommits.Add(changesetInfo);
currentCommit = null;
}
}
//stdout.Close();
}
private TfsChangesetInfo TryParseChangesetInfo(string gitTfsMetaInfo, string commit, bool includeStubRemotes)
{
var match = GitTfsConstants.TfsCommitInfoRegex.Match(gitTfsMetaInfo);
if (match.Success)
{
var commitInfo = _container.GetInstance<TfsChangesetInfo>();
commitInfo.Remote = ReadTfsRemote(match.Groups["url"].Value, match.Groups["repository"].Value, includeStubRemotes);
commitInfo.ChangesetId = Convert.ToInt32(match.Groups["changeset"].Value);
commitInfo.GitCommit = commit;
return commitInfo;
}
return null;
}
public IDictionary<string, GitObject> GetObjects(string commit)
{
var entries = GetObjects();
if (commit != null)
{
ParseEntries(entries, Command("ls-tree", "-r", "-z", commit), commit);
ParseEntries(entries, Command("ls-tree", "-r", "-d", "-z", commit), commit);
}
return entries;
}
public Dictionary<string, GitObject> GetObjects()
{
return new Dictionary<string, GitObject>(StringComparer.InvariantCultureIgnoreCase);
}
public string GetCommitMessage(string head, string parentCommitish)
{
string message = string.Empty;
using (var logMessage = CommandOutputPipe("log", parentCommitish + ".." + head))
{
string line;
while (null != (line = logMessage.ReadLine()))
{
if (!line.StartsWith(" "))
continue;
message += line.TrimStart() + Environment.NewLine;
}
}
return message;
}
private void ParseEntries(IDictionary<string, GitObject> entries, string treeInfo, string commit)
{
foreach (var treeEntry in treeInfo.Split('\0'))
{
var gitObject = MakeGitObject(commit, treeEntry);
if (gitObject != null)
{
entries[gitObject.Path] = gitObject;
}
}
}
private GitObject MakeGitObject(string commit, string treeInfo)
{
var treeRegex =
new Regex(@"\A(?<mode>\d{6}) (?<type>blob|tree) (?<sha>" + GitTfsConstants.Sha1 + @")\t(?<path>.*)");
var match = treeRegex.Match(treeInfo);
return !match.Success ? null : new GitObject
{
Mode = match.Groups["mode"].Value,
Sha = match.Groups["sha"].Value,
ObjectType = match.Groups["type"].Value,
Path = match.Groups["path"].Value,
Commit = commit
};
}
public IEnumerable<IGitChangedFile> GetChangedFiles(string from, string to)
{
using (var diffOutput = CommandOutputPipe("diff-tree", "-r", "-M", from, to))
{
string line;
while (null != (line = diffOutput.ReadLine()))
{
var change = GitChangeInfo.Parse(line);
if (FileMode.GitLink == change.NewMode)
continue;
yield return BuildGitChangedFile(change);
}
}
}
private IGitChangedFile BuildGitChangedFile(GitChangeInfo change)
{
return change.ToGitChangedFile(_container.With((IGitRepository)this));
}
public string GetChangeSummary(string from, string to)
{
string summary = "";
CommandOutputPipe(stdout => summary = stdout.ReadToEnd(),
"diff-tree", "--shortstat", "-M", from, to);
return summary;
}
public bool WorkingCopyHasUnstagedOrUncommitedChanges
{
get
{
string pendingChanges = "";
CommandOutputPipe(stdout => pendingChanges = stdout.ReadToEnd(),
"diff-index", "--name-status", "-M", "HEAD");
return !string.IsNullOrEmpty(pendingChanges);
}
}
public void GetBlob(string sha, string outputFile)
{
Directory.CreateDirectory(Path.GetDirectoryName(outputFile));
CommandOutputPipe(stdout => Copy(stdout, outputFile), "cat-file", "-p", sha);
}
private void Copy(TextReader stdout, string file)
{
var stdoutStream = ((StreamReader)stdout).BaseStream;
using (var destination = File.Create(file))
{
stdoutStream.CopyTo(destination);
}
}
public string HashAndInsertObject(string filename)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(new FileInfo(filename));
return objectId.Name;
}
public string HashAndInsertObject(Stream file)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(file.Length, file);
return objectId.Name;
}
public string HashAndInsertObject(Stream file, long length)
{
var writer = new ObjectWriter(_repository);
var objectId = writer.WriteBlob(length, file);
return objectId.Name;
}
}
}
+3 -3
View File
@@ -28,9 +28,9 @@ namespace Sep.Git.Tfs.Core
Tfs = tfsHelper;
}
public void EnsureTfsAuthenticated()
{
Tfs.EnsureAuthenticated();
public void EnsureTfsAuthenticated()
{
Tfs.EnsureAuthenticated();
}
public bool IsDerived
+2 -2
View File
@@ -30,8 +30,8 @@ namespace Sep.Git.Tfs.Core
long Checkin(string treeish, TfsChangesetInfo parentChangeset);
void CleanupWorkspace();
ITfsChangeset GetChangeset(long changesetId);
void UpdateRef(string commitHash, long changesetId);
void EnsureTfsAuthenticated();
void UpdateRef(string commitHash, long changesetId);
void EnsureTfsAuthenticated();
}
public static partial class Ext
+3 -3
View File
@@ -23,8 +23,8 @@ namespace Sep.Git.Tfs.Core.TfsInterop
bool HasShelveset(string shelvesetName);
bool CanShowCheckinDialog { get; }
long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable<IWorkItemCheckedInfo> checkedInfos, string checkinComment);
void CleanupWorkspaces(string workingDirectory);
void EnsureAuthenticated();
void CleanupWorkspaces(string workingDirectory);
void EnsureAuthenticated();
}
}