Skip to content

Instantly share code, notes, and snippets.

@instance-id
Last active March 27, 2021 03:58
Show Gist options
  • Save instance-id/cc9f572fb553ef140875f68ccbbd2bea to your computer and use it in GitHub Desktop.
Save instance-id/cc9f572fb553ef140875f68ccbbd2bea to your computer and use it in GitHub Desktop.
Auto pull all git repos that reside within a parent directory. (For those of us who are repo hoarders).
#!/usr/bin/env pwsh
<#
.NOTES
===========================================================
Created on: 03/26/2021
Created by: instance.id
Platform: Linux/Windows
Filename: updaterepos.ps1
PSVersion: 7.2-preview4
===========================================================
.DESCRIPTION
Iterate your GitHub folder and pull any that are behind
I am sure this could use some additional logic,
but it does what I needed/wanted it to do
.PARAMETER Path
The path to the parent folder which contains your repos
#>
Param (
[Parameter(ValueFromPipeline = $true)][string]$Path = $(Get-Location)
)
# -- Add repositories you wish to skip to this array.
$exclusions = @('instance-id')
$location = $Path
[Int32]$gitFolders = 0
[Int32]$parentDirectories = 0
$directories = New-Object 'System.Collections.Generic.List[PSCustomObject]'
# -------------------------------------------- Program Execution
# --------------------------------------------------------------
Set-Location $location
Write-Progress -Activity 'Ensuring git repositories' -PercentComplete 0 -CurrentOperation 'Initialization'
foreach ($directory in [System.IO.Directory]::EnumerateDirectories($location, '*.*', 'TopDirectoryOnly')) {
try { $folderObject = Get-Item $directory -ErrorAction SilentlyContinue } catch [UnauthorizedAccessException] {}
$parentDirectories++
if ( $exclusions.Contains($folderObject.BaseName) ) { Write-Host "SKIPPING: ${directory}"; Continue }
foreach ($subDirectory in [System.IO.Directory]::EnumerateDirectories($directory, '.git')) {
try { $subfolderObject = Get-Item $subDirectory -ErrorAction SilentlyContinue } catch [UnauthorizedAccessException] {}
$directories.Add([PSCustomObject]@{Parent = $directory; Name = $folderObject.BaseName; SubDir = $subDirectory })
$gitFolders++
}
}
$updates = New-Object 'System.Collections.Generic.List[PSCustomObject]'
$updateNum = 0
$directories = $directories | Sort-Object -Property Parent
for ($i = 0; $i -lt $directories.Count; $i++) {
$pct = ($i + 1) / $directories.Count * 100
$dirName = $directories[$i].Name
$current = $directories[$i].Parent
Set-Location $current
Write-Progress -Activity "Updating: ${dirName}" -PercentComplete $pct -CurrentOperation 'Fetching...'
git fetch >$null
Write-Progress -Activity "Updating: ${dirName}" -PercentComplete $pct -CurrentOperation 'Status Check...'
$status = git status -sb --porcelain=v2 | Out-String
$status -match 'branch.ab \+(?<ahead>\d+) -(?<behind>\d+)' >$null 2>&1
if ($Matches.Ahead -gt 0) { Continue }
if ($Matches.behind -gt 0) {
Write-Progress -Activity "Updating: ${dirName}" -PercentComplete $pct -CurrentOperation 'Pulling...'
git pull; $updateNum++; $updates += $directories[$i];
}
}
Set-Location $location
Write-Host "Updated ${updateNum} repos. See Updated repos here: ${location}/$($([IO.FileInfo]$location).BaseName)_updated.txt"
Write-Output $updates | Sort-Object -Property Parent | Format-Table -auto | Out-File -Width 999 -FilePath .\$($([IO.FileInfo]$location).BaseName)_updated.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment