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
22 changes: 22 additions & 0 deletions Constants/DiffContextDefaults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace WriteCommit.Constants;

/// <summary>
/// Default thresholds used when analyzing diffs.
/// </summary>
public static class DiffContextDefaults
{
/// <summary>
/// Maximum number of files considered a "small" diff.
/// </summary>
public const int SmallDiffFileThreshold = 2;

/// <summary>
/// Maximum total line count considered a "small" diff.
/// </summary>
public const int SmallDiffLineThreshold = 20;

/// <summary>
/// Extra context lines to fetch around changes in small diffs.
/// </summary>
public const int ExtraContextLines = 10;
}
25 changes: 24 additions & 1 deletion Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,30 @@ static async Task GenerateCommitMessage(
}

// Get staged changes
var stagedChanges = await gitService.GetStagedChangesAsync();
var stagedChanges = await gitService.GetStagedChangesAsync(verbose);

// If the diff is very small, grab a few extra lines of context
var fileCount = System.Text.RegularExpressions.Regex.Matches(
stagedChanges,
"^diff --git",
System.Text.RegularExpressions.RegexOptions.Multiline
).Count;
var lineCount = stagedChanges.Split('\n').Length;

if (
fileCount <= DiffContextDefaults.SmallDiffFileThreshold
&& lineCount < DiffContextDefaults.SmallDiffLineThreshold
)
{
if (verbose)
{
Console.WriteLine("Small diff detected, gathering additional context...");
}
stagedChanges = await gitService.GetStagedChangesWithContextAsync(
DiffContextDefaults.ExtraContextLines,
verbose
);
}
if (string.IsNullOrWhiteSpace(stagedChanges))
{
Console.WriteLine(
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ A cross-platform .NET tool that generates AI-powered commit messages using OpenA
- 📝 **Verbose output** - Detailed logging for debugging and transparency
- ⚡ **Fast and lightweight** - Direct OpenAI API integration for quick responses
- 📋 **Smart chunking** - Handles large diffs by intelligently splitting them into semantic chunks
- 🔍 **Context-aware** - Adds surrounding code lines when diffs are very small for better summaries

## 🚀 Quick Start

Expand Down
15 changes: 13 additions & 2 deletions Services/GitService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@ public async Task<bool> IsInGitRepositoryAsync()
}
}

public async Task<string> GetStagedChangesAsync()
public async Task<string> GetStagedChangesAsync(bool verbose = false)
{
var result = await RunCommandAsync("git", "--no-pager diff --staged", false);
var result = await RunCommandAsync("git", "--no-pager diff --staged", verbose);
if (result.ExitCode != 0)
{
throw new InvalidOperationException($"Failed to get staged changes: {result.Error}");
}
return result.Output;
}

public async Task<string> GetStagedChangesWithContextAsync(int contextLines, bool verbose = false)
{
var args = $"--no-pager diff --staged --unified={contextLines}";
var result = await RunCommandAsync("git", args, verbose);
if (result.ExitCode != 0)
{
throw new InvalidOperationException($"Failed to get staged changes with context: {result.Error}");
}
return result.Output;
}

public async Task CommitChangesAsync(string commitMessage, bool verbose)
{
// Create temporary file for commit message
Expand Down