diff --git a/ProjectDirector.Test/CommitTests.cs b/ProjectDirector.Test/CommitTests.cs
index 1c17242..3689dc0 100644
--- a/ProjectDirector.Test/CommitTests.cs
+++ b/ProjectDirector.Test/CommitTests.cs
@@ -223,6 +223,43 @@ public void ARenameWhoseSourceLooksLikeARecordIsStillNotListed()
}
}
+ ///
+ /// A rename can also be reported in the worktree column: a file added with intent-to-add that
+ /// git matches against a deleted tracked file comes out as R. Its source path still
+ /// follows as a bare entry and must be consumed, or "ab cd.txt" is listed as "cd.txt".
+ ///
+ [TestMethod]
+ public void AWorktreeRenameReportsOnlyItsDestination()
+ {
+ // Arrange
+ string root = CreateCommittedRepository();
+
+ try
+ {
+ File.WriteAllText(Path.Join(root, "ab cd.txt"), "moved content\n");
+ Assert.IsTrue(GitCli.RunIn(root, "add", "--all").Succeeded);
+ Assert.IsTrue(GitCli.RunIn(root, "commit", "-m", "second").Succeeded);
+
+ File.Delete(Path.Join(root, "ab cd.txt"));
+ File.WriteAllText(Path.Join(root, "new.txt"), "moved content\n");
+ Assert.IsTrue(GitCli.RunIn(root, "add", "-N", "new.txt").Succeeded, "git add -N failed.");
+
+ GitResult status = GitCli.RunIn(root, "status", "--porcelain", "-z");
+ Assert.StartsWith(" R new.txt\0", status.Output, "git should report the rename in the worktree column.");
+
+ // Act
+ Collection changes = GitCli.ListPendingChanges(root);
+
+ // Assert
+ Assert.HasCount(1, changes);
+ Assert.AreEqual("new.txt", changes[0]);
+ }
+ finally
+ {
+ Cleanup(root);
+ }
+ }
+
///
/// A path that is not a repository at all reports nothing rather than throwing, so the button
/// degrades to "nothing to commit" instead of taking the application down.
diff --git a/ProjectDirector/GitCli.cs b/ProjectDirector/GitCli.cs
index 7ea1846..6d2f076 100644
--- a/ProjectDirector/GitCli.cs
+++ b/ProjectDirector/GitCli.cs
@@ -213,8 +213,10 @@ internal static Collection ListPendingChanges(string repositoryPath)
changes.Add(entry[3..]);
- // A rename or copy is recorded against the index, in the first status character.
- if (entry[0] is 'R' or 'C')
+ // A rename or copy is usually recorded against the index, in the first status character,
+ // but one detected in the worktree (an intent-to-add file matched against a deleted
+ // tracked one) is recorded in the second. Either way the source path follows.
+ if (entry[0] is 'R' or 'C' || entry[1] is 'R' or 'C')
{
++i;
}