# Git Repository Updater - PowerShell Version # Made by: Andreas Nilsen - adde88@gmail.com - https://www.github.com/adde88 # Date: 24.07.2025 # Requires PowerShell 5.0 or higher # Set error action preference to stop on errors $ErrorActionPreference = "Stop" # Initialize variables $gitRepositories = @() $currentDirectory = Get-Location Write-Host "============================================" -ForegroundColor Cyan Write-Host "Git Repository Updater - PowerShell Version" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan Write-Host "" Write-Host "Scanning current directory for Git repositories..." -ForegroundColor Yellow Write-Host "Current directory: $currentDirectory" -ForegroundColor Gray Write-Host "" # Find all Git repositories in subdirectories try { $subdirectories = Get-ChildItem -Directory -ErrorAction SilentlyContinue foreach ($dir in $subdirectories) { $gitPath = Join-Path $dir.FullName ".git" if (Test-Path $gitPath) { Write-Host "Found Git repository: $($dir.Name)" -ForegroundColor Green $gitRepositories += $dir.Name } } } catch { Write-Host "ERROR: Failed to scan directories - $($_.Exception.Message)" -ForegroundColor Red Read-Host "Press Enter to exit" exit 1 } Write-Host "" Write-Host "Found $($gitRepositories.Count) Git repositories." -ForegroundColor Yellow Write-Host "" # Check if any repositories were found if ($gitRepositories.Count -eq 0) { Write-Host "No Git repositories found in subdirectories." -ForegroundColor Yellow Read-Host "Press Enter to exit" exit 0 } Write-Host "Repositories to update: $($gitRepositories -join ', ')" -ForegroundColor Cyan Write-Host "" Write-Host "Starting update process..." -ForegroundColor Yellow Write-Host "============================================" -ForegroundColor Cyan Write-Host "" # Function to execute git commands with proper error handling function Invoke-GitCommand { param( [string]$Command, [string]$Arguments = "", [string]$WorkingDirectory = $PWD ) try { $processInfo = New-Object System.Diagnostics.ProcessStartInfo $processInfo.FileName = "git" $processInfo.Arguments = $Arguments $processInfo.WorkingDirectory = $WorkingDirectory $processInfo.RedirectStandardOutput = $true $processInfo.RedirectStandardError = $true $processInfo.UseShellExecute = $false $processInfo.CreateNoWindow = $true $process = New-Object System.Diagnostics.Process $process.StartInfo = $processInfo $null = $process.Start() $stdout = $process.StandardOutput.ReadToEnd() $stderr = $process.StandardError.ReadToEnd() $process.WaitForExit() return @{ ExitCode = $process.ExitCode StdOut = $stdout StdErr = $stderr } } catch { return @{ ExitCode = -1 StdOut = "" StdErr = $_.Exception.Message } } } # Process each repository foreach ($repo in $gitRepositories) { Write-Host "" Write-Host "----------------------------------------" -ForegroundColor DarkCyan Write-Host "Processing repository: $repo" -ForegroundColor White Write-Host "----------------------------------------" -ForegroundColor DarkCyan $repoPath = Join-Path $currentDirectory $repo # Verify directory exists and is accessible if (-not (Test-Path $repoPath)) { Write-Host "ERROR: Cannot access directory $repo" -ForegroundColor Red continue } Write-Host "Current directory: $repoPath" -ForegroundColor Gray Write-Host "Running: git pull" -ForegroundColor Gray # Attempt git pull $pullResult = Invoke-GitCommand -Arguments "pull" -WorkingDirectory $repoPath if ($pullResult.ExitCode -ne 0) { Write-Host "" Write-Host "*** ERROR: git pull failed for repository $repo ***" -ForegroundColor Red Write-Host "" Write-Host "Error details:" -ForegroundColor Yellow if ($pullResult.StdErr) { Write-Host $pullResult.StdErr -ForegroundColor Red } if ($pullResult.StdOut) { Write-Host $pullResult.StdOut -ForegroundColor Yellow } Write-Host "" Write-Host "This could be due to:" -ForegroundColor Yellow Write-Host "- Uncommitted local changes conflicting with remote changes" -ForegroundColor Gray Write-Host "- Merge conflicts" -ForegroundColor Gray Write-Host "- Network issues" -ForegroundColor Gray Write-Host "- Authentication problems" -ForegroundColor Gray Write-Host "" Write-Host "Would you like to reset this repository to match the remote exactly?" -ForegroundColor Yellow Write-Host "WARNING: This will PERMANENTLY DELETE any uncommitted local changes!" -ForegroundColor Red Write-Host "" do { $userChoice = Read-Host "Reset repository $repo to remote state? (Y/N)" $userChoice = $userChoice.Trim().ToUpper() } while ($userChoice -ne "Y" -and $userChoice -ne "N") if ($userChoice -eq "Y") { Write-Host "" Write-Host "Resetting repository $repo to HEAD..." -ForegroundColor Yellow Write-Host "Running: git reset --hard HEAD" -ForegroundColor Gray $resetResult = Invoke-GitCommand -Arguments "reset --hard HEAD" -WorkingDirectory $repoPath if ($resetResult.ExitCode -ne 0) { Write-Host "ERROR: git reset --hard HEAD failed for $repo" -ForegroundColor Red if ($resetResult.StdErr) { Write-Host $resetResult.StdErr -ForegroundColor Red } Write-Host "Skipping this repository..." -ForegroundColor Yellow } else { Write-Host "Reset successful. Attempting git pull again..." -ForegroundColor Green Write-Host "Running: git pull" -ForegroundColor Gray $pullRetryResult = Invoke-GitCommand -Arguments "pull" -WorkingDirectory $repoPath if ($pullRetryResult.ExitCode -ne 0) { Write-Host "ERROR: git pull still failed after reset for $repo" -ForegroundColor Red if ($pullRetryResult.StdErr) { Write-Host $pullRetryResult.StdErr -ForegroundColor Red } Write-Host "This may require manual intervention." -ForegroundColor Yellow } else { Write-Host "SUCCESS: Repository $repo updated successfully after reset!" -ForegroundColor Green if ($pullRetryResult.StdOut) { Write-Host $pullRetryResult.StdOut -ForegroundColor Cyan } } } } elseif ($userChoice -eq "N") { Write-Host "" Write-Host "User chose not to reset repository $repo." -ForegroundColor Yellow Write-Host "Exiting script as requested..." -ForegroundColor Red Write-Host "" Read-Host "Press Enter to exit" exit 1 } } else { Write-Host "SUCCESS: Repository $repo updated successfully!" -ForegroundColor Green if ($pullResult.StdOut) { Write-Host $pullResult.StdOut -ForegroundColor Cyan } } } Write-Host "" Write-Host "============================================" -ForegroundColor Cyan Write-Host "All repositories processed!" -ForegroundColor Green Write-Host "============================================" -ForegroundColor Cyan Write-Host "" Read-Host "Press Enter to exit"