Skip to content

Commit 41ee52c

Browse files
authored
Merge pull request #1103 from DmitryZhelnin/fix827
fix GitCommitDate being author date rather than commit date
2 parents c384a4c + c0cec9d commit 41ee52c

File tree

16 files changed

+91
-17
lines changed

16 files changed

+91
-17
lines changed

src/NerdBank.GitVersioning/DisabledGit/DisabledGitContext.cs

Lines changed: 2 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 4 additions & 1 deletion
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 34 additions & 9 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
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)

0 commit comments

Comments
 (0)