Skip to content

Instantly share code, notes, and snippets.

@james-world
Created April 23, 2020 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james-world/e394d92bca2c0280831e1d7f4cb92595 to your computer and use it in GitHub Desktop.
Save james-world/e394d92bca2c0280831e1d7f4cb92595 to your computer and use it in GitHub Desktop.
Put these in a directory containing all your repos. Run FetchAll it to get latest remote changes for all repos in sub-directories, Run UpdateMain to update the main branch in all repos with main checked out and without local changes.
# Get latest remote changes for all repos in sub-directories
Write-Output "Fetching remote repositories..."
Get-ChildItem -Directory |
# Has a hidden .git directory (i.e. is a repository)
Where-Object { ( $_ | Get-ChildItem -Hidden ).Name -contains ".git" } |
# Has at lease one remote
Where-Object { Push-Location $_; (git remote).Count -gt 0; Pop-Location } |
# Fetch remote changes
ForEach-Object { Push-Location $_; "Checking $_..."; git fetch; Pop-Location; "`t...Done"; }
# Update local main branches if HEAD is on main and there are no changes
function UpdateRepo($dir) {
# Update a branch if clean, on master and behind the remote
Push-Location $dir
"Checking $dir"
$line1 = "On branch master"
$line2 = "Your branch is behind 'origin/master' by \d+ commits?, and can be fast-forwarded."
$line3 = "`(use `"git pull`" to update your local branch`)"
$line5 = "nothing to commit, working tree clean"
$current = (git branch --show-current)
if ($current -ne "master")
{
"`tSkipping as on branch $current"
}
else
{
$status = (git status --ahead-behind)
if ($status.Length -eq 5 -and `
$status[0] -match $line1 -and `
$status[1] -match $line2 -and `
$status[2] -match $line3 -and `
$status[4] -match $line5)
{
"`tPulling"
git pull
}
elseif ($status.Length -gt 3 -and $status[3] -match $line5)
{
"`tSkipping as clean"
}
else
{
"`tSkipping as up to date or to uncommitted or unpushed work"
$status
}
}
Pop-Location
}
Get-ChildItem -Directory |
# Has a hidden .git directory (i.e. is a repository)
Where-Object { ( $_ | Get-ChildItem -Hidden ).Name -contains ".git" } |
# Has at lease one remote
Where-Object { Push-Location $_; (git remote).Count -gt 0; Pop-Location } |
# Is on branch master and strictly behind remote
ForEach-Object { UpdateRepo $_ }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment