diff --git a/Constants/DiffContextDefaults.cs b/Constants/DiffContextDefaults.cs new file mode 100644 index 0000000..07d3c84 --- /dev/null +++ b/Constants/DiffContextDefaults.cs @@ -0,0 +1,22 @@ +namespace WriteCommit.Constants; + +/// +/// Default thresholds used when analyzing diffs. +/// +public static class DiffContextDefaults +{ + /// + /// Maximum number of files considered a "small" diff. + /// + public const int SmallDiffFileThreshold = 2; + + /// + /// Maximum total line count considered a "small" diff. + /// + public const int SmallDiffLineThreshold = 20; + + /// + /// Extra context lines to fetch around changes in small diffs. + /// + public const int ExtraContextLines = 10; +} diff --git a/Program.cs b/Program.cs index 14dbd69..4b09e63 100644 --- a/Program.cs +++ b/Program.cs @@ -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( diff --git a/README.md b/README.md index 0a7827f..e0c03b6 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/Services/GitService.cs b/Services/GitService.cs index 5f5543f..3b134bd 100644 --- a/Services/GitService.cs +++ b/Services/GitService.cs @@ -18,9 +18,9 @@ public async Task IsInGitRepositoryAsync() } } - public async Task GetStagedChangesAsync() + public async Task 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}"); @@ -28,6 +28,17 @@ public async Task GetStagedChangesAsync() return result.Output; } + public async Task 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