diff --git a/GitTfs/Core/GitIndexInfo.cs b/GitTfs/Core/GitIndexInfo.cs index 8797940a..66607182 100644 --- a/GitTfs/Core/GitIndexInfo.cs +++ b/GitTfs/Core/GitIndexInfo.cs @@ -5,17 +5,17 @@ namespace Sep.Git.Tfs.Core { public class GitIndexInfo : IDisposable { - public static int Do(IGitHelpers repository, Action indexAction) + public static int Do(IGitRepository repository, Action indexAction) { int nr = 0; - repository.CommandInputPipe(stdin => nr = Do(stdin, indexAction), + repository.CommandInputPipe(stdin => nr = Do(stdin, repository, indexAction), "update-index", "-z", "--index-info"); return nr; } - private static int Do(TextWriter stdin, Action action) + private static int Do(TextWriter stdin, IGitRepository repository, Action action) { - using (var indexInfo = new GitIndexInfo(stdin)) + using (var indexInfo = new GitIndexInfo(stdin, repository)) { action(indexInfo); return indexInfo.nr; @@ -23,11 +23,13 @@ namespace Sep.Git.Tfs.Core } private readonly TextWriter stdin; + private readonly IGitRepository repository; private int nr = 0; - private GitIndexInfo(TextWriter stdin) + private GitIndexInfo(TextWriter stdin, IGitRepository repository) { this.stdin = stdin; + this.repository = repository; } public int Remove(string path) @@ -40,8 +42,9 @@ namespace Sep.Git.Tfs.Core return ++nr; } - public int Update(string mode, string hash, string path) + public int Update(string mode, string path, Stream data) { + var hash = repository.HashAndInsertObject(data); stdin.Write(mode); stdin.Write(' '); stdin.Write(hash); diff --git a/GitTfs/Core/GitRepository.cs b/GitTfs/Core/GitRepository.cs index 30379978..0f2be8cb 100644 --- a/GitTfs/Core/GitRepository.cs +++ b/GitTfs/Core/GitRepository.cs @@ -97,18 +97,20 @@ namespace Sep.Git.Tfs.Core // This is attractive, but I'm wary of encoding/buffering issues due // to pulling BaseStream out of stdin. It also breaks my abstraction of // using TextWriter for stdin. - //public string HashAndInsertObject(Stream file) - //{ - // string newHash = null; - // CommandInputOutputPipe((stdin, stdout) => newHash = HashAndInsertObject(stdin, stdout, file), - // "has-object", "-w", "--stdin"); - // return newHash; - //} - //private string HashAndInsertObject(StreamWriter stdin, TextReader stdout, Stream file) - //{ - // file.CopyTo(stdin.BaseStream); - // return stdout.ReadLine().Trim(); - //} + // An alternative is to write the stream to a temp file, and call the + // string-based HAIO. + public string HashAndInsertObject(Stream file) + { + string newHash = null; + CommandInputOutputPipe((stdin, stdout) => newHash = HashAndInsertObject(stdin, stdout, file), + "has-object", "-w", "--stdin"); + return newHash; + } + private string HashAndInsertObject(TextWriter stdin, TextReader stdout, Stream file) + { + file.CopyTo(((StreamWriter) stdin).BaseStream); + return stdout.ReadLine().Trim(); + } public string HashAndInsertObject(string filename) { diff --git a/GitTfs/Core/GitTfsRemote.cs b/GitTfs/Core/GitTfsRemote.cs index e0490b68..c930c717 100644 --- a/GitTfs/Core/GitTfsRemote.cs +++ b/GitTfs/Core/GitTfsRemote.cs @@ -46,6 +46,19 @@ namespace Sep.Git.Tfs.Core } } + public bool IsIgnored(string path) + { + var inDotGit = new Regex("?:^|/)\\.git(?:/|$)"); + if(inDotGit.IsMatch(path)) return true; + if(IgnoreRegex != null && new Regex(IgnoreRegex).IsMatch(path)) return true; + if(remoteOptions.IgnoreRegex != null && new Regex(remoteOptions.IgnoreRegex).IsMatch(path)) return true; + return false; + } + + public string GetPathInGitRepo(string tfsPath) + { + } + public void Fetch() { //var ignoreRegexPattern = remoteOptions.IgnoreRegex ?? IgnoreRegex; @@ -194,4 +207,4 @@ namespace Sep.Git.Tfs.Core } } } -} \ No newline at end of file +} diff --git a/GitTfs/Core/IGitRepository.cs b/GitTfs/Core/IGitRepository.cs index 578f6811..8b17f663 100644 --- a/GitTfs/Core/IGitRepository.cs +++ b/GitTfs/Core/IGitRepository.cs @@ -9,5 +9,6 @@ namespace Sep.Git.Tfs.Core IEnumerable ReadAllTfsRemotes(); GitTfsRemote ReadTfsRemote(string remoteId); string HashAndInsertObject(string filename); + string HashAndInsertObject(Stream data); } } diff --git a/GitTfs/Core/TfsChangeset.cs b/GitTfs/Core/TfsChangeset.cs index a2fef823..8a492b3c 100644 --- a/GitTfs/Core/TfsChangeset.cs +++ b/GitTfs/Core/TfsChangeset.cs @@ -10,21 +10,28 @@ namespace Sep.Git.Tfs.Core private readonly Changeset changeset; public TfsChangesetInfo Summary { get; set; } - public LogEntry Apply(GitIndexInfo index) + public LogEntry Apply(GitTfsRemote remote, GitIndexInfo index) { foreach(var change in changeset.Changes) { - if (change.ChangeType.IncludesOneOf(ChangeType.Add, ChangeType.Edit, ChangeType.Undelete, ChangeType.Branch, ChangeType.Merge)) + var pathInGitRepo = remote.GetPathInGitRepo(change.Item.ServerItem); + if(pathInGitRepo == null || remote.IsIgnored(pathInGitRepo)) + continue; + if (change.ChangeType.IncludesOneOf(ChangeType.Add, ChangeType.Edit, ChangeType.Rename, ChangeType.Undelete, ChangeType.Branch, ChangeType.Merge)) { - throw new NotImplementedException("TODO: add/edit"); - } - else if(change.ChangeType.IncludesOneOf(ChangeType.Rename)) - { - throw new NotImplementedException("TODO: rename"); + if(change.ChangeType.IncludesOneOf(ChangeType.Rename)) + { + var oldPath = GetPathBeforeRename(change); + if(oldPath != null) index.Remove(oldPath); + } + using(var changeStream = GetStream(change)) + { + index.Update(GetMode(change), pathInGitRepo, changeStream); + } } else if (change.ChangeType.IncludesOneOf(ChangeType.Delete)) { - throw new NotImplementedException("TODO: delete"); + index.Remove(pathInGitRepo); } else { @@ -32,8 +39,20 @@ namespace Sep.Git.Tfs.Core change.Item.ServerItem + " of type " + change.ChangeType + "."); } } - //throw new System.NotImplementedException(); - return new LogEntry(); + return MakeNewLogEntry(); + } + + private string GetMode(Change change) + { + } + + private LogEntry MakeNewLogEntry() + { + var log = new LogEntry(); + log.CommitterName = log.AuthorName = GetAuthorName(); + log.CommitterEmail = log.AuthorEmail = GetAuthorEmail(); + log.Date = changeset.Date; + log.Log = changeset.Description + Environment.NewLine; } public TfsChangeset(TfsHelper tfs, Changeset changeset) diff --git a/GitTfs/Core/TfsHelper.cs b/GitTfs/Core/TfsHelper.cs index 76a3d658..b509fec9 100644 --- a/GitTfs/Core/TfsHelper.cs +++ b/GitTfs/Core/TfsHelper.cs @@ -78,7 +78,7 @@ namespace Sep.Git.Tfs.Core foreach (Changeset changeset in changesets) { yield return - new TfsChangeset(this, changeset) + new TfsChangeset(this, changeset, basePath) { Summary = new TfsChangesetInfo() @@ -87,4 +87,4 @@ namespace Sep.Git.Tfs.Core } } } -} \ No newline at end of file +}