Public/Invoke-PSUGitCommit.ps1
function Invoke-PSUGitCommit { <# .SYNOPSIS Generates and commits a conventional Git commit message using Gemini AI, then syncs with remote. .DESCRIPTION Analyzes uncommitted changes in a Git repository, generates a conventional commit message using Gemini AI, commits those changes, pulls latest from remote with rebase, and pushes your new commit. .PARAMETER RootPath Optional. Git repository root path. Defaults to current directory. .EXAMPLE Invoke-PSUGitCommit .EXAMPLE Invoke-PSUGitCommit -RootPath "c:\repo" .NOTES Author : Lakshmanachari Panuganti Date : 2025-07-31 Requires: - Git CLI - $env:API_KEY_GEMINI - Invoke-PSUPromptOnGeminiAi #> [CmdletBinding()] param ( [string]$RootPath = (Get-Location).Path ) Push-Location $RootPath try { $gitOutput = git status --porcelain if (-not $gitOutput.Count) { Write-Host "No uncommitted changes found." -ForegroundColor Green return } $changedItems = foreach ($line in $gitOutput) { $line = $line.Trim() $changeCode = $line.Split(' ')[0].Trim() $path = $line.Split(' ', 2)[1].Trim().Trim('"') $fullPath = Join-Path -Path $RootPath -ChildPath $path $itemInfo = Get-Item $fullPath -ErrorAction SilentlyContinue $itemType = if ($changeCode -eq 'D' -or -not $itemInfo) { 'File/Folder' } elseif ($itemInfo -is [System.IO.DirectoryInfo]) { 'Folder' } elseif ($itemInfo -is [System.IO.FileInfo]) { 'File' } else { 'Unknown' } [pscustomobject]@{ Name = Split-Path $path -Leaf ItemType = $itemType ChangeType = switch ($changeCode) { 'M' { 'Modified' } 'A' { 'Added' } 'D' { 'Deleted' } 'R' { 'Renamed' } 'C' { 'Copied' } 'U' { 'Unmerged' } '??' { 'New' } default { "Other: $changeCode" } } Path = $fullPath } } $fileChanges = $changedItems | ForEach-Object { $item = $_ $status = $item.ChangeType $path = $item.Path $itemType = $item.ItemType $diff = switch ($status) { 'Modified' { git diff -- "$path" } 'New' { if ($itemType -eq 'File') { Get-Content -Path $path } } default { "" } } [PSCustomObject]@{ Path = $path ItemType = $itemType Status = $status Diff = $diff -join "`n" } } $prompt = @" You are a Git commit message generator with expertise in software development. Generate a clear, conventional commit message based on the following file changes. The message must start with one of: feat, fix, chore, docs, refactor, style, test. Limit to 1-2 lines. Changes: "@ foreach ($item in $fileChanges) { $prompt += @" ### File: $($item.Path) Change Type: $($item.Status) ```diff $($item.Diff) "@ } $commitMessage = Invoke-PSUPromptOnGeminiAi -Prompt ($prompt | Out-String) -ApiKey $env:API_KEY_GEMINI $commitMessage = $commitMessage.Trim() | where-object { $_ } Write-Host "Following is the Commit message!" -ForegroundColor Cyan Write-Host $CommitMessage -ForegroundColor DarkYellow $CustomCommitMsg = Read-Host "Press enter to commit with this message or provide your own commit message" if ($CustomCommitMsg) { $commitMessage = $CustomCommitMsg } # Stage and commit git add . *> $null git commit -m "$commitMessage" *> $null # Sync with remote Write-Host "`⇅ Syncing with remote..." -ForegroundColor Cyan git pull --rebase *> $null git push *> $null Write-Host "Sync complete." -ForegroundColor Green } catch { Write-Error "Error: $_" throw } finally { Pop-Location } } |