Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions GitIntegration.Test/Parsing/GitFetchParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,38 @@ public void ToleratesCarriageReturnLineEndings()
Assert.AreEqual(NewSha.As<GitCommitSha>(), result.Updates[0].NewSha);
}

[TestMethod]
[DataRow("0000000000000000000000000000000000000000", "6702dd1957dedc4e0f54245bda65f3ddc5f37e64")]
[DataRow(
"0000000000000000000000000000000000000000000000000000000000000000",
"6702dd1957dedc4e0f54245bda65f3ddc5f37e646702dd1957dedc4e0f54245b")]
public void ReportsANullOldIdAsNullForACreatedRef(string nullId, string newSha)
{
// git writes its null id for the side of the update that does not exist. Push() reports
// null there, so fetch must too, under SHA-1 and SHA-256 alike.
GitRefUpdate update = GitFetchParser.Parse(
Record("*", nullId, newSha, "refs/remotes/origin/created")).Updates[0];

Assert.AreEqual(GitRefUpdateKind.Created, update.Kind);
Assert.IsNull(update.OldSha);
Assert.AreEqual(newSha.As<GitCommitSha>(), update.NewSha);
}

[TestMethod]
[DataRow("7c85857fc85452150652c289fc94f1f912b96c40", "0000000000000000000000000000000000000000")]
[DataRow(
"7c85857fc85452150652c289fc94f1f912b96c407c85857fc85452150652c289",
"0000000000000000000000000000000000000000000000000000000000000000")]
public void ReportsANullNewIdAsNullForAPrunedRef(string oldSha, string nullId)
{
GitRefUpdate update = GitFetchParser.Parse(
Record("-", oldSha, nullId, "refs/remotes/origin/pruned")).Updates[0];

Assert.AreEqual(GitRefUpdateKind.Removed, update.Kind);
Assert.AreEqual(oldSha.As<GitCommitSha>(), update.OldSha);
Assert.IsNull(update.NewSha);
}

[TestMethod]
public void ReportsAnUnknownFlagWithoutThrowing()
{
Expand Down
21 changes: 19 additions & 2 deletions GitIntegration/Parsing/GitFetchParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,28 @@ private static GitRefUpdate ReadUpdate(string record)
{
Kind = ToKind(flag),
Reference = GitParseValues.ToSemantic<GitRefName>(fields[2], "fetched reference"),
OldSha = GitParseValues.ToSemantic<GitCommitSha>(fields[0], "fetched old object id"),
NewSha = GitParseValues.ToSemantic<GitCommitSha>(fields[1], "fetched new object id"),
OldSha = ReadObjectId(fields[0], "fetched old object id"),
NewSha = ReadObjectId(fields[1], "fetched new object id"),
};
}

/// <summary>
/// Converts one side of a fetch record to a commit id, or <see langword="null"/> for git's null id.
/// </summary>
/// <remarks>
/// git writes the null id for whichever side of the update does not exist: the old side of a
/// created ref and the new side of a pruned one. Reporting it as <see langword="null"/> matches
/// what <c>Push()</c> returns for the same kinds of update, and what the worktree and submodule
/// parsers do with the null id.
/// </remarks>
/// <param name="objectId">The object id git printed.</param>
/// <param name="description">What the field holds, for the parse error.</param>
/// <returns>The commit id, or <see langword="null"/> when git printed the null id.</returns>
private static GitCommitSha? ReadObjectId(string objectId, string description) =>
GitParseValues.IsNullObjectId(objectId)
? null
: GitParseValues.ToSemantic<GitCommitSha>(objectId, description);

private static GitRefUpdateKind ToKind(char flag) => flag switch
{
' ' => GitRefUpdateKind.FastForward,
Expand Down
Loading