From 4bb82ddcfd83d3440eabe9ea404c5083c37c0c3a Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 14 Jun 2019 18:03:37 +0200 Subject: [PATCH 1/5] Fix the git log and git status output processors. Split status field into two. The git status output processor was not handling all the variations that the command outputs for the status flags. Make it actually follow what the manual says. In the process, the status field of a git status entry has now been split into indexStatus and workTreeStatus fields, to provide all the underlying information that the command provides. Staged and Unmerged can be obtained via new properties in the GitStatusEntry structure, or calculated directly from the indexStatus and workTreeStatus fields. --- src/.gitignore | 3 +- src/GitHub.Api/Git/GitObjectFactory.cs | 4 +- src/GitHub.Api/Git/GitStatusEntry.cs | 75 +++++-- src/GitHub.Api/Git/IGitObjectFactory.cs | 2 +- src/GitHub.Api/Git/RepositoryManager.cs | 2 +- src/GitHub.Api/Git/Tasks/GitLogTask.cs | 21 +- src/GitHub.Api/Git/Tasks/GitStatusTask.cs | 2 +- .../BranchListOutputProcessor.cs | 21 +- .../GitCountObjectsProcessor.cs | 5 +- .../OutputProcessors/LineProcessor.cs | 86 ++++++-- .../LogEntryOutputProcessor.cs | 102 ++------- .../RemoteListOutputProcessor.cs | 2 +- .../OutputProcessors/StatusOutputProcessor.cs | 204 ++++++------------ .../WindowsDiskUsageOutputProcessor.cs | 23 +- .../Platform/WindowsDiskUsageTask.cs | 4 +- src/GitHub.Api/Tasks/ProcessTask.cs | 21 +- .../GitHub.Unity/UI/ChangesTreeControl.cs | 2 +- src/tests/IntegrationTests/IOTestsRepo.zip | 4 +- .../IntegrationTests/IntegrationTests.csproj | 1 - .../Process/ProcessManagerIntegrationTests.cs | 20 +- .../Helpers}/ProcessManagerExtensions.cs | 39 ++-- .../Substitutes/SubstituteFactory.cs | 11 +- src/tests/TestUtils/TestUtils.csproj | 1 + src/tests/TestWebServer/HttpServer.cs | 2 +- .../UnitTests/IO/GitLogEntryListTests.cs | 17 +- src/tests/UnitTests/IO/GitLogEntryTests.cs | 13 +- .../UnitTests/IO/GitObjectFactoryTests.cs | 4 +- .../IO/GitStatusEntryFactoryTests.cs | 14 +- .../UnitTests/IO/GitStatusEntryListTests.cs | 18 +- src/tests/UnitTests/IO/GitStatusEntryTests.cs | 115 ++++++++-- .../IO/LogEntryOutputProcessorTests.cs | 6 +- .../IO/StatusOutputProcessorTests.cs | 99 ++++----- .../WindowsDiskUsageOutputProcessorTests.cs | 4 +- .../UnitTests/ProcessManagerExtensions.cs | 109 ---------- src/tests/UnitTests/UnitTests.csproj | 1 - 35 files changed, 498 insertions(+), 559 deletions(-) rename src/tests/{IntegrationTests => TestUtils/Helpers}/ProcessManagerExtensions.cs (59%) delete mode 100644 src/tests/UnitTests/ProcessManagerExtensions.cs diff --git a/src/.gitignore b/src/.gitignore index f8cebfc72..a7abc4e4a 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -312,4 +312,5 @@ sysinfo.txt # Builds *.apk *.unitypackage -UnityExtension/**/manifest.json \ No newline at end of file +UnityExtension/**/manifest.json +tests/IntegrationTests/IOTestsRepo/ \ No newline at end of file diff --git a/src/GitHub.Api/Git/GitObjectFactory.cs b/src/GitHub.Api/Git/GitObjectFactory.cs index d7d4cf194..d0fe3b640 100644 --- a/src/GitHub.Api/Git/GitObjectFactory.cs +++ b/src/GitHub.Api/Git/GitObjectFactory.cs @@ -12,13 +12,13 @@ public GitObjectFactory(IEnvironment environment) this.environment = environment; } - public GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus status, string originalPath = null, bool staged = false) + public GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus indexStatus, GitFileStatus workTreeStatus = GitFileStatus.None, string originalPath = null) { var absolutePath = new NPath(path).MakeAbsolute(); var relativePath = absolutePath.RelativeTo(environment.RepositoryPath); var projectPath = absolutePath.RelativeTo(environment.UnityProjectPath); - return new GitStatusEntry(relativePath, absolutePath, projectPath, status, originalPath?.ToNPath(), staged); + return new GitStatusEntry(relativePath, absolutePath, projectPath, indexStatus, workTreeStatus, originalPath?.ToNPath()); } } } diff --git a/src/GitHub.Api/Git/GitStatusEntry.cs b/src/GitHub.Api/Git/GitStatusEntry.cs index 5de898770..b20c3efa8 100644 --- a/src/GitHub.Api/Git/GitStatusEntry.cs +++ b/src/GitHub.Api/Git/GitStatusEntry.cs @@ -11,21 +11,22 @@ public struct GitStatusEntry public string fullPath; public string projectPath; public string originalPath; - public GitFileStatus status; - public bool staged; + public GitFileStatus indexStatus; + public GitFileStatus workTreeStatus; - public GitStatusEntry(string path, string fullPath, string projectPath, GitFileStatus status, - string originalPath = null, bool staged = false) + public GitStatusEntry(string path, string fullPath, string projectPath, + GitFileStatus indexStatus, GitFileStatus workTreeStatus, + string originalPath = null) { Guard.ArgumentNotNullOrWhiteSpace(path, "path"); Guard.ArgumentNotNullOrWhiteSpace(fullPath, "fullPath"); this.path = path; - this.status = status; + this.indexStatus = indexStatus; + this.workTreeStatus = workTreeStatus; this.fullPath = fullPath; this.projectPath = projectPath; this.originalPath = originalPath; - this.staged = staged; } public override int GetHashCode() @@ -35,8 +36,8 @@ public override int GetHashCode() hash = hash * 23 + (fullPath?.GetHashCode() ?? 0); hash = hash * 23 + (projectPath?.GetHashCode() ?? 0); hash = hash * 23 + (originalPath?.GetHashCode() ?? 0); - hash = hash * 23 + status.GetHashCode(); - hash = hash * 23 + staged.GetHashCode(); + hash = hash * 23 + indexStatus.GetHashCode(); + hash = hash * 23 + workTreeStatus.GetHashCode(); return hash; } @@ -54,8 +55,8 @@ public bool Equals(GitStatusEntry other) String.Equals(fullPath, other.fullPath) && String.Equals(projectPath, other.projectPath) && String.Equals(originalPath, other.originalPath) && - status == other.status && - staged == other.staged + indexStatus == other.indexStatus && + workTreeStatus == other.workTreeStatus ; } @@ -78,6 +79,49 @@ public bool Equals(GitStatusEntry other) return !(lhs == rhs); } + public static GitFileStatus ParseStatusMarker(char changeFlag) + { + GitFileStatus status = GitFileStatus.None; + switch (changeFlag) + { + case 'M': + status = GitFileStatus.Modified; + break; + case 'A': + status = GitFileStatus.Added; + break; + case 'D': + status = GitFileStatus.Deleted; + break; + case 'R': + status = GitFileStatus.Renamed; + break; + case 'C': + status = GitFileStatus.Copied; + break; + case 'U': + status = GitFileStatus.Unmerged; + break; + case 'T': + status = GitFileStatus.TypeChange; + break; + case 'X': + status = GitFileStatus.Unknown; + break; + case 'B': + status = GitFileStatus.Broken; + break; + case '?': + status = GitFileStatus.Untracked; + break; + case '!': + status = GitFileStatus.Ignored; + break; + default: break; + } + return status; + } + public string Path => path; public string FullPath => fullPath; @@ -86,13 +130,18 @@ public bool Equals(GitStatusEntry other) public string OriginalPath => originalPath; - public GitFileStatus Status => status; + public GitFileStatus Status => workTreeStatus != GitFileStatus.None ? workTreeStatus : indexStatus; + public GitFileStatus IndexStatus => indexStatus; + public GitFileStatus WorkTreeStatus => workTreeStatus; + + public bool Staged => indexStatus != GitFileStatus.None; - public bool Staged => staged; + public bool Unmerged => (indexStatus == workTreeStatus && (indexStatus == GitFileStatus.Added || indexStatus == GitFileStatus.Deleted)) || + indexStatus == GitFileStatus.Unmerged || workTreeStatus == GitFileStatus.Unmerged; public override string ToString() { - return $"Path:'{Path}' Status:'{Status}' FullPath:'{FullPath}' ProjectPath:'{ProjectPath}' OriginalPath:'{OriginalPath}' Staged:'{Staged}'"; + return $"Path:'{Path}' Status:'{Status}' FullPath:'{FullPath}' ProjectPath:'{ProjectPath}' OriginalPath:'{OriginalPath}' Staged:'{Staged}' Unmerged:'{Unmerged}' Status:'{IndexStatus}' Status:'{WorkTreeStatus}' "; } } } diff --git a/src/GitHub.Api/Git/IGitObjectFactory.cs b/src/GitHub.Api/Git/IGitObjectFactory.cs index febd83983..7458c9403 100644 --- a/src/GitHub.Api/Git/IGitObjectFactory.cs +++ b/src/GitHub.Api/Git/IGitObjectFactory.cs @@ -2,6 +2,6 @@ namespace GitHub.Unity { public interface IGitObjectFactory { - GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus status, string originalPath = null, bool staged = false); + GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus indexStatus, GitFileStatus workTreeStatus, string originalPath = null); } } diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index 328801b1d..7b2045b43 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -317,7 +317,7 @@ public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries) foreach (var gitStatusEntry in gitStatusEntries) { - if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked) + if (gitStatusEntry.WorkTreeStatus == GitFileStatus.Added || gitStatusEntry.WorkTreeStatus == GitFileStatus.Untracked) { itemsToDelete.Add(gitStatusEntry.path.ToNPath().MakeAbsolute()); } diff --git a/src/GitHub.Api/Git/Tasks/GitLogTask.cs b/src/GitHub.Api/Git/Tasks/GitLogTask.cs index 89a2af11a..ace25072a 100644 --- a/src/GitHub.Api/Git/Tasks/GitLogTask.cs +++ b/src/GitHub.Api/Git/Tasks/GitLogTask.cs @@ -9,20 +9,39 @@ public class GitLogTask : ProcessTaskWithListOutput private readonly string arguments; public GitLogTask(IGitObjectFactory gitObjectFactory, + CancellationToken token, + BaseOutputListProcessor processor = null) + : this(0, gitObjectFactory, token, processor) + { + } + + public GitLogTask(string file, + IGitObjectFactory gitObjectFactory, CancellationToken token, BaseOutputListProcessor processor = null) + : this(file, 0, gitObjectFactory, token, processor) + { + } + + public GitLogTask(int numberOfCommits, IGitObjectFactory gitObjectFactory, + CancellationToken token, + BaseOutputListProcessor processor = null) : base(token, processor ?? new LogEntryOutputProcessor(gitObjectFactory)) { Name = TaskName; arguments = baseArguments; + if (numberOfCommits > 0) + arguments += " -n " + numberOfCommits; } - public GitLogTask(string file, + public GitLogTask(string file, int numberOfCommits, IGitObjectFactory gitObjectFactory, CancellationToken token, BaseOutputListProcessor processor = null) : base(token, processor ?? new LogEntryOutputProcessor(gitObjectFactory)) { Name = TaskName; arguments = baseArguments; + if (numberOfCommits > 0) + arguments += " -n " + numberOfCommits; arguments += " -- "; arguments += " \"" + file + "\""; } diff --git a/src/GitHub.Api/Git/Tasks/GitStatusTask.cs b/src/GitHub.Api/Git/Tasks/GitStatusTask.cs index 08361fcb8..2acf8d26a 100644 --- a/src/GitHub.Api/Git/Tasks/GitStatusTask.cs +++ b/src/GitHub.Api/Git/Tasks/GitStatusTask.cs @@ -15,7 +15,7 @@ public GitStatusTask(IGitObjectFactory gitObjectFactory, public override string ProcessArguments { - get { return "-c i18n.logoutputencoding=utf8 -c core.quotepath=false status -b -u --porcelain"; } + get { return "-c i18n.logoutputencoding=utf8 -c core.quotepath=false --no-optional-locks status -b -u --porcelain"; } } public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } } public override string Message { get; set; } = "Listing changed files..."; diff --git a/src/GitHub.Api/OutputProcessors/BranchListOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/BranchListOutputProcessor.cs index 85172a96d..2b6427f40 100644 --- a/src/GitHub.Api/OutputProcessors/BranchListOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/BranchListOutputProcessor.cs @@ -1,4 +1,5 @@ using System; +using System.Security.AccessControl; using System.Text.RegularExpressions; namespace GitHub.Unity @@ -18,23 +19,24 @@ public override void LineReceived(string line) try { - proc.Matches('*'); + string name; + string trackingName = null; + + if (proc.Matches('*')) + proc.MoveNext(); proc.SkipWhitespace(); - var detached = proc.Matches("(HEAD "); - var name = "detached"; - if (detached) + if (proc.Matches("(HEAD ")) { + name = "detached"; proc.MoveToAfter(')'); } else { name = proc.ReadUntilWhitespace(); } - proc.SkipWhitespace(); - proc.ReadUntilWhitespace(); - var tracking = proc.Matches(trackingBranchRegex); - var trackingName = ""; - if (tracking) + + proc.ReadUntilWhitespaceTrim(); + if (proc.Matches(trackingBranchRegex)) { trackingName = proc.ReadChunk('[', ']'); var indexOf = trackingName.IndexOf(':'); @@ -45,7 +47,6 @@ public override void LineReceived(string line) } var branch = new GitBranch(name, trackingName); - RaiseOnEntry(branch); } catch(Exception ex) diff --git a/src/GitHub.Api/OutputProcessors/GitCountObjectsProcessor.cs b/src/GitHub.Api/OutputProcessors/GitCountObjectsProcessor.cs index 56b4d96ff..3fe0f31b7 100644 --- a/src/GitHub.Api/OutputProcessors/GitCountObjectsProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/GitCountObjectsProcessor.cs @@ -15,9 +15,8 @@ public override void LineReceived(string line) { var proc = new LineParser(line); - proc.ReadUntil(','); - proc.SkipWhitespace(); - var kilobytes = int.Parse(proc.ReadUntilWhitespace()); + proc.MoveToAfter(','); + var kilobytes = int.Parse(proc.ReadUntilWhitespaceTrim()); RaiseOnEntry(kilobytes); } diff --git a/src/GitHub.Api/OutputProcessors/LineProcessor.cs b/src/GitHub.Api/OutputProcessors/LineProcessor.cs index 213717162..8d90ea413 100644 --- a/src/GitHub.Api/OutputProcessors/LineProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/LineProcessor.cs @@ -61,19 +61,30 @@ public void SkipWhitespace() if (IsAtEnd) throw new InvalidOperationException("Reached end of line"); - while (!Char.IsWhiteSpace(line[current]) && current < line.Length) - current++; - while (Char.IsWhiteSpace(line[current]) && current < line.Length) + while (current < line.Length && char.IsWhiteSpace(line[current])) current++; } - public string ReadUntil(char separator) + /// + /// Reads until it finds the separator and returns what it read. + /// + /// + /// If the current character matches the + /// separator and you actually want to read the next match, set this to true (if you're tokenizing, for instance) + /// + public string ReadUntil(char separator, bool skipCurrentIfMatch = false) { if (IsAtEnd) throw new InvalidOperationException("Reached end of line"); - if (line[current] == separator) - current++; + if (Matches(separator)) + { + if (skipCurrentIfMatch) + MoveNext(); + else + return null; + } + var end = line.IndexOf(separator, current); if (end == -1) return null; @@ -82,23 +93,30 @@ public string ReadUntil(char separator) return LastSubstring; } + + public string ReadUntilWhitespaceTrim() + { + SkipWhitespace(); + if (IsAtEnd) + return null; + return ReadUntilWhitespace(); + } + public string ReadUntilWhitespace() { if (IsAtEnd) throw new InvalidOperationException("Reached end of line"); - if (Char.IsWhiteSpace(line[current])) - SkipWhitespace(); + if (char.IsWhiteSpace(line[current])) + return null; + + var end = current; + while (end < line.Length && !char.IsWhiteSpace(line[end])) + end++; + + if (end == current) // current character is a whitespace, read nothing + return null; - int end = line.Length; - for (var i = current; i < end; i++) - { - if (Char.IsWhiteSpace(line[i])) - { - end = i; - break; - } - } LastSubstring = line.Substring(current, end - current); current = end; return LastSubstring; @@ -125,6 +143,30 @@ public string ReadToEnd() return LastSubstring; } + public string Read(int howMany) + { + if (IsAtEnd) + throw new InvalidOperationException("Reached end of line"); + + if (current + howMany > line.Length) + return null; + + LastSubstring = line.Substring(current, howMany); + current += howMany; + return LastSubstring; + } + + public char ReadChar() + { + if (IsAtEnd) + throw new InvalidOperationException("Reached end of line"); + + var ret = line[current]; + LastSubstring = ret.ToString(); + MoveNext(); + return ret; + } + public string ReadUntilLast(string str) { if (IsAtEnd) @@ -138,10 +180,10 @@ public string ReadUntilLast(string str) return LastSubstring; } - public bool IsAtEnd { get { return line != null ? line.Length == current : true; } } - public bool IsAtWhitespace { get { return line != null && Char.IsWhiteSpace(line[current]); } } - public bool IsAtDigit { get { return line != null && Char.IsDigit(line[current]); } } - public bool IsAtLetter { get { return line != null && Char.IsLetter(line[current]); } } + public bool IsAtEnd => line == null || line.Length == current; + public bool IsAtWhitespace => line != null && Char.IsWhiteSpace(line[current]); + public bool IsAtDigit => line != null && Char.IsDigit(line[current]); + public bool IsAtLetter => line != null && Char.IsLetter(line[current]); public string LastSubstring { get; private set; } } -} \ No newline at end of file +} diff --git a/src/GitHub.Api/OutputProcessors/LogEntryOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/LogEntryOutputProcessor.cs index f0d011039..79d1fdeef 100644 --- a/src/GitHub.Api/OutputProcessors/LogEntryOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/LogEntryOutputProcessor.cs @@ -190,101 +190,45 @@ public override void LineReceived(string line) var proc = new LineParser(line); string file = null; - GitFileStatus status; + GitFileStatus status = GitFileStatus.None; string originalPath = null; - if (proc.Matches('M')) - { - status = GitFileStatus.Modified; - } - else if (proc.Matches('A')) - { - status = GitFileStatus.Added; - } - else if (proc.Matches('D')) - { - status = GitFileStatus.Deleted; - } - else if (proc.Matches('R')) - { - status = GitFileStatus.Renamed; - } - else if (proc.Matches('C')) - { - status = GitFileStatus.Copied; - } - else if (proc.Matches('T')) - { - status = GitFileStatus.TypeChange; - } - else if (proc.Matches('U')) - { - status = GitFileStatus.Unmerged; - } - else if (proc.Matches('X')) - { - status = GitFileStatus.Unknown; - } - else if (proc.Matches('B')) - { - status = GitFileStatus.Broken; - } - else if (String.IsNullOrEmpty(line)) + if (proc.IsAtEnd) { // there's no files on this commit, it's a new one! ReturnGitLogEntry(); return; } else + { + status = GitStatusEntry.ParseStatusMarker(proc.ReadChar()); + } + + if (status == GitFileStatus.None) { HandleUnexpected(line); return; } - switch (status) + proc.ReadUntilWhitespace(); + if (status == GitFileStatus.Copied || status == GitFileStatus.Renamed) { - case GitFileStatus.Modified: - case GitFileStatus.Added: - case GitFileStatus.Deleted: - proc.SkipWhitespace(); - - file = proc.Matches('"') - ? proc.ReadUntil('"') - : proc.ReadToEnd(); - - break; - case GitFileStatus.Renamed: - - proc.SkipWhitespace(); - - originalPath = - proc.Matches('"') - ? proc.ReadUntil('"') - : proc.ReadUntilWhitespace(); - - proc.SkipWhitespace(); - - file = proc.Matches('"') - ? proc.ReadUntil('"') - : proc.ReadToEnd(); - - break; - - default: - proc.SkipWhitespace(); - - file = proc.Matches('"') - ? proc.ReadUntil('"') - : proc.ReadUntilWhitespace(); - if (file == null) - { - file = proc.ReadToEnd(); - } - - break; + var files = + proc.ReadToEnd().Trim() + .Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries) + .Select(s => s.Trim()) + .Select(s => s.Trim('"')) + .ToArray(); + + originalPath = files[0]; + file = files[1]; + } + else + { + file = proc.ReadToEnd().Trim().Trim('"'); } - changes.Add(gitObjectFactory.CreateGitStatusEntry(file, status, originalPath)); + changes.Add(gitObjectFactory.CreateGitStatusEntry(file, status, GitFileStatus.None, originalPath)); break; diff --git a/src/GitHub.Api/OutputProcessors/RemoteListOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/RemoteListOutputProcessor.cs index 03f8f9d68..08332bbe6 100644 --- a/src/GitHub.Api/OutputProcessors/RemoteListOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/RemoteListOutputProcessor.cs @@ -110,4 +110,4 @@ private void Reset() currentUrl = null; } } -} \ No newline at end of file +} diff --git a/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs index 3cbb45a65..26be0f9fd 100644 --- a/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs @@ -89,160 +89,76 @@ public override void LineReceived(string line) } else { - // M GitHubVS.sln - //R README.md -> README2.md - // D deploy.cmd - //A something added.txt - //?? something.txt + var gitStatusMarker = proc.Read(2); + if (gitStatusMarker == null) + { + HandleUnexpected(line); + return; + } + + + /* + X Y Meaning + ------------------------------------------------- + [AMD] not updated + M [ MD] updated in index + A [ MD] added to index + D deleted from index + R [ MD] renamed in index + C [ MD] copied in index + [MARC] index and work tree matches + [ MARC] M work tree changed since index + [ MARC] D deleted in work tree + [ D] R renamed in work tree + [ D] C copied in work tree + ------------------------------------------------- + D D unmerged, both deleted + A A unmerged, both added + A U unmerged, added by us + D U unmerged, deleted by us + U A unmerged, added by them + U D unmerged, deleted by them + U U unmerged, both modified + ------------------------------------------------- + ? ? untracked + ! ! ignored + ------------------------------------------------- + */ string originalPath = null; string path = null; - var status = GitFileStatus.Added; - var staged = false; - if (proc.Matches('?')) - { - //?? something.txt - proc.MoveToAfter('?'); - proc.SkipWhitespace(); + var indexStatusMarker = gitStatusMarker[0]; + var workTreeStatusMarker = gitStatusMarker[1]; - path = proc.ReadToEnd().Trim('"'); - status = GitFileStatus.Untracked; - } - else if (proc.Matches('!')) + GitFileStatus indexStatus = GitStatusEntry.ParseStatusMarker(indexStatusMarker); + GitFileStatus workTreeStatus = GitStatusEntry.ParseStatusMarker(workTreeStatusMarker); + GitFileStatus status = workTreeStatus != GitFileStatus.None ? workTreeStatus : indexStatus; + + if (status == GitFileStatus.None) { - //?? something.txt - proc.MoveToAfter('!'); - proc.SkipWhitespace(); + HandleUnexpected(line); + return; + } - path = proc.ReadToEnd().Trim('"'); - status = GitFileStatus.Ignored; + if (status == GitFileStatus.Copied || status == GitFileStatus.Renamed) + { + var files = + proc.ReadToEnd() + .Split(new[] { "->" }, StringSplitOptions.RemoveEmptyEntries) + .Select(s => s.Trim()) + .Select(s => s.Trim('"')) + .ToArray(); + + originalPath = files[0]; + path = files[1]; } else { - var secondPosition = false; - if (proc.IsAtWhitespace) - { - proc.SkipWhitespace(); - secondPosition = true; - } - - if (proc.Matches('M')) - { - //M GitHubVS.sln - proc.MoveNext(); - proc.SkipWhitespace(); - - path = proc.ReadToEnd().Trim('"'); - status = GitFileStatus.Modified; - staged = !secondPosition; - } - else if (proc.Matches('D')) - { - proc.MoveNext(); - - if (proc.Matches('D') || proc.Matches('U')) - { - //DD deploy.cmd - unmerged, both deleted - //DU deploy.cmd - unmerged, deleted by us - - status = GitFileStatus.Unmerged; - } - else if(proc.IsAtWhitespace) - { - //D deploy.cmd - // D deploy.cmd - - status = GitFileStatus.Deleted; - staged = !secondPosition; - } - else - { - HandleUnexpected(line); - return; - } - - proc.SkipWhitespace(); - - path = proc.ReadToEnd().Trim('"'); - } - else if (proc.Matches('R')) - { - //R README.md -> README2.md - // R README.md -> README2.md - - proc.MoveNext(); - proc.SkipWhitespace(); - - var files = - proc.ReadToEnd() - .Split(new[] { "->" }, StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.Trim()) - .Select(s => s.Trim('"')) - .ToArray(); - - originalPath = files[0]; - path = files[1]; - status = GitFileStatus.Renamed; - staged = !secondPosition; - } - else if (proc.Matches('A')) - { - proc.MoveNext(); - if (proc.Matches('A') || proc.Matches('U')) - { - //AA deploy.cmd - unmerged, both added - //AU deploy.cmd - unmerged, added by us - - status = GitFileStatus.Unmerged; - } - else if (proc.IsAtWhitespace) - { - //A something added.txt - // A something added.txt - - status = GitFileStatus.Added; - staged = !secondPosition; - } - else - { - HandleUnexpected(line); - return; - } - - proc.SkipWhitespace(); - - path = proc.ReadToEnd().Trim('"'); - } - else if (proc.Matches('U')) - { - proc.MoveNext(); - if (proc.Matches('D') || proc.Matches('A') || proc.Matches('U')) - { - //UD deploy.cmd - unmerged, deleted by them - //UA deploy.cmd - unmerged, added by them - //UU deploy.cmd - unmerged, both modified - - status = GitFileStatus.Unmerged; - } - else - { - HandleUnexpected(line); - return; - } - - proc.SkipWhitespace(); - - path = proc.ReadToEnd().Trim('"'); - } - else - { - HandleUnexpected(line); - return; - } + path = proc.ReadToEnd().Trim().Trim('"'); } - var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry(path, status, originalPath, staged); + var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry(path, indexStatus, workTreeStatus, originalPath); gitStatus.Entries.Add(gitStatusEntry); } } @@ -278,9 +194,9 @@ private void HandleUnexpected(string line) Logger.Error("Unexpected Input:\"{0}\"", line); } - class StatusOutputPathComparer : IComparer + public class StatusOutputPathComparer : IComparer { - internal static StatusOutputPathComparer Instance => new StatusOutputPathComparer(); + public static StatusOutputPathComparer Instance => new StatusOutputPathComparer(); public int Compare(string x, string y) { diff --git a/src/GitHub.Api/OutputProcessors/WindowsDiskUsageOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/WindowsDiskUsageOutputProcessor.cs index 761b903f5..5de075701 100644 --- a/src/GitHub.Api/OutputProcessors/WindowsDiskUsageOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/WindowsDiskUsageOutputProcessor.cs @@ -1,13 +1,16 @@ using System; +using System.Text.RegularExpressions; namespace GitHub.Unity { - public class WindowsDiskUsageOutputProcessor : BaseOutputProcessor + public class WindowsDiskUsageOutputProcessor : BaseOutputProcessor { private int index = -1; private int lineCount = 0; private string[] buffer = new string[2]; - + // 199854 File(s) 25,835,841,045 bytes + private static readonly Regex totalFileCount = new Regex(@"[\s]*[\d]+[\s]+File\(s\)[\s]+(?[^\s]+)", + RegexOptions.Compiled); public override void LineReceived(string line) { lineCount++; @@ -24,14 +27,14 @@ public override void LineReceived(string line) Logger.Trace("Processing: {0}", output); - var proc = new LineParser(output); - proc.SkipWhitespace(); - proc.ReadUntilWhitespace(); - proc.ReadUntilWhitespace(); - proc.SkipWhitespace(); + var match = totalFileCount.Match(output); + long kilobytes = 0; + if (match.Success) + { + var bytes = long.Parse(match.Groups["bytes"].Value.Replace(",", String.Empty).Replace(".", String.Empty)); + kilobytes = bytes / 1024; + } - var bytes = int.Parse(proc.ReadUntilWhitespace().Replace(",", string.Empty)); - var kilobytes = bytes / 1024; RaiseOnEntry(kilobytes); } else @@ -40,4 +43,4 @@ public override void LineReceived(string line) } } } -} \ No newline at end of file +} diff --git a/src/GitHub.Api/Platform/WindowsDiskUsageTask.cs b/src/GitHub.Api/Platform/WindowsDiskUsageTask.cs index 75fd4ff32..d2fb89d12 100644 --- a/src/GitHub.Api/Platform/WindowsDiskUsageTask.cs +++ b/src/GitHub.Api/Platform/WindowsDiskUsageTask.cs @@ -3,7 +3,7 @@ namespace GitHub.Unity { - class WindowsDiskUsageTask : ProcessTask + class WindowsDiskUsageTask : ProcessTask { private readonly string arguments; @@ -19,4 +19,4 @@ public WindowsDiskUsageTask(NPath directory, CancellationToken token) public override TaskAffinity Affinity { get { return TaskAffinity.Concurrent; } } public override string Message { get; set; } = "Getting directory size..."; } -} \ No newline at end of file +} diff --git a/src/GitHub.Api/Tasks/ProcessTask.cs b/src/GitHub.Api/Tasks/ProcessTask.cs index aac238d89..66cb5a3f2 100644 --- a/src/GitHub.Api/Tasks/ProcessTask.cs +++ b/src/GitHub.Api/Tasks/ProcessTask.cs @@ -117,15 +117,22 @@ public void Run() { Process.OutputDataReceived += (s, e) => { - lastOutput = DateTimeOffset.UtcNow; - gotOutput.Set(); - if (e.Data != null) + try { - var line = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(e.Data)); - outputProcessor.LineReceived(line.TrimEnd('\r','\n')); + lastOutput = DateTimeOffset.UtcNow; + gotOutput.Set(); + if (e.Data != null) + { + var line = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(e.Data)); + outputProcessor.LineReceived(line.TrimEnd('\r', '\n')); + } + else + outputProcessor.LineReceived(null); + } + catch (Exception ex) + { + Logger.Error(ex); } - else - outputProcessor.LineReceived(null); }; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs index cd81fcfe2..9554e2b55 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs @@ -29,7 +29,7 @@ public GitStatusEntry GitStatusEntry } public string ProjectPath { get { return GitStatusEntry.projectPath; } } - public GitFileStatus GitFileStatus { get { return GitStatusEntry.status; } } + public GitFileStatus GitFileStatus { get { return GitStatusEntry.Status; } } } [Serializable] diff --git a/src/tests/IntegrationTests/IOTestsRepo.zip b/src/tests/IntegrationTests/IOTestsRepo.zip index 1b7560cd6..d44348f7b 100644 --- a/src/tests/IntegrationTests/IOTestsRepo.zip +++ b/src/tests/IntegrationTests/IOTestsRepo.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e8614b3fb2545993c4539dd3967df29072386c523d4707ec579a91a6a4efaf9 -size 296148 +oid sha256:b32bc4a54fa11844beacd90ff0d4cbf673b0fd720134197aab9f1f772c980c7b +size 296183 diff --git a/src/tests/IntegrationTests/IntegrationTests.csproj b/src/tests/IntegrationTests/IntegrationTests.csproj index 96ab7bcad..91f33f22c 100644 --- a/src/tests/IntegrationTests/IntegrationTests.csproj +++ b/src/tests/IntegrationTests/IntegrationTests.csproj @@ -74,7 +74,6 @@ - diff --git a/src/tests/IntegrationTests/Process/ProcessManagerIntegrationTests.cs b/src/tests/IntegrationTests/Process/ProcessManagerIntegrationTests.cs index 342d35088..f817a1ad7 100644 --- a/src/tests/IntegrationTests/Process/ProcessManagerIntegrationTests.cs +++ b/src/tests/IntegrationTests/Process/ProcessManagerIntegrationTests.cs @@ -35,7 +35,7 @@ public async Task LogEntriesTest() List logEntries = null; logEntries = await ProcessManager - .GetGitLogEntries(TestRepoMasterCleanUnsynchronized, Environment, GitEnvironment, 2) + .GetGitLogEntries(TestRepoMasterCleanUnsynchronized, Environment, 2) .StartAsAsync(); var firstCommitTime = new DateTimeOffset(2017, 1, 27, 17, 19, 32, TimeSpan.FromHours(-5)); @@ -53,7 +53,7 @@ public async Task LogEntriesTest() { new GitStatusEntry("Assets/TestDocument.txt".ToNPath(), TestRepoMasterCleanUnsynchronized + "/Assets/TestDocument.txt".ToNPath(), "Assets/TestDocument.txt".ToNPath(), - GitFileStatus.Renamed, "TestDocument.txt") + GitFileStatus.Renamed, GitFileStatus.None, "TestDocument.txt") }), new GitLogEntry("03939ffb3eb8486dba0259b43db00842bbe6eca1", @@ -66,7 +66,7 @@ public async Task LogEntriesTest() { new GitStatusEntry("TestDocument.txt".ToNPath(), TestRepoMasterCleanUnsynchronized + "/TestDocument.txt".ToNPath(), "TestDocument.txt".ToNPath(), - GitFileStatus.Added), + GitFileStatus.Added, GitFileStatus.None), }), }); } @@ -78,7 +78,7 @@ public async Task RussianLogEntriesTest() List logEntries = null; logEntries = await ProcessManager - .GetGitLogEntries(TestRepoMasterCleanUnsynchronizedRussianLanguage, Environment, GitEnvironment, 1) + .GetGitLogEntries(TestRepoMasterCleanUnsynchronizedRussianLanguage, Environment, 1) .StartAsAsync(); var commitTime = new DateTimeOffset(2017, 4, 20, 11, 47, 18, TimeSpan.FromHours(-4)); @@ -95,7 +95,7 @@ public async Task RussianLogEntriesTest() { new GitStatusEntry(@"Assets\A new file.txt".ToNPath(), TestRepoMasterCleanUnsynchronizedRussianLanguage + "/Assets/A new file.txt".ToNPath(), "Assets/A new file.txt".ToNPath(), - GitFileStatus.Added), + GitFileStatus.Added, GitFileStatus.None), }), }); } @@ -120,7 +120,7 @@ public async Task StatusTest() GitStatus? gitStatus = null; gitStatus = await ProcessManager - .GetGitStatus(TestRepoMasterDirtyUnsynchronized, Environment, GitEnvironment) + .GetGitStatus(TestRepoMasterDirtyUnsynchronized, Environment) .StartAsAsync(); gitStatus.Value.AssertEqual(new GitStatus() @@ -133,17 +133,17 @@ public async Task StatusTest() new GitStatusEntry("Assets/Added Document.txt".ToNPath(), TestRepoMasterDirtyUnsynchronized.Combine("Assets/Added Document.txt"), "Assets/Added Document.txt".ToNPath(), - GitFileStatus.Added, staged: true), + GitFileStatus.Added, GitFileStatus.None), new GitStatusEntry("Assets/Renamed TestDocument.txt".ToNPath(), TestRepoMasterDirtyUnsynchronized.Combine("Assets/Renamed TestDocument.txt"), "Assets/Renamed TestDocument.txt".ToNPath(), - GitFileStatus.Renamed, "Assets/TestDocument.txt".ToNPath(), true), + GitFileStatus.Renamed, GitFileStatus.None, "Assets/TestDocument.txt".ToNPath()), new GitStatusEntry("Assets/Untracked Document.txt".ToNPath(), TestRepoMasterDirtyUnsynchronized.Combine("Assets/Untracked Document.txt"), "Assets/Untracked Document.txt".ToNPath(), - GitFileStatus.Untracked), + GitFileStatus.Untracked, GitFileStatus.Untracked), } }); } @@ -154,7 +154,7 @@ public async Task CredentialHelperGetTest() InitializePlatformAndEnvironment(TestRepoMasterCleanSynchronized); await ProcessManager - .GetGitCreds(TestRepoMasterCleanSynchronized, Environment, GitEnvironment) + .GetGitCreds(TestRepoMasterCleanSynchronized) .StartAsAsync(); } } diff --git a/src/tests/IntegrationTests/ProcessManagerExtensions.cs b/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs similarity index 59% rename from src/tests/IntegrationTests/ProcessManagerExtensions.cs rename to src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs index 622006c8b..0a4c4703b 100644 --- a/src/tests/IntegrationTests/ProcessManagerExtensions.cs +++ b/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs @@ -4,7 +4,7 @@ using System.Threading; using System.Threading.Tasks; -namespace IntegrationTests +namespace TestUtils { static class ProcessManagerExtensions { @@ -15,47 +15,35 @@ public static ITask> GetGitBranches(this IProcessManager process NPath? gitPath = null) { var processor = new BranchListOutputProcessor(); - NPath path = gitPath ?? defaultGitPath; - return new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, "branch -vv", workingDirectory, false); + return new GitListLocalBranchesTask(CancellationToken.None, processor) + .Configure(processManager, gitPath ?? defaultGitPath, workingDirectory: workingDirectory); } public static ITask> GetGitLogEntries(this IProcessManager processManager, NPath workingDirectory, - IEnvironment environment, IProcessEnvironment gitEnvironment, - int? logCount = null, + IEnvironment environment, + int logCount = 0, NPath? gitPath = null) { var gitStatusEntryFactory = new GitObjectFactory(environment); var processor = new LogEntryOutputProcessor(gitStatusEntryFactory); - var logNameStatus = @"log --pretty=format:""%H%n%P%n%aN%n%aE%n%aI%n%cN%n%cE%n%cI%n%B---GHUBODYEND---"" --name-status"; - - if (logCount.HasValue) - { - logNameStatus = logNameStatus + " -" + logCount.Value; - } - - NPath path = gitPath ?? defaultGitPath; - - return new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, logNameStatus, workingDirectory, false); + return new GitLogTask(logCount, null, CancellationToken.None, processor) + .Configure(processManager, gitPath ?? defaultGitPath, workingDirectory: workingDirectory); } public static ITask GetGitStatus(this IProcessManager processManager, NPath workingDirectory, - IEnvironment environment, IProcessEnvironment gitEnvironment, + IEnvironment environment, NPath? gitPath = null) { var gitStatusEntryFactory = new GitObjectFactory(environment); var processor = new GitStatusOutputProcessor(gitStatusEntryFactory); - NPath path = gitPath ?? defaultGitPath; - - return new ProcessTask(CancellationToken.None, processor) - .Configure(processManager, path, "status -b -u --porcelain", workingDirectory, false); + return new GitStatusTask(null, CancellationToken.None, processor) + .Configure(processManager, workingDirectory: workingDirectory); } public static ITask> GetGitRemoteEntries(this IProcessManager processManager, @@ -64,15 +52,12 @@ public static ITask> GetGitRemoteEntries(this IProcessManager pr { var processor = new RemoteListOutputProcessor(); - NPath path = gitPath ?? defaultGitPath; - - return new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, "remote -v", workingDirectory, false); + return new GitRemoteListTask(CancellationToken.None, processor) + .Configure(processManager, gitPath ?? defaultGitPath, workingDirectory: workingDirectory); } public static ITask GetGitCreds(this IProcessManager processManager, NPath workingDirectory, - IEnvironment environment, IProcessEnvironment gitEnvironment, NPath? gitPath = null) { var processor = new FirstNonNullLineOutputProcessor(); diff --git a/src/tests/TestUtils/Substitutes/SubstituteFactory.cs b/src/tests/TestUtils/Substitutes/SubstituteFactory.cs index 29e1690cc..13e2b32cf 100644 --- a/src/tests/TestUtils/Substitutes/SubstituteFactory.cs +++ b/src/tests/TestUtils/Substitutes/SubstituteFactory.cs @@ -310,15 +310,14 @@ public IGitObjectFactory CreateGitObjectFactory(string gitRepoPath) { var gitObjectFactory = Substitute.For(); - gitObjectFactory.CreateGitStatusEntry(Args.String, Args.GitFileStatus, Args.String, Args.Bool) + gitObjectFactory.CreateGitStatusEntry(Args.String, Args.GitFileStatus, Args.GitFileStatus, Args.String) .Returns(info => { var path = (string)info[0]; - var status = (GitFileStatus)info[1]; - var originalPath = (string)info[2]; - var staged = (bool)info[3]; + var indexStatus = (GitFileStatus)info[1]; + var workTreeStatus = (GitFileStatus)info[2]; + var originalPath = (string)info[3]; - return new GitStatusEntry(path, gitRepoPath + @"\" + path, null, status, originalPath, - staged); + return new GitStatusEntry(path, gitRepoPath + @"\" + path, null, indexStatus, workTreeStatus, originalPath); }); return gitObjectFactory; diff --git a/src/tests/TestUtils/TestUtils.csproj b/src/tests/TestUtils/TestUtils.csproj index 8ae36c41d..bb3d2857f 100644 --- a/src/tests/TestUtils/TestUtils.csproj +++ b/src/tests/TestUtils/TestUtils.csproj @@ -62,6 +62,7 @@ + diff --git a/src/tests/TestWebServer/HttpServer.cs b/src/tests/TestWebServer/HttpServer.cs index 1693b6da4..d2c824b85 100644 --- a/src/tests/TestWebServer/HttpServer.cs +++ b/src/tests/TestWebServer/HttpServer.cs @@ -83,7 +83,7 @@ public void Start() var thread = new Thread(p => Process((HttpListenerContext)p)); thread.Start(context); } - catch (Exception ex) + catch (Exception) { break; } diff --git a/src/tests/UnitTests/IO/GitLogEntryListTests.cs b/src/tests/UnitTests/IO/GitLogEntryListTests.cs index 769559435..49c2f7187 100644 --- a/src/tests/UnitTests/IO/GitLogEntryListTests.cs +++ b/src/tests/UnitTests/IO/GitLogEntryListTests.cs @@ -87,7 +87,7 @@ public void ListOf1ShouldEqualListOf1() commitTime, commitTime, new List { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }, "MergeA", "MergeB") }; @@ -102,8 +102,7 @@ public void ListOf1ShouldEqualListOf1() commitTime, commitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }), "MergeA", "MergeB") }; @@ -126,7 +125,7 @@ public void ListOf2ShouldEqualListOf2() commitTime, commitTime, new List { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }, "MergeA", "MergeB"), new GitLogEntry("`CommitID", @@ -148,7 +147,7 @@ public void ListOf2ShouldEqualListOf2() "Description", commitTime, commitTime, new List { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, "SomeOriginalPath") + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath") }, "MergeA", "MergeB"), new GitLogEntry("`CommitID", @@ -181,8 +180,7 @@ public void ListOf2ShouldNotEqualListOf2InDifferentOrder() commitTime, commitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }), "MergeA", "MergeB"), new GitLogEntry("`CommitID", @@ -213,8 +211,7 @@ public void ListOf2ShouldNotEqualListOf2InDifferentOrder() otherCommitTime, otherCommitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }), "MergeA", "MergeB") }; @@ -222,4 +219,4 @@ public void ListOf2ShouldNotEqualListOf2InDifferentOrder() entries.AssertNotEqual(otherEntries); } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/IO/GitLogEntryTests.cs b/src/tests/UnitTests/IO/GitLogEntryTests.cs index 7d5d43b33..dd0e66940 100644 --- a/src/tests/UnitTests/IO/GitLogEntryTests.cs +++ b/src/tests/UnitTests/IO/GitLogEntryTests.cs @@ -89,7 +89,7 @@ public void ShouldEqualAnotherWhenChangesIsNotEmpty() commitTime, commitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, "SomeOriginalPath"), + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"), }), "MergeA", "MergeB"); @@ -101,8 +101,7 @@ public void ShouldEqualAnotherWhenChangesIsNotEmpty() commitTime, commitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath") + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added,GitFileStatus.None, "SomeOriginalPath") }), "MergeA", "MergeB"); @@ -122,8 +121,7 @@ public void ShouldNotEqualAnotherWhenChangesAreDifferent() commitTime, commitTime, new List(new[] { - new GitStatusEntry("ASDFASDF", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath"), + new GitStatusEntry("ASDFASDF", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added,GitFileStatus.None, "SomeOriginalPath"), }), "MergeA", "MergeB"); @@ -135,12 +133,11 @@ public void ShouldNotEqualAnotherWhenChangesAreDifferent() commitTime, commitTime, new List(new[] { - new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, - "SomeOriginalPath") + new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath") }), "MergeA", "MergeB"); gitLogEntry1.AssertNotEqual(gitLogEntry2); } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/IO/GitObjectFactoryTests.cs b/src/tests/UnitTests/IO/GitObjectFactoryTests.cs index 35c98d5cd..95cb8aa0d 100644 --- a/src/tests/UnitTests/IO/GitObjectFactoryTests.cs +++ b/src/tests/UnitTests/IO/GitObjectFactoryTests.cs @@ -23,7 +23,7 @@ public void ShouldParseNormalFile() environment.UnityProjectPath.Returns(@"c:\Projects\UnityProject".ToNPath()); var gitObjectFactory = new GitObjectFactory(environment); - var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry("hello.txt", GitFileStatus.Deleted); + var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry("hello.txt", GitFileStatus.None, GitFileStatus.Deleted); Assert.AreEqual(@"c:\Projects\UnityProject\hello.txt", gitStatusEntry.FullPath); } @@ -42,7 +42,7 @@ public void ShouldParseOddFile() environment.UnityProjectPath.Returns(@"c:\Projects\UnityProject".ToNPath()); var gitObjectFactory = new GitObjectFactory(environment); - var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry("c:UsersOculusGoVideo.mp4", GitFileStatus.Deleted); + var gitStatusEntry = gitObjectFactory.CreateGitStatusEntry("c:UsersOculusGoVideo.mp4", GitFileStatus.None, GitFileStatus.Deleted); Assert.AreEqual(@"c:\Projects\UnityProject\c:UsersOculusGoVideo.mp4", gitStatusEntry.FullPath); } diff --git a/src/tests/UnitTests/IO/GitStatusEntryFactoryTests.cs b/src/tests/UnitTests/IO/GitStatusEntryFactoryTests.cs index 78fe0482b..fd0a7e685 100644 --- a/src/tests/UnitTests/IO/GitStatusEntryFactoryTests.cs +++ b/src/tests/UnitTests/IO/GitStatusEntryFactoryTests.cs @@ -39,11 +39,11 @@ public void CreateObjectWhenProjectRootIsChildOfGitRootAndFileInGitRoot() var expectedFullPath = repositoryPath.Combine(inputPath); var expectedProjectPath = expectedFullPath.RelativeTo(unityProjectPath); - var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, inputStatus); + var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, GitFileStatus.None, inputStatus); var gitStatusEntryFactory = new GitObjectFactory(environment); - var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, inputStatus); + var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, GitFileStatus.None, inputStatus); result.Should().Be(expected); } @@ -69,11 +69,11 @@ public void CreateObjectWhenProjectRootIsChildOfGitRootAndFileInProjectRoot() var expectedFullPath = repositoryPath.Combine(inputPath); const string expectedProjectPath = "Something.sln"; - var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, inputStatus); + var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, GitFileStatus.None, inputStatus); var gitStatusEntryFactory = new GitObjectFactory(environment); - var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, inputStatus); + var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, GitFileStatus.None, inputStatus); result.Should().Be(expected); } @@ -99,13 +99,13 @@ public void CreateObjectWhenProjectRootIsSameAsGitRootAndFileInGitRoot() var expectedFullPath = repositoryPath.Combine(inputPath); const string expectedProjectPath = inputPath; - var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, inputStatus); + var expected = new GitStatusEntry(inputPath, expectedFullPath, expectedProjectPath, GitFileStatus.None, inputStatus); var gitStatusEntryFactory = new GitObjectFactory(environment); - var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, inputStatus); + var result = gitStatusEntryFactory.CreateGitStatusEntry(inputPath, GitFileStatus.None, inputStatus); result.Should().Be(expected); } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/IO/GitStatusEntryListTests.cs b/src/tests/UnitTests/IO/GitStatusEntryListTests.cs index bd2fbdf84..a38f7b503 100644 --- a/src/tests/UnitTests/IO/GitStatusEntryListTests.cs +++ b/src/tests/UnitTests/IO/GitStatusEntryListTests.cs @@ -13,19 +13,19 @@ public void ListOf2ShouldEqualListOf2() var gitStatusEntry1 = new[] { new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"), + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"), new GitStatusEntry("ASDFSomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Modified) + GitFileStatus.None, GitFileStatus.Modified) }; var gitStatusEntry2 = new[] { new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"), + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"), new GitStatusEntry("ASDFSomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Modified) + GitFileStatus.None, GitFileStatus.Modified) }; gitStatusEntry1.AssertEqual(gitStatusEntry2); @@ -37,22 +37,22 @@ public void ListOf2ShouldNotEqualListOf2InDifferentOrder() var gitStatusEntry1 = new[] { new GitStatusEntry("ASDFSomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Modified), + GitFileStatus.None, GitFileStatus.Modified), new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath") + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath") }; var gitStatusEntry2 = new[] { new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"), + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"), new GitStatusEntry("ASDFSomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Modified) + GitFileStatus.None, GitFileStatus.Modified) }; gitStatusEntry1.AssertNotEqual(gitStatusEntry2); } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/IO/GitStatusEntryTests.cs b/src/tests/UnitTests/IO/GitStatusEntryTests.cs index c7fff8c4f..4c0d57904 100644 --- a/src/tests/UnitTests/IO/GitStatusEntryTests.cs +++ b/src/tests/UnitTests/IO/GitStatusEntryTests.cs @@ -12,22 +12,31 @@ public class GitStatusEntryTests public void ShouldNotBeEqualIfGitFileStatusIsDifferent() { var gitStatusEntry1 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"); var gitStatusEntry2 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Modified, "SomeOriginalPath"); + GitFileStatus.None, GitFileStatus.Modified, "SomeOriginalPath"); gitStatusEntry1.Should().NotBe(gitStatusEntry2); + + gitStatusEntry1 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Modified, GitFileStatus.Added, "SomeOriginalPath"); + + gitStatusEntry2 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Renamed, GitFileStatus.Modified, "SomeOriginalPath"); + + gitStatusEntry1.Should().NotBe(gitStatusEntry2); + } [Test] public void ShouldNotBeEqualIfPathIsDifferent() { var gitStatusEntry1 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"); var gitStatusEntry2 = new GitStatusEntry("SomePath2", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"); gitStatusEntry1.Should().NotBe(gitStatusEntry2); } @@ -36,7 +45,7 @@ public void ShouldNotBeEqualIfPathIsDifferent() public void ShouldBeEqualIfOriginalpathIsNull() { var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added); + GitFileStatus.None, GitFileStatus.Added); gitStatusEntry.Should().Be(gitStatusEntry); } @@ -45,7 +54,7 @@ public void ShouldBeEqualIfOriginalpathIsNull() public void ShouldBeEqual() { var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); gitStatusEntry.Should().Be(gitStatusEntry); } @@ -54,10 +63,10 @@ public void ShouldBeEqual() public void ShouldBeEqualToOther() { var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); var gitStatusEntry2 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); gitStatusEntry.Should().Be(gitStatusEntry2); } @@ -66,10 +75,10 @@ public void ShouldBeEqualToOther() public void ShouldNotBeEqualIfOneIsStaged() { var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath", staged: true); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); var gitStatusEntry2 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath"); + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"); gitStatusEntry.Should().NotBe(gitStatusEntry2); } @@ -78,12 +87,92 @@ public void ShouldNotBeEqualIfOneIsStaged() public void ShouldBeEqualIfBothAreStaged() { var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath", true); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); var gitStatusEntry2 = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", - GitFileStatus.Added, "SomeOriginalPath", true); + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); gitStatusEntry.Should().Be(gitStatusEntry2); } + + [Test] + public void StagedIsTrue() + { + var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Added, GitFileStatus.None, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Modified, GitFileStatus.None, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Deleted, GitFileStatus.None, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Copied, GitFileStatus.None, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Renamed, GitFileStatus.None, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeTrue(); + } + + [Test] + public void StagedIsFalse() + { + var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.None, GitFileStatus.Added, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.None, GitFileStatus.Modified, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.None, GitFileStatus.Deleted, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.None, GitFileStatus.Copied, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.None, GitFileStatus.Renamed, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + } + + [Test] + public void UnmergedDetection() + { + var gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Added, GitFileStatus.Added, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Deleted, GitFileStatus.Deleted, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Unmerged, GitFileStatus.Unmerged, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Added, GitFileStatus.Unmerged, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Unmerged, GitFileStatus.Added, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Deleted, GitFileStatus.Unmerged, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Unmerged, GitFileStatus.Deleted, "SomeOriginalPath"); + gitStatusEntry.Unmerged.Should().BeTrue(); + } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/IO/LogEntryOutputProcessorTests.cs b/src/tests/UnitTests/IO/LogEntryOutputProcessorTests.cs index 347ea565b..f613210c4 100644 --- a/src/tests/UnitTests/IO/LogEntryOutputProcessorTests.cs +++ b/src/tests/UnitTests/IO/LogEntryOutputProcessorTests.cs @@ -54,7 +54,7 @@ public void ShouldParseSingleCommit() { new GitStatusEntry("src/GitHub.App/Models/RemoteRepositoryModel.cs", TestRootPath + @"\src/GitHub.App/Models/RemoteRepositoryModel.cs", null, - GitFileStatus.Modified), + GitFileStatus.Modified, GitFileStatus.None), }) }; @@ -97,7 +97,7 @@ public void ShouldParseSummaryAndDescription() { new GitStatusEntry("src/GitHub.App/Models/RemoteRepositoryModel.cs", TestRootPath + @"\src/GitHub.App/Models/RemoteRepositoryModel.cs", null, - GitFileStatus.Modified), + GitFileStatus.Modified, GitFileStatus.None), }) }; @@ -142,7 +142,7 @@ public void ShouldParseSummaryAndDescriptionWithExtraNewLines() { new GitStatusEntry("src/GitHub.App/Models/RemoteRepositoryModel.cs", TestRootPath + @"\src/GitHub.App/Models/RemoteRepositoryModel.cs", null, - GitFileStatus.Modified), + GitFileStatus.Modified, GitFileStatus.None), }) }; diff --git a/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs b/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs index f40377f8a..61fefa82f 100644 --- a/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs +++ b/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs @@ -1,5 +1,6 @@ using TestUtils; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using GitHub.Unity; @@ -28,12 +29,12 @@ public void ShouldParseDirtyWorkingTreeUntracked() LocalBranch = "master", Entries = new List { - new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.Deleted), - new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.Modified), - new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, "README.md", true), - new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, staged: true), - new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked), - } + new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.None, GitFileStatus.Modified), + new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, GitFileStatus.None, "README.md"), + new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.None, GitFileStatus.Deleted), + new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, GitFileStatus.None), + new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -58,14 +59,14 @@ public void ShouldParseUnmergedStates() LocalBranch = "master", Entries = new List { - new GitStatusEntry("something1.txt", TestRootPath + @"\something1.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something2.txt", TestRootPath + @"\something2.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something3.txt", TestRootPath + @"\something3.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something4.txt", TestRootPath + @"\something4.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something5.txt", TestRootPath + @"\something5.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something6.txt", TestRootPath + @"\something6.txt", null, GitFileStatus.Unmerged), - new GitStatusEntry("something7.txt", TestRootPath + @"\something7.txt", null, GitFileStatus.Unmerged), - } + new GitStatusEntry("something1.txt", TestRootPath + @"\something1.txt", null, GitFileStatus.Deleted, GitFileStatus.Deleted), + new GitStatusEntry("something2.txt", TestRootPath + @"\something2.txt", null, GitFileStatus.Added, GitFileStatus.Unmerged), + new GitStatusEntry("something3.txt", TestRootPath + @"\something3.txt", null, GitFileStatus.Unmerged, GitFileStatus.Deleted), + new GitStatusEntry("something4.txt", TestRootPath + @"\something4.txt", null, GitFileStatus.Unmerged, GitFileStatus.Added), + new GitStatusEntry("something5.txt", TestRootPath + @"\something5.txt", null, GitFileStatus.Deleted, GitFileStatus.Unmerged), + new GitStatusEntry("something6.txt", TestRootPath + @"\something6.txt", null, GitFileStatus.Added, GitFileStatus.Added), + new GitStatusEntry("something7.txt", TestRootPath + @"\something7.txt", null, GitFileStatus.Unmerged, GitFileStatus.Unmerged), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -91,12 +92,12 @@ public void ShouldParseDirtyWorkingTreeTrackedAhead1Behind1() Behind = 1, Entries = new List { - new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.Deleted), - new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.Modified), - new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, "README.md", true), - new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, staged: true), - new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked), - } + new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.None, GitFileStatus.Modified), + new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, GitFileStatus.None, "README.md"), + new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.None, GitFileStatus.Deleted), + new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, GitFileStatus.None), + new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -121,12 +122,12 @@ public void ShouldParseDirtyWorkingTreeTrackedAhead1() Ahead = 1, Entries = new List { - new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.Deleted), - new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.Modified), - new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, "README.md", true), - new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, staged: true), - new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked), - } + new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.None, GitFileStatus.Modified), + new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, GitFileStatus.None, "README.md"), + new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.None, GitFileStatus.Deleted), + new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, GitFileStatus.None), + new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -151,12 +152,12 @@ public void ShouldParseDirtyWorkingTreeTrackedBehind1() Behind = 1, Entries = new List { - new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.Deleted), - new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.Modified), - new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, "README.md", true), - new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, staged: true), - new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked), - } + new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.None, GitFileStatus.Modified), + new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, GitFileStatus.None, "README.md"), + new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.None, GitFileStatus.Deleted), + new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, GitFileStatus.None), + new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -180,12 +181,12 @@ public void ShouldParseDirtyWorkingTreeTracked() RemoteBranch = "origin/master", Entries = new List { - new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.Deleted), - new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.Modified), - new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, "README.md", true), - new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, staged: true), - new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked), - } + new GitStatusEntry("GitHubVS.sln", TestRootPath + @"\GitHubVS.sln", null, GitFileStatus.None, GitFileStatus.Modified), + new GitStatusEntry("README2.md", TestRootPath + @"\README2.md", null, GitFileStatus.Renamed, GitFileStatus.None, "README.md"), + new GitStatusEntry("deploy.cmd", TestRootPath + @"\deploy.cmd", null, GitFileStatus.None, GitFileStatus.Deleted), + new GitStatusEntry("something added.txt", TestRootPath + @"\something added.txt", null, GitFileStatus.Added, GitFileStatus.None), + new GitStatusEntry("something.txt", TestRootPath + @"\something.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + }.OrderBy(entry => entry.Path, GitStatusOutputProcessor.StatusOutputPathComparer.Instance).ToList() }); } @@ -302,17 +303,17 @@ public void ShouldSortOutputCorrectly() LocalBranch = "master", Entries = new List { - new GitStatusEntry(@"Assets/Assets.Test.dll", TestRootPath + @"\Assets/Assets.Test.dll", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Assets/Assets.Test.dll.meta", TestRootPath + @"\Assets/Assets.Test.dll.meta", null, GitFileStatus.Untracked), - new GitStatusEntry(@"blah.txt", TestRootPath + @"\blah.txt", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity.dll", TestRootPath + @"\Plugins/GitHub.Unity.dll", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity.dll.meta", TestRootPath + @"\Plugins/GitHub.Unity.dll.meta", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity.dll.mdb", TestRootPath + @"\Plugins/GitHub.Unity.dll.mdb", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity.dll.mdb.meta", TestRootPath + @"\Plugins/GitHub.Unity.dll.mdb.meta", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity2.dll", TestRootPath + @"\Plugins/GitHub.Unity2.dll", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.meta", TestRootPath + @"\Plugins/GitHub.Unity2.dll.meta", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.mdb", TestRootPath + @"\Plugins/GitHub.Unity2.dll.mdb", null, GitFileStatus.Untracked), - new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.mdb.meta", TestRootPath + @"\Plugins/GitHub.Unity2.dll.mdb.meta", null, GitFileStatus.Untracked), + new GitStatusEntry(@"Assets/Assets.Test.dll", TestRootPath + @"\Assets/Assets.Test.dll", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Assets/Assets.Test.dll.meta", TestRootPath + @"\Assets/Assets.Test.dll.meta", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"blah.txt", TestRootPath + @"\blah.txt", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity.dll", TestRootPath + @"\Plugins/GitHub.Unity.dll", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity.dll.meta", TestRootPath + @"\Plugins/GitHub.Unity.dll.meta", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity.dll.mdb", TestRootPath + @"\Plugins/GitHub.Unity.dll.mdb", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity.dll.mdb.meta", TestRootPath + @"\Plugins/GitHub.Unity.dll.mdb.meta", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity2.dll", TestRootPath + @"\Plugins/GitHub.Unity2.dll", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.meta", TestRootPath + @"\Plugins/GitHub.Unity2.dll.meta", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.mdb", TestRootPath + @"\Plugins/GitHub.Unity2.dll.mdb", null, GitFileStatus.Untracked, GitFileStatus.Untracked), + new GitStatusEntry(@"Plugins/GitHub.Unity2.dll.mdb.meta", TestRootPath + @"\Plugins/GitHub.Unity2.dll.mdb.meta", null, GitFileStatus.Untracked, GitFileStatus.Untracked), } }); } diff --git a/src/tests/UnitTests/IO/WindowsDiskUsageOutputProcessorTests.cs b/src/tests/UnitTests/IO/WindowsDiskUsageOutputProcessorTests.cs index 5e1a327e8..860f7cdfd 100644 --- a/src/tests/UnitTests/IO/WindowsDiskUsageOutputProcessorTests.cs +++ b/src/tests/UnitTests/IO/WindowsDiskUsageOutputProcessorTests.cs @@ -48,7 +48,7 @@ public void WindowsDiskUsageOutput() private void AssertProcessOutput(IEnumerable lines, int expected) { - int? result = null; + long? result = null; var outputProcessor = new WindowsDiskUsageOutputProcessor(); outputProcessor.OnEntry += status => { result = status; }; @@ -61,4 +61,4 @@ private void AssertProcessOutput(IEnumerable lines, int expected) Assert.AreEqual(expected, result.Value); } } -} \ No newline at end of file +} diff --git a/src/tests/UnitTests/ProcessManagerExtensions.cs b/src/tests/UnitTests/ProcessManagerExtensions.cs deleted file mode 100644 index c4043551f..000000000 --- a/src/tests/UnitTests/ProcessManagerExtensions.cs +++ /dev/null @@ -1,109 +0,0 @@ -using GitHub.Unity; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace UnitTests -{ - static class ProcessManagerExtensions - { - static NPath defaultGitPath = "git".ToNPath(); - - public static async Task> GetGitBranches(this ProcessManager processManager, - NPath workingDirectory, - NPath? gitPath = null) - { - var processor = new BranchListOutputProcessor(); - NPath path = gitPath ?? defaultGitPath; - - var results = await new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, "branch -vv", workingDirectory, false) - .Start() - .Task; - - return results; - } - - public static async Task> GetGitLogEntries(this ProcessManager processManager, - NPath workingDirectory, - IEnvironment environment, IFileSystem filesystem, IProcessEnvironment gitEnvironment, - int? logCount = null, - NPath? gitPath = null) - { - var gitStatusEntryFactory = new GitObjectFactory(environment); - - var processor = new LogEntryOutputProcessor(gitStatusEntryFactory); - - var logNameStatus = @"log --pretty=format:""%H%n%P%n%aN%n%aE%n%aI%n%cN%n%cE%n%cI%n%B---GHUBODYEND---"" --name-status"; - - if (logCount.HasValue) - { - logNameStatus = logNameStatus + " -" + logCount.Value; - } - - NPath path = gitPath ?? defaultGitPath; - - var results = await new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, logNameStatus, workingDirectory, false) - .Start() - .Task; - - return results; - } - - public static async Task GetGitStatus(this ProcessManager processManager, - NPath workingDirectory, - IEnvironment environment, IFileSystem filesystem, IProcessEnvironment gitEnvironment, - NPath? gitPath = null) - { - var gitStatusEntryFactory = new GitObjectFactory(environment); - var processor = new GitStatusOutputProcessor(gitStatusEntryFactory); - - NPath path = gitPath ?? defaultGitPath; - - var results = await new ProcessTask(CancellationToken.None, processor) - .Configure(processManager, path, "status -b -u --porcelain", workingDirectory, false) - .Start() - .Task; - - return results; - } - - public static async Task> GetGitRemoteEntries(this ProcessManager processManager, - NPath workingDirectory, - NPath? gitPath = null) - { - var processor = new RemoteListOutputProcessor(); - - NPath path = gitPath ?? defaultGitPath; - - var results = await new ProcessTaskWithListOutput(CancellationToken.None, processor) - .Configure(processManager, path, "remote -v", workingDirectory, false) - .Start() - .Task; - return results; - } - - public static async Task GetGitCreds(this ProcessManager processManager, - NPath workingDirectory, - IEnvironment environment, IFileSystem filesystem, IProcessEnvironment gitEnvironment, - NPath? gitPath = null) - { - var processor = new FirstNonNullLineOutputProcessor(); - - NPath path = gitPath ?? defaultGitPath; - - var task = new ProcessTask(CancellationToken.None, processor) - .Configure(processManager, path, "credential-wincred get", workingDirectory, true); - - task.OnStartProcess += p => - { - p.StandardInput.WriteLine("protocol=https"); - p.StandardInput.WriteLine("host=github.com"); - p.StandardInput.Close(); - }; - return await task.StartAsAsync(); - } - } -} diff --git a/src/tests/UnitTests/UnitTests.csproj b/src/tests/UnitTests/UnitTests.csproj index e172e1b74..20f755fe7 100644 --- a/src/tests/UnitTests/UnitTests.csproj +++ b/src/tests/UnitTests/UnitTests.csproj @@ -98,7 +98,6 @@ - From f75709c1519ec0ac1f52e812cd4132449a663b36 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 14 Jun 2019 18:06:44 +0200 Subject: [PATCH 2/5] Bump version to 1.4, since there's new API and stuff --- common/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/SolutionInfo.cs b/common/SolutionInfo.cs index 8f30da468..eb95db6a0 100644 --- a/common/SolutionInfo.cs +++ b/common/SolutionInfo.cs @@ -31,7 +31,7 @@ namespace System { internal static class AssemblyVersionInformation { - private const string GitHubForUnityVersion = "1.3.2"; + private const string GitHubForUnityVersion = "1.4.0"; internal const string VersionForAssembly = GitHubForUnityVersion; // If this is an alpha, beta or other pre-release, mark it as such as shown below From 76732e7c72ecde4932f4aebd4bc1b6c7f0d88bd8 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 14 Jun 2019 18:11:50 +0200 Subject: [PATCH 3/5] Bleh --- src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs b/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs index 0a4c4703b..aa09e5b55 100644 --- a/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs +++ b/src/tests/TestUtils/Helpers/ProcessManagerExtensions.cs @@ -3,6 +3,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using GitHub.Unity.Git.Tasks; namespace TestUtils { From 12f4d61043c665bd05627feb1754aceb3a3ff24a Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 17 Jun 2019 09:34:48 +0200 Subject: [PATCH 4/5] Add more GitStatusEntry tests --- src/tests/UnitTests/IO/GitStatusEntryTests.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests/UnitTests/IO/GitStatusEntryTests.cs b/src/tests/UnitTests/IO/GitStatusEntryTests.cs index 4c0d57904..fa6566b11 100644 --- a/src/tests/UnitTests/IO/GitStatusEntryTests.cs +++ b/src/tests/UnitTests/IO/GitStatusEntryTests.cs @@ -141,6 +141,18 @@ public void StagedIsFalse() gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", GitFileStatus.None, GitFileStatus.Renamed, "SomeOriginalPath"); gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Untracked, GitFileStatus.Untracked, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Ignored, GitFileStatus.Ignored, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); + + gitStatusEntry = new GitStatusEntry("SomePath", "SomeFullPath", "SomeProjectPath", + GitFileStatus.Unmerged, GitFileStatus.Added, "SomeOriginalPath"); + gitStatusEntry.Staged.Should().BeFalse(); } [Test] From 6f752a96d78f4448ab95e6d6a626287723904818 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 17 Jun 2019 09:40:50 +0200 Subject: [PATCH 5/5] Fix Staged calculation --- src/GitHub.Api/Git/GitStatusEntry.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/GitHub.Api/Git/GitStatusEntry.cs b/src/GitHub.Api/Git/GitStatusEntry.cs index b20c3efa8..8ba7c6d58 100644 --- a/src/GitHub.Api/Git/GitStatusEntry.cs +++ b/src/GitHub.Api/Git/GitStatusEntry.cs @@ -134,11 +134,14 @@ public static GitFileStatus ParseStatusMarker(char changeFlag) public GitFileStatus IndexStatus => indexStatus; public GitFileStatus WorkTreeStatus => workTreeStatus; - public bool Staged => indexStatus != GitFileStatus.None; + public bool Staged => indexStatus != GitFileStatus.None && !Unmerged && !Untracked && !Ignored; public bool Unmerged => (indexStatus == workTreeStatus && (indexStatus == GitFileStatus.Added || indexStatus == GitFileStatus.Deleted)) || indexStatus == GitFileStatus.Unmerged || workTreeStatus == GitFileStatus.Unmerged; + public bool Untracked => workTreeStatus == GitFileStatus.Untracked; + public bool Ignored => workTreeStatus == GitFileStatus.Ignored; + public override string ToString() { return $"Path:'{Path}' Status:'{Status}' FullPath:'{FullPath}' ProjectPath:'{ProjectPath}' OriginalPath:'{OriginalPath}' Staged:'{Staged}' Unmerged:'{Unmerged}' Status:'{IndexStatus}' Status:'{WorkTreeStatus}' ";