Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 4bb82dd

Browse files
committed
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.
1 parent 2802e84 commit 4bb82dd

35 files changed

+498
-559
lines changed

src/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,5 @@ sysinfo.txt
312312
# Builds
313313
*.apk
314314
*.unitypackage
315-
UnityExtension/**/manifest.json
315+
UnityExtension/**/manifest.json
316+
tests/IntegrationTests/IOTestsRepo/

src/GitHub.Api/Git/GitObjectFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ public GitObjectFactory(IEnvironment environment)
1212
this.environment = environment;
1313
}
1414

15-
public GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus status, string originalPath = null, bool staged = false)
15+
public GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus indexStatus, GitFileStatus workTreeStatus = GitFileStatus.None, string originalPath = null)
1616
{
1717
var absolutePath = new NPath(path).MakeAbsolute();
1818
var relativePath = absolutePath.RelativeTo(environment.RepositoryPath);
1919
var projectPath = absolutePath.RelativeTo(environment.UnityProjectPath);
2020

21-
return new GitStatusEntry(relativePath, absolutePath, projectPath, status, originalPath?.ToNPath(), staged);
21+
return new GitStatusEntry(relativePath, absolutePath, projectPath, indexStatus, workTreeStatus, originalPath?.ToNPath());
2222
}
2323
}
2424
}

src/GitHub.Api/Git/GitStatusEntry.cs

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@ public struct GitStatusEntry
1111
public string fullPath;
1212
public string projectPath;
1313
public string originalPath;
14-
public GitFileStatus status;
15-
public bool staged;
14+
public GitFileStatus indexStatus;
15+
public GitFileStatus workTreeStatus;
1616

17-
public GitStatusEntry(string path, string fullPath, string projectPath, GitFileStatus status,
18-
string originalPath = null, bool staged = false)
17+
public GitStatusEntry(string path, string fullPath, string projectPath,
18+
GitFileStatus indexStatus, GitFileStatus workTreeStatus,
19+
string originalPath = null)
1920
{
2021
Guard.ArgumentNotNullOrWhiteSpace(path, "path");
2122
Guard.ArgumentNotNullOrWhiteSpace(fullPath, "fullPath");
2223

2324
this.path = path;
24-
this.status = status;
25+
this.indexStatus = indexStatus;
26+
this.workTreeStatus = workTreeStatus;
2527
this.fullPath = fullPath;
2628
this.projectPath = projectPath;
2729
this.originalPath = originalPath;
28-
this.staged = staged;
2930
}
3031

3132
public override int GetHashCode()
@@ -35,8 +36,8 @@ public override int GetHashCode()
3536
hash = hash * 23 + (fullPath?.GetHashCode() ?? 0);
3637
hash = hash * 23 + (projectPath?.GetHashCode() ?? 0);
3738
hash = hash * 23 + (originalPath?.GetHashCode() ?? 0);
38-
hash = hash * 23 + status.GetHashCode();
39-
hash = hash * 23 + staged.GetHashCode();
39+
hash = hash * 23 + indexStatus.GetHashCode();
40+
hash = hash * 23 + workTreeStatus.GetHashCode();
4041
return hash;
4142
}
4243

@@ -54,8 +55,8 @@ public bool Equals(GitStatusEntry other)
5455
String.Equals(fullPath, other.fullPath) &&
5556
String.Equals(projectPath, other.projectPath) &&
5657
String.Equals(originalPath, other.originalPath) &&
57-
status == other.status &&
58-
staged == other.staged
58+
indexStatus == other.indexStatus &&
59+
workTreeStatus == other.workTreeStatus
5960
;
6061
}
6162

@@ -78,6 +79,49 @@ public bool Equals(GitStatusEntry other)
7879
return !(lhs == rhs);
7980
}
8081

82+
public static GitFileStatus ParseStatusMarker(char changeFlag)
83+
{
84+
GitFileStatus status = GitFileStatus.None;
85+
switch (changeFlag)
86+
{
87+
case 'M':
88+
status = GitFileStatus.Modified;
89+
break;
90+
case 'A':
91+
status = GitFileStatus.Added;
92+
break;
93+
case 'D':
94+
status = GitFileStatus.Deleted;
95+
break;
96+
case 'R':
97+
status = GitFileStatus.Renamed;
98+
break;
99+
case 'C':
100+
status = GitFileStatus.Copied;
101+
break;
102+
case 'U':
103+
status = GitFileStatus.Unmerged;
104+
break;
105+
case 'T':
106+
status = GitFileStatus.TypeChange;
107+
break;
108+
case 'X':
109+
status = GitFileStatus.Unknown;
110+
break;
111+
case 'B':
112+
status = GitFileStatus.Broken;
113+
break;
114+
case '?':
115+
status = GitFileStatus.Untracked;
116+
break;
117+
case '!':
118+
status = GitFileStatus.Ignored;
119+
break;
120+
default: break;
121+
}
122+
return status;
123+
}
124+
81125
public string Path => path;
82126

83127
public string FullPath => fullPath;
@@ -86,13 +130,18 @@ public bool Equals(GitStatusEntry other)
86130

87131
public string OriginalPath => originalPath;
88132

89-
public GitFileStatus Status => status;
133+
public GitFileStatus Status => workTreeStatus != GitFileStatus.None ? workTreeStatus : indexStatus;
134+
public GitFileStatus IndexStatus => indexStatus;
135+
public GitFileStatus WorkTreeStatus => workTreeStatus;
136+
137+
public bool Staged => indexStatus != GitFileStatus.None;
90138

91-
public bool Staged => staged;
139+
public bool Unmerged => (indexStatus == workTreeStatus && (indexStatus == GitFileStatus.Added || indexStatus == GitFileStatus.Deleted)) ||
140+
indexStatus == GitFileStatus.Unmerged || workTreeStatus == GitFileStatus.Unmerged;
92141

93142
public override string ToString()
94143
{
95-
return $"Path:'{Path}' Status:'{Status}' FullPath:'{FullPath}' ProjectPath:'{ProjectPath}' OriginalPath:'{OriginalPath}' Staged:'{Staged}'";
144+
return $"Path:'{Path}' Status:'{Status}' FullPath:'{FullPath}' ProjectPath:'{ProjectPath}' OriginalPath:'{OriginalPath}' Staged:'{Staged}' Unmerged:'{Unmerged}' Status:'{IndexStatus}' Status:'{WorkTreeStatus}' ";
96145
}
97146
}
98147
}

src/GitHub.Api/Git/IGitObjectFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ namespace GitHub.Unity
22
{
33
public interface IGitObjectFactory
44
{
5-
GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus status, string originalPath = null, bool staged = false);
5+
GitStatusEntry CreateGitStatusEntry(string path, GitFileStatus indexStatus, GitFileStatus workTreeStatus, string originalPath = null);
66
}
77
}

src/GitHub.Api/Git/RepositoryManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries)
317317

318318
foreach (var gitStatusEntry in gitStatusEntries)
319319
{
320-
if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked)
320+
if (gitStatusEntry.WorkTreeStatus == GitFileStatus.Added || gitStatusEntry.WorkTreeStatus == GitFileStatus.Untracked)
321321
{
322322
itemsToDelete.Add(gitStatusEntry.path.ToNPath().MakeAbsolute());
323323
}

src/GitHub.Api/Git/Tasks/GitLogTask.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,39 @@ public class GitLogTask : ProcessTaskWithListOutput<GitLogEntry>
99
private readonly string arguments;
1010

1111
public GitLogTask(IGitObjectFactory gitObjectFactory,
12+
CancellationToken token,
13+
BaseOutputListProcessor<GitLogEntry> processor = null)
14+
: this(0, gitObjectFactory, token, processor)
15+
{
16+
}
17+
18+
public GitLogTask(string file,
19+
IGitObjectFactory gitObjectFactory,
1220
CancellationToken token, BaseOutputListProcessor<GitLogEntry> processor = null)
21+
: this(file, 0, gitObjectFactory, token, processor)
22+
{
23+
}
24+
25+
public GitLogTask(int numberOfCommits, IGitObjectFactory gitObjectFactory,
26+
CancellationToken token,
27+
BaseOutputListProcessor<GitLogEntry> processor = null)
1328
: base(token, processor ?? new LogEntryOutputProcessor(gitObjectFactory))
1429
{
1530
Name = TaskName;
1631
arguments = baseArguments;
32+
if (numberOfCommits > 0)
33+
arguments += " -n " + numberOfCommits;
1734
}
1835

19-
public GitLogTask(string file,
36+
public GitLogTask(string file, int numberOfCommits,
2037
IGitObjectFactory gitObjectFactory,
2138
CancellationToken token, BaseOutputListProcessor<GitLogEntry> processor = null)
2239
: base(token, processor ?? new LogEntryOutputProcessor(gitObjectFactory))
2340
{
2441
Name = TaskName;
2542
arguments = baseArguments;
43+
if (numberOfCommits > 0)
44+
arguments += " -n " + numberOfCommits;
2645
arguments += " -- ";
2746
arguments += " \"" + file + "\"";
2847
}

src/GitHub.Api/Git/Tasks/GitStatusTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public GitStatusTask(IGitObjectFactory gitObjectFactory,
1515

1616
public override string ProcessArguments
1717
{
18-
get { return "-c i18n.logoutputencoding=utf8 -c core.quotepath=false status -b -u --porcelain"; }
18+
get { return "-c i18n.logoutputencoding=utf8 -c core.quotepath=false --no-optional-locks status -b -u --porcelain"; }
1919
}
2020
public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } }
2121
public override string Message { get; set; } = "Listing changed files...";

src/GitHub.Api/OutputProcessors/BranchListOutputProcessor.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Security.AccessControl;
23
using System.Text.RegularExpressions;
34

45
namespace GitHub.Unity
@@ -18,23 +19,24 @@ public override void LineReceived(string line)
1819

1920
try
2021
{
21-
proc.Matches('*');
22+
string name;
23+
string trackingName = null;
24+
25+
if (proc.Matches('*'))
26+
proc.MoveNext();
2227
proc.SkipWhitespace();
23-
var detached = proc.Matches("(HEAD ");
24-
var name = "detached";
25-
if (detached)
28+
if (proc.Matches("(HEAD "))
2629
{
30+
name = "detached";
2731
proc.MoveToAfter(')');
2832
}
2933
else
3034
{
3135
name = proc.ReadUntilWhitespace();
3236
}
33-
proc.SkipWhitespace();
34-
proc.ReadUntilWhitespace();
35-
var tracking = proc.Matches(trackingBranchRegex);
36-
var trackingName = "";
37-
if (tracking)
37+
38+
proc.ReadUntilWhitespaceTrim();
39+
if (proc.Matches(trackingBranchRegex))
3840
{
3941
trackingName = proc.ReadChunk('[', ']');
4042
var indexOf = trackingName.IndexOf(':');
@@ -45,7 +47,6 @@ public override void LineReceived(string line)
4547
}
4648

4749
var branch = new GitBranch(name, trackingName);
48-
4950
RaiseOnEntry(branch);
5051
}
5152
catch(Exception ex)

src/GitHub.Api/OutputProcessors/GitCountObjectsProcessor.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ public override void LineReceived(string line)
1515
{
1616
var proc = new LineParser(line);
1717

18-
proc.ReadUntil(',');
19-
proc.SkipWhitespace();
20-
var kilobytes = int.Parse(proc.ReadUntilWhitespace());
18+
proc.MoveToAfter(',');
19+
var kilobytes = int.Parse(proc.ReadUntilWhitespaceTrim());
2120

2221
RaiseOnEntry(kilobytes);
2322
}

0 commit comments

Comments
 (0)