Show the window before slow location probes and wrap git.exe for commit, diff, and merge.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,7 +15,7 @@ public class GitPorcelainParserTests
|
||||
# branch.ab +2 -1
|
||||
1 .M N... 100644 100644 100644 a a src/App.cs
|
||||
1 M. N... 100644 100644 100644 b b README.md
|
||||
2 R. N... 100644 100644 100644 c c R100 old.txt new.txt
|
||||
2 R. N... 100644 100644 100644 c c R100 new.txt old.txt
|
||||
? bin/out.dll
|
||||
? notes.md
|
||||
! ignore.me
|
||||
@@ -28,8 +28,79 @@ public class GitPorcelainParserTests
|
||||
Assert.Equal(1, status.Behind);
|
||||
Assert.False(status.WorkingTreeClean);
|
||||
Assert.Equal("main · 3 modified · 2 untracked · 2 ahead · 1 behind", status.Badge);
|
||||
Assert.Collection(
|
||||
status.Changes,
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(GitChangeState.Staged, c.State);
|
||||
Assert.Equal("old.txt", c.OriginalPath);
|
||||
Assert.Equal("new.txt", c.Path);
|
||||
Assert.Equal("old.txt → new.txt", c.DisplayPath);
|
||||
Assert.Equal("renamed", c.ChangeLabel);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(GitChangeState.Staged, c.State);
|
||||
Assert.Equal("README.md", c.Path);
|
||||
Assert.Equal("modified", c.ChangeLabel);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(GitChangeState.Unstaged, c.State);
|
||||
Assert.Equal("src/App.cs", c.Path);
|
||||
Assert.Equal("modified", c.ChangeLabel);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(GitChangeState.Untracked, c.State);
|
||||
Assert.Equal("bin/out.dll", c.Path);
|
||||
},
|
||||
c =>
|
||||
{
|
||||
Assert.Equal(GitChangeState.Untracked, c.State);
|
||||
Assert.Equal("notes.md", c.Path);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Lists_staged_and_unstaged_for_the_same_path()
|
||||
{
|
||||
var status = GitPorcelainParser.Parse("""
|
||||
# branch.head main
|
||||
1 MM N... 100644 100644 100644 a a src/Both.cs
|
||||
""", @"C:\src");
|
||||
Assert.NotNull(status);
|
||||
Assert.Equal(1, status.ModifiedCount);
|
||||
Assert.Equal(2, status.Changes.Count);
|
||||
Assert.Equal(GitChangeState.Staged, status.Changes[0].State);
|
||||
Assert.Equal(GitChangeState.Unstaged, status.Changes[1].State);
|
||||
Assert.All(status.Changes, c => Assert.Equal("src/Both.cs", c.Path));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Lists_unmerged_and_quoted_paths()
|
||||
{
|
||||
var status = GitPorcelainParser.Parse("""
|
||||
# branch.head topic
|
||||
u UU N... 100644 100644 100644 100644 a b c conflict.txt
|
||||
1 .M N... 100644 100644 100644 a a "my file.txt"
|
||||
? docs/a file.md
|
||||
""", @"C:\src");
|
||||
Assert.NotNull(status);
|
||||
Assert.Equal(2, status.ModifiedCount);
|
||||
Assert.Equal(1, status.UntrackedCount);
|
||||
Assert.Equal(GitChangeState.Unmerged, status.Changes[0].State);
|
||||
Assert.Equal("conflict.txt", status.Changes[0].Path);
|
||||
Assert.Equal("unmerged", status.Changes[0].ChangeLabel);
|
||||
Assert.Equal("my file.txt", status.Changes[1].Path);
|
||||
Assert.Equal("docs/a file.md", status.Changes[2].Path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unquote_decodes_c_escapes()
|
||||
=> Assert.Equal("a\"b", GitPorcelainParser.Unquote("\"a\\\"b\""));
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Clean_tree_uses_detached_oid_prefix()
|
||||
{
|
||||
@@ -95,4 +166,57 @@ public class GitRepoDetectorTests
|
||||
[Fact]
|
||||
public void Virtual_roots_are_not_repos()
|
||||
=> Assert.Null(GitRepoDetector.FindRoot(LocationRoots.ThisPc, _ => true, _ => true));
|
||||
|
||||
[Fact]
|
||||
public void Finds_gitdir_from_a_directory_and_a_gitfile()
|
||||
{
|
||||
var dirs = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
@"C:\src",
|
||||
@"C:\src\.git",
|
||||
@"C:\work",
|
||||
@"D:\repo\.git\worktrees\topic"
|
||||
};
|
||||
var files = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { @"C:\work\.git" };
|
||||
Assert.Equal(@"C:\src\.git", GitRepoDetector.FindGitDir(@"C:\src", dirs.Contains, files.Contains));
|
||||
Assert.Equal(
|
||||
@"D:\repo\.git\worktrees\topic",
|
||||
GitRepoDetector.FindGitDir(
|
||||
@"C:\work",
|
||||
dirs.Contains,
|
||||
files.Contains,
|
||||
_ => "gitdir: D:/repo/.git/worktrees/topic"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Detects_merge_and_rebase_in_progress()
|
||||
{
|
||||
var dirs = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
@"C:\src",
|
||||
@"C:\src\.git",
|
||||
@"C:\src\.git\rebase-merge",
|
||||
@"C:\work",
|
||||
@"D:\repo\.git\worktrees\topic"
|
||||
};
|
||||
var files = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
@"C:\src\.git\MERGE_HEAD",
|
||||
@"C:\work\.git",
|
||||
@"D:\repo\.git\worktrees\topic\CHERRY_PICK_HEAD"
|
||||
};
|
||||
Assert.Equal(GitOperationKind.Merge, GitRepoDetector.GetOperation(@"C:\src", dirs.Contains, files.Contains));
|
||||
Assert.True(GitRepoDetector.IsOperationInProgress(@"C:\src", dirs.Contains, files.Contains));
|
||||
dirs.Remove(@"C:\src\.git\rebase-merge");
|
||||
files.Remove(@"C:\src\.git\MERGE_HEAD");
|
||||
Assert.Equal(GitOperationKind.None, GitRepoDetector.GetOperation(@"C:\src", dirs.Contains, files.Contains));
|
||||
Assert.False(GitRepoDetector.IsOperationInProgress(@"C:\src", dirs.Contains, files.Contains));
|
||||
Assert.Equal(
|
||||
GitOperationKind.CherryPick,
|
||||
GitRepoDetector.GetOperation(
|
||||
@"C:\work",
|
||||
dirs.Contains,
|
||||
files.Contains,
|
||||
_ => "gitdir: D:/repo/.git/worktrees/topic"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user