Last active
July 24, 2025 10:02
-
-
Save adde88/51eb3dae09167ca76c1734f81cdf1b30 to your computer and use it in GitHub Desktop.
Poweshell: GIT Update all GIT-repos within this folder. (Searches all sub-dirs for GIT repos, and updates them perfectly)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Git Repository Updater - PowerShell Version | |
# Made by: Andreas Nilsen - [email protected] - 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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment