From 50a7bfa2f09c593b83f040acfcdb192e1ef67bc6 Mon Sep 17 00:00:00 2001 From: Matt Burke Date: Thu, 14 Jul 2011 00:03:10 -0400 Subject: [PATCH] Fix line endings. --- GitTfs.Vs2008/TfsHelper.Vs2008.cs | 160 +++--- GitTfs.VsCommon/TfsHelper.Common.cs | 50 +- GitTfs/Commands/Bootstrap.cs | 8 +- GitTfs/Core/DerivedGitTfsRemote.cs | 14 +- GitTfs/Core/GitRepository.cs | 800 +++++++++++++-------------- GitTfs/Core/GitTfsRemote.cs | 6 +- GitTfs/Core/IGitTfsRemote.cs | 4 +- GitTfs/Core/TfsInterop/ITfsHelper.cs | 6 +- 8 files changed, 524 insertions(+), 524 deletions(-) diff --git a/GitTfs.Vs2008/TfsHelper.Vs2008.cs b/GitTfs.Vs2008/TfsHelper.Vs2008.cs index 753d6cc2..dedbd6c4 100644 --- a/GitTfs.Vs2008/TfsHelper.Vs2008.cs +++ b/GitTfs.Vs2008/TfsHelper.Vs2008.cs @@ -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() - { - 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 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).DownloadFile(tempfile); - return tempfile.ToStream(); - } - } -} \ No newline at end of file +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() + { + 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 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).DownloadFile(tempfile); + return tempfile.ToStream(); + } + } +} diff --git a/GitTfs.VsCommon/TfsHelper.Common.cs b/GitTfs.VsCommon/TfsHelper.Common.cs index 383ad972..8df712b9 100644 --- a/GitTfs.VsCommon/TfsHelper.Common.cs +++ b/GitTfs.VsCommon/TfsHelper.Common.cs @@ -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(); protected VersionControlServer VersionControl diff --git a/GitTfs/Commands/Bootstrap.cs b/GitTfs/Commands/Bootstrap.cs index b1da053e..45f39af9 100644 --- a/GitTfs/Commands/Bootstrap.cs +++ b/GitTfs/Commands/Bootstrap.cs @@ -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; } diff --git a/GitTfs/Core/DerivedGitTfsRemote.cs b/GitTfs/Core/DerivedGitTfsRemote.cs index cdad392b..ca470811 100644 --- a/GitTfs/Core/DerivedGitTfsRemote.cs +++ b/GitTfs/Core/DerivedGitTfsRemote.cs @@ -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 } } diff --git a/GitTfs/Core/GitRepository.cs b/GitTfs/Core/GitRepository.cs index fb61b8af..73e10e84 100644 --- a/GitTfs/Core/GitRepository.cs +++ b/GitTfs/Core/GitRepository.cs @@ -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\\.(?[^.]+)\\.(?[^.=]+)=(?.*)$"); - private IDictionary _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 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 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 GetTfsRemotes() - { - return _cachedRemotes ?? (_cachedRemotes = ReadTfsRemotes()); - } - - private IDictionary ReadTfsRemotes() - { - var remotes = new Dictionary(); - 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 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 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(); - 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(); - } - - public IEnumerable GetParentTfsCommits(string head) - { - return GetParentTfsCommits(head, false); - } - - public IEnumerable GetParentTfsCommits(string head, bool includeStubRemotes) - { - var tfsCommits = new List(); - 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 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(); - 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 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 GetObjects() - { - return new Dictionary(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 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(?\d{6}) (?blob|tree) (?" + GitTfsConstants.Sha1 + @")\t(?.*)"); - 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 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\\.(?[^.]+)\\.(?[^.=]+)=(?.*)$"); + private IDictionary _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 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 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 GetTfsRemotes() + { + return _cachedRemotes ?? (_cachedRemotes = ReadTfsRemotes()); + } + + private IDictionary ReadTfsRemotes() + { + var remotes = new Dictionary(); + 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 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 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(); + 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(); + } + + public IEnumerable GetParentTfsCommits(string head) + { + return GetParentTfsCommits(head, false); + } + + public IEnumerable GetParentTfsCommits(string head, bool includeStubRemotes) + { + var tfsCommits = new List(); + 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 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(); + 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 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 GetObjects() + { + return new Dictionary(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 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(?\d{6}) (?blob|tree) (?" + GitTfsConstants.Sha1 + @")\t(?.*)"); + 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 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; + } + } +} diff --git a/GitTfs/Core/GitTfsRemote.cs b/GitTfs/Core/GitTfsRemote.cs index 852579f4..1682285a 100644 --- a/GitTfs/Core/GitTfsRemote.cs +++ b/GitTfs/Core/GitTfsRemote.cs @@ -28,9 +28,9 @@ namespace Sep.Git.Tfs.Core Tfs = tfsHelper; } - public void EnsureTfsAuthenticated() - { - Tfs.EnsureAuthenticated(); + public void EnsureTfsAuthenticated() + { + Tfs.EnsureAuthenticated(); } public bool IsDerived diff --git a/GitTfs/Core/IGitTfsRemote.cs b/GitTfs/Core/IGitTfsRemote.cs index 092d0e1c..698a989c 100644 --- a/GitTfs/Core/IGitTfsRemote.cs +++ b/GitTfs/Core/IGitTfsRemote.cs @@ -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 diff --git a/GitTfs/Core/TfsInterop/ITfsHelper.cs b/GitTfs/Core/TfsInterop/ITfsHelper.cs index 9efb026b..583c5232 100644 --- a/GitTfs/Core/TfsInterop/ITfsHelper.cs +++ b/GitTfs/Core/TfsInterop/ITfsHelper.cs @@ -23,8 +23,8 @@ namespace Sep.Git.Tfs.Core.TfsInterop bool HasShelveset(string shelvesetName); bool CanShowCheckinDialog { get; } long ShowCheckinDialog(IWorkspace workspace, IPendingChange[] pendingChanges, IEnumerable checkedInfos, string checkinComment); - void CleanupWorkspaces(string workingDirectory); - - void EnsureAuthenticated(); + void CleanupWorkspaces(string workingDirectory); + + void EnsureAuthenticated(); } } \ No newline at end of file