Skip to content

Commit c0cec9d

Browse files
author
Dmitry Zhelnin
committed
fix GitCommitDate being author date rather than commit date
1 parent c384a4c commit c0cec9d

16 files changed

+91
-17
lines changed

src/NerdBank.GitVersioning/DisabledGit/DisabledGitContext.cs

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public DisabledGitContext(string workingTreePath)
2424

2525
public override DateTimeOffset? GitCommitDate => null;
2626

27+
public override DateTimeOffset? GitCommitAuthorDate => null;
28+
2729
public override string? HeadCanonicalName => null;
2830

2931
public override IReadOnlyCollection<string>? HeadTags => null;

src/NerdBank.GitVersioning/GitContext.cs

+5
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ public string RepoRelativeProjectDirectory
113113
/// </summary>
114114
public abstract DateTimeOffset? GitCommitDate { get; }
115115

116+
/// <summary>
117+
/// Gets the date that the commit identified by <see cref="GitCommitId"/> was authored.
118+
/// </summary>
119+
public abstract DateTimeOffset? GitCommitAuthorDate { get; }
120+
116121
/// <summary>
117122
/// Gets the canonical name for HEAD's position (e.g. <c>refs/heads/main</c>).
118123
/// </summary>

src/NerdBank.GitVersioning/LibGit2/LibGit2Context.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ internal LibGit2Context(string workingTreeDirectory, string dotGitPath, string?
5151
public override bool IsHead => this.Repository.Head?.Tip?.Equals(this.Commit) ?? false;
5252

5353
/// <inheritdoc />
54-
public override DateTimeOffset? GitCommitDate => this.Commit?.Author.When;
54+
public override DateTimeOffset? GitCommitDate => this.Commit?.Committer.When;
55+
56+
/// <inheritdoc />
57+
public override DateTimeOffset? GitCommitAuthorDate => this.Commit?.Author.When;
5558

5659
/// <inheritdoc />
5760
public override string HeadCanonicalName => this.Repository.Head.CanonicalName;

src/NerdBank.GitVersioning/Managed/ManagedGitContext.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ internal ManagedGitContext(string workingDirectory, string dotGitPath, string? c
5353
public override bool IsHead => this.Repository.GetHeadCommit().Equals(this.Commit);
5454

5555
/// <inheritdoc />
56-
public override DateTimeOffset? GitCommitDate => this.Commit is { } commit ? (commit.Author?.Date ?? this.Repository.GetCommit(commit.Sha, readAuthor: true).Author?.Date) : null;
56+
public override DateTimeOffset? GitCommitDate => this.Commit is { } commit ? (commit.Committer?.Date ?? this.Repository.GetCommit(commit.Sha, readAuthor: true).Committer?.Date) : null;
57+
58+
/// <inheritdoc />
59+
public override DateTimeOffset? GitCommitAuthorDate => this.Commit is { } commit ? (commit.Author?.Date ?? this.Repository.GetCommit(commit.Sha, readAuthor: true).Author?.Date) : null;
5760

5861
/// <inheritdoc />
5962
public override string HeadCanonicalName => this.Repository.GetHeadAsReferenceOrSha().ToString() ?? throw new InvalidOperationException("Unable to determine the HEAD position.");

src/NerdBank.GitVersioning/ManagedGit/GitCommit.cs

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ public struct GitCommit : IEquatable<GitCommit>
4848
/// </summary>
4949
public GitSignature? Author { get; set; }
5050

51+
/// <summary>
52+
/// Gets or sets the committer of this commit.
53+
/// </summary>
54+
public GitSignature? Committer { get; set; }
55+
5156
public static bool operator ==(GitCommit left, GitCommit right)
5257
{
5358
return Equals(left, right);

src/NerdBank.GitVersioning/ManagedGit/GitCommitReader.cs

+34-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public static class GitCommitReader
1919
private static readonly byte[] TreeStart = GitRepository.Encoding.GetBytes("tree ");
2020
private static readonly byte[] ParentStart = GitRepository.Encoding.GetBytes("parent ");
2121
private static readonly byte[] AuthorStart = GitRepository.Encoding.GetBytes("author ");
22+
private static readonly byte[] CommitterStart = GitRepository.Encoding.GetBytes("committer ");
2223

2324
/// <summary>
2425
/// Reads a <see cref="GitCommit"/> object from a <see cref="Stream"/>.
@@ -30,7 +31,7 @@ public static class GitCommitReader
3031
/// The <see cref="GitObjectId"/> of the commit.
3132
/// </param>
3233
/// <param name="readAuthor">
33-
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> field.
34+
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> and <see cref="GitCommit.Committer"/> fields.
3435
/// </param>
3536
/// <returns>
3637
/// The <see cref="GitCommit"/>.
@@ -67,7 +68,7 @@ public static GitCommit Read(Stream stream, GitObjectId sha, bool readAuthor = f
6768
/// The <see cref="GitObjectId"/> of the commit.
6869
/// </param>
6970
/// <param name="readAuthor">
70-
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> field.
71+
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> and <see cref="GitCommit.Committer"/> fields.
7172
/// </param>
7273
/// <returns>
7374
/// The <see cref="GitCommit"/>.
@@ -102,11 +103,22 @@ public static GitCommit Read(ReadOnlySpan<byte> commit, GitObjectId sha, bool re
102103
buffer = buffer.Slice(ParentLineLength);
103104
}
104105

105-
GitSignature signature = default;
106+
GitSignature author = default;
107+
GitSignature committer = default;
106108

107-
if (readAuthor && !TryReadAuthor(buffer, out signature))
109+
if (readAuthor)
108110
{
109-
throw new GitException();
111+
if (!TryReadAuthor(buffer, out author, out int lineLength))
112+
{
113+
throw new GitException();
114+
}
115+
116+
buffer = buffer.Slice(lineLength);
117+
118+
if (!TryReadCommitter(buffer, out committer))
119+
{
120+
throw new GitException();
121+
}
110122
}
111123

112124
return new GitCommit()
@@ -116,7 +128,8 @@ public static GitCommit Read(ReadOnlySpan<byte> commit, GitObjectId sha, bool re
116128
SecondParent = secondParent,
117129
AdditionalParents = additionalParents,
118130
Tree = tree,
119-
Author = readAuthor ? signature : null,
131+
Author = readAuthor ? author : null,
132+
Committer = readAuthor ? committer : null,
120133
};
121134
}
122135

@@ -153,16 +166,27 @@ private static bool TryReadParent(ReadOnlySpan<byte> line, out GitObjectId paren
153166
return true;
154167
}
155168

156-
private static bool TryReadAuthor(ReadOnlySpan<byte> line, out GitSignature signature)
169+
private static bool TryReadAuthor(ReadOnlySpan<byte> line, out GitSignature signature, out int lineLength)
170+
{
171+
return TryReadSignature(line, AuthorStart, out signature, out lineLength);
172+
}
173+
174+
private static bool TryReadCommitter(ReadOnlySpan<byte> line, out GitSignature signature)
175+
{
176+
return TryReadSignature(line, CommitterStart, out signature, out _);
177+
}
178+
179+
private static bool TryReadSignature(ReadOnlySpan<byte> line, byte[] signatureStart, out GitSignature signature, out int lineLength)
157180
{
158181
signature = default;
182+
lineLength = default;
159183

160-
if (!line.Slice(0, AuthorStart.Length).SequenceEqual(AuthorStart))
184+
if (!line.Slice(0, signatureStart.Length).SequenceEqual(signatureStart))
161185
{
162186
return false;
163187
}
164188

165-
line = line.Slice(AuthorStart.Length);
189+
line = line.Slice(signatureStart.Length);
166190

167191
int emailStart = line.IndexOf((byte)'<');
168192
int emailEnd = line.IndexOf((byte)'>');
@@ -179,6 +203,7 @@ private static bool TryReadAuthor(ReadOnlySpan<byte> line, out GitSignature sign
179203
long ticks = long.Parse(GitRepository.GetString(time.Slice(0, offsetStart)));
180204
signature.Date = DateTimeOffset.FromUnixTimeSeconds(ticks);
181205

206+
lineLength = signatureStart.Length + lineEnd + 1;
182207
return true;
183208
}
184209
}

src/NerdBank.GitVersioning/ManagedGit/GitRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ public GitObjectId GetHeadCommitSha()
296296
/// Gets the current HEAD commit, if available.
297297
/// </summary>
298298
/// <param name="readAuthor">
299-
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> field.
299+
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> and <see cref="GitCommit.Committer"/> fields.
300300
/// </param>
301301
/// <returns>
302302
/// The current HEAD commit, or <see langword="null"/> if not available.
@@ -320,7 +320,7 @@ public GitObjectId GetHeadCommitSha()
320320
/// The Git object Id of the commit.
321321
/// </param>
322322
/// <param name="readAuthor">
323-
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> field.
323+
/// A value indicating whether to populate the <see cref="GitCommit.Author"/> and <see cref="GitCommit.Committer"/> fields.
324324
/// </param>
325325
/// <returns>
326326
/// The requested commit.

src/NerdBank.GitVersioning/NoGit/NoGitContext.cs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public NoGitContext(string workingTreePath)
3030
/// <inheritdoc/>
3131
public override DateTimeOffset? GitCommitDate => null;
3232

33+
public override DateTimeOffset? GitCommitAuthorDate => null;
34+
3335
/// <inheritdoc/>
3436
public override string? HeadCanonicalName => null;
3537

src/NerdBank.GitVersioning/VersionOracle.cs

+5
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ public IEnumerable<string> BuildMetadataWithCommitId
265265
/// </summary>
266266
public DateTimeOffset? GitCommitDate => this.context.GitCommitDate;
267267

268+
/// <summary>
269+
/// Gets the Git revision control commit author date for HEAD (the current source code version).
270+
/// </summary>
271+
public DateTimeOffset? GitCommitAuthorDate => this.context.GitCommitAuthorDate;
272+
268273
/// <summary>
269274
/// Gets or sets the number of commits in the longest single path between
270275
/// the specified commit and the most distant ancestor (inclusive)

src/Nerdbank.GitVersioning.Tasks/AssemblyVersionInfo.cs

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ the code is regenerated.
9191

9292
public string GitCommitDateTicks { get; set; }
9393

94+
public string GitCommitAuthorDateTicks { get; set; }
95+
9496
public bool EmitThisAssemblyClass { get; set; } = true;
9597

9698
/// <summary>
@@ -440,6 +442,11 @@ private void GenerateAssemblyAttributes()
440442
fields.Add("GitCommitDate", (new DateTime(gitCommitDateTicks, DateTimeKind.Utc), true));
441443
}
442444

445+
if (long.TryParse(this.GitCommitAuthorDateTicks, out long gitCommitAuthorDateTicks))
446+
{
447+
fields.Add("GitCommitAuthorDate", (new DateTime(gitCommitAuthorDateTicks, DateTimeKind.Utc), true));
448+
}
449+
443450
if (this.AdditionalThisAssemblyFields is object)
444451
{
445452
foreach (ITaskItem item in this.AdditionalThisAssemblyFields)

src/Nerdbank.GitVersioning.Tasks/GetBuildVersion.cs

+9
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ public GetBuildVersion()
165165
[Output]
166166
public string GitCommitDateTicks { get; private set; }
167167

168+
/// <summary>
169+
/// Gets the Git revision control commit author date for HEAD (the current source code version), expressed as the number of 100-nanosecond
170+
/// intervals that have elapsed since January 1, 0001 at 00:00:00.000 in the Gregorian calendar.
171+
/// </summary>
172+
[Output]
173+
public string GitCommitAuthorDateTicks { get; private set; }
174+
168175
/// <summary>
169176
/// Gets the number of commits in the longest single path between
170177
/// the specified commit and the most distant ancestor (inclusive)
@@ -266,6 +273,7 @@ protected override bool ExecuteInner()
266273
this.GitCommitId = oracle.GitCommitId;
267274
this.GitCommitIdShort = oracle.GitCommitIdShort;
268275
this.GitCommitDateTicks = oracle.GitCommitDate is not null ? oracle.GitCommitDate.Value.UtcTicks.ToString(CultureInfo.InvariantCulture) : null;
276+
this.GitCommitAuthorDateTicks = oracle.GitCommitAuthorDate is not null ? oracle.GitCommitAuthorDate.Value.UtcTicks.ToString(CultureInfo.InvariantCulture) : null;
269277
this.GitVersionHeight = oracle.VersionHeight;
270278
this.BuildMetadataFragment = oracle.BuildMetadataFragment;
271279
this.CloudBuildNumber = oracle.CloudBuildNumberEnabled ? oracle.CloudBuildNumber : null;
@@ -314,6 +322,7 @@ protected override bool ExecuteInner()
314322
{ "GitCommitId", this.GitCommitId },
315323
{ "GitCommitIdShort", this.GitCommitIdShort },
316324
{ "GitCommitDateTicks", this.GitCommitDateTicks },
325+
{ "GitCommitAuthorDateTicks", this.GitCommitAuthorDateTicks },
317326
{ "GitVersionHeight", this.GitVersionHeight.ToString(CultureInfo.InvariantCulture) },
318327
{ "BuildNumber", this.BuildNumber.ToString(CultureInfo.InvariantCulture) },
319328
{ "BuildVersionNumberComponent", this.BuildNumber.ToString(CultureInfo.InvariantCulture) },

src/Nerdbank.GitVersioning.Tasks/build/Nerdbank.GitVersioning.targets

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
PrereleaseVersion="$(PrereleaseVersion)"
170170
GitCommitId="$(GitCommitId)"
171171
GitCommitDateTicks="$(GitCommitDateTicks)"
172+
GitCommitAuthorDateTicks="$(GitCommitAuthorDateTicks)"
172173
EmitNonVersionCustomAttributes="$(NBGV_EmitNonVersionCustomAttributes)"
173174
EmitThisAssemblyClass="$(NBGV_EmitThisAssemblyClass)"
174175
AdditionalThisAssemblyFields="@(AdditionalThisAssemblyFields)"

test/Nerdbank.GitVersioning.Tests/BuildIntegrationTests.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ protected void AssertStandardProperties(VersionOptions versionOptions, BuildResu
304304
Assert.Equal(idAsVersion.Build.ToString(), buildResult.BuildVersionNumberComponent);
305305
Assert.Equal($"{idAsVersion.Major}.{idAsVersion.Minor}.{idAsVersion.Build}", buildResult.BuildVersionSimple);
306306
Assert.Equal(this.LibGit2Repository.Head.Tip.Id.Sha, buildResult.GitCommitId);
307-
Assert.Equal(this.LibGit2Repository.Head.Tip.Author.When.UtcTicks.ToString(CultureInfo.InvariantCulture), buildResult.GitCommitDateTicks);
307+
Assert.Equal(this.LibGit2Repository.Head.Tip.Committer.When.UtcTicks.ToString(CultureInfo.InvariantCulture), buildResult.GitCommitDateTicks);
308+
Assert.Equal(this.LibGit2Repository.Head.Tip.Author.When.UtcTicks.ToString(CultureInfo.InvariantCulture), buildResult.GitCommitAuthorDateTicks);
308309
Assert.Equal(commitIdShort, buildResult.GitCommitIdShort);
309310
Assert.Equal(versionHeight.ToString(), buildResult.GitVersionHeight);
310311
Assert.Equal($"{version.Major}.{version.Minor}", buildResult.MajorMinorVersion);
@@ -558,6 +559,8 @@ internal BuildResults(BuildResult buildResult, IReadOnlyList<BuildEventArgs> log
558559

559560
public string GitCommitDateTicks => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitCommitDateTicks");
560561

562+
public string GitCommitAuthorDateTicks => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitCommitAuthorDateTicks");
563+
561564
public string GitVersionHeight => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitVersionHeight");
562565

563566
public string SemVerBuildSuffix => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("SemVerBuildSuffix");

test/Nerdbank.GitVersioning.Tests/ManagedGit/GitCommitReaderTests.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ public void ReadTest()
3232
Assert.Equal(new DateTimeOffset(2020, 10, 6, 13, 40, 09, TimeSpan.FromHours(-6)), author.Date);
3333
Assert.Equal("[email protected]", author.Email);
3434

35-
// Committer and commit message are not read
35+
GitSignature committer = commit.Committer.Value;
36+
37+
Assert.Equal("Andrew Arnott", committer.Name);
38+
Assert.Equal(new DateTimeOffset(2020, 10, 6, 14, 40, 09, TimeSpan.FromHours(-6)), committer.Date);
39+
Assert.Equal("[email protected]", committer.Email);
3640
}
3741
}
3842

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tree f914b48023c7c804a4f3be780d451f31aef74ac1
22
parent 06cc627f28736c0d13506b0414126580fe37c6f3
33
author Andrew Arnott <[email protected]> 1602013209 -0600
4-
committer Andrew Arnott <[email protected]> 1602013209 -0600
4+
committer Andrew Arnott <[email protected]> 1602016809 -0600
55

66
Set version to '3.4-alpha'

test/Nerdbank.GitVersioning.Tests/ManagedGit/commit-d56dc3ed179053abef2097d1120b4507769bcf1a

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ tree f914b48023c7c804a4f3be780d451f31aef74ac1
22
parent 4497b0eaaa89abf0e6d70961ad5f04fd3a49cbc6
33
parent 0989e8fe0cd0e0900173b26decdfb24bc0cc8232
44
author Andrew Arnott <[email protected]> 1602013209 -0600
5-
committer Andrew Arnott <[email protected]> 1602013209 -0600
5+
committer Andrew Arnott <[email protected]> 1602016809 -0600
66

77
Merge branch 'v3.3'

0 commit comments

Comments
 (0)