diff --git a/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs b/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs index 99f11ebe3..3cbb45a65 100644 --- a/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs +++ b/src/GitHub.Api/OutputProcessors/StatusOutputProcessor.cs @@ -120,13 +120,11 @@ public override void LineReceived(string line) } else { + var secondPosition = false; if (proc.IsAtWhitespace) { proc.SkipWhitespace(); - } - else - { - staged = true; + secondPosition = true; } if (proc.Matches('M')) @@ -137,19 +135,42 @@ public override void LineReceived(string line) path = proc.ReadToEnd().Trim('"'); status = GitFileStatus.Modified; + staged = !secondPosition; } else if (proc.Matches('D')) { - //D deploy.cmd 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('"'); - status = GitFileStatus.Deleted; } else if (proc.Matches('R')) { //R README.md -> README2.md + // R README.md -> README2.md + proc.MoveNext(); proc.SkipWhitespace(); @@ -163,19 +184,61 @@ public override void LineReceived(string line) originalPath = files[0]; path = files[1]; status = GitFileStatus.Renamed; + staged = !secondPosition; } else if (proc.Matches('A')) { - //A something added.txt 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('"'); - status = GitFileStatus.Added; } else { HandleUnexpected(line); + return; } } diff --git a/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs b/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs index 299ce511a..f40377f8a 100644 --- a/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs +++ b/src/tests/UnitTests/IO/StatusOutputProcessorTests.cs @@ -37,6 +37,38 @@ public void ShouldParseDirtyWorkingTreeUntracked() }); } + [Test] + public void ShouldParseUnmergedStates() + { + var output = new[] + { + "## master", + "DD something1.txt", + "AU something2.txt", + "UD something3.txt", + "UA something4.txt", + "DU something5.txt", + "AA something6.txt", + "UU something7.txt", + null + }; + + AssertProcessOutput(output, new GitStatus + { + 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), + } + }); + } + [Test] public void ShouldParseDirtyWorkingTreeTrackedAhead1Behind1() {