-
-
Save csandfeld/4983044f51f424a43178936048da57b2 to your computer and use it in GitHub Desktop.
Sync-GithubFork.ps1
This file contains 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
function Sync-GithubFork { | |
[CmdletBinding()] | |
Param( | |
[Parameter(ValueFromPipeline = $true)] | |
[System.String[]] | |
$Path = (Get-Location) | |
, | |
[System.String[]] | |
$Branch = $null | |
) | |
begin { | |
function Get-GitBranch { | |
Param( | |
[Switch] | |
$Current = $false | |
) | |
# Get all branches | |
$Branch = (git.exe branch) | |
# If Current switch get only branch with asterisk | |
if ($Current) { | |
$Branch = $Branch | Where-Object { $_ -match '^\*' } | |
} | |
# Remove asterisk and whitespace to return only names | |
$Branch = $Branch | ForEach-Object { $_.Replace('*', '').Trim() } | |
return $Branch | |
} | |
} | |
process { | |
foreach ($p in $Path) { | |
Write-Verbose -Message "Checking for Git repository in path: $p" | |
$IsGitRepo = Test-Path -Path (Join-Path -Path $p -ChildPath '.git') -PathType Container | |
if ($IsGitRepo) { | |
Write-Verbose -Message 'Git repository found' | |
Write-Verbose -Message 'Getting Remote Origin URL for repository' | |
$RemoteOriginUrl = (git.exe config --get remote.origin.url).Trim() | |
Write-Verbose -Message "Remote Origin URL: $RemoteOriginUrl" | |
Write-Verbose -Message 'Checking if it is a GitHub repository' | |
$IsGitHub = ($RemoteOriginUrl -match 'github.com') | |
if ($IsGitHub) { | |
Write-Verbose -Message 'It appear to be a GitHub repository' | |
Write-Verbose -Message 'Getting User and Repository parts from the Remote Origin URL' | |
$UserAndRepo = [regex]::Match($RemoteOriginUrl, '([^\/.]+\/[^\/.]+)\.git$').Groups[1].Value | |
Write-Verbose -Message "Github User/Repository: $UserAndRepo" | |
Write-Verbose 'Getting GitHub Repository REST data' | |
$RestData = Invoke-RestMethod -Uri "https://api.github.com/repos/$UserAndRepo" | |
Write-Verbose -Message 'Checking if GitHub Repository is a fork' | |
if ($RestData.fork) { | |
Write-Verbose 'Repository is a fork' | |
Write-Verbose 'Getting parent repository owner' | |
$ParentOwner = $RestData.parent.owner.login | |
Write-Verbose "Parent repository owner: $ParentOwner" | |
Write-Verbose 'Getting parent repository clone URL' | |
$ParentCloneUrl = $RestData.parent.clone_url | |
Write-Verbose "Parent repository clone URL: $ParentCloneUrl" | |
Write-Verbose 'Getting configured remotes' | |
$Remotes = (git.exe remote -v) | |
Write-Verbose 'Building HashTable of configured remotes' | |
$RemotesHash = @{} | |
foreach ($Remote in $Remotes) { | |
$RegEx = [regex]::Match($Remote, '^(.+)\s(.+)\s\((.+)\)$') | |
$RemotesHash[$RegEx.Groups[1].Value] = $RegEx.Groups[2].Value | |
} | |
Write-Verbose "Checking if $ParentOwner is already configured as remote" | |
if (-not ($ParentOwner -in $RemotesHash.GetEnumerator().Name)) { | |
Write-Verbose "Adding $ParentOwner as a remote" | |
git.exe remote add $ParentOwner $ParentCloneUrl | |
} | |
else { | |
Write-Verbose "$ParentOwner is already configured as a remote" | |
} | |
Write-Verbose -Message 'Getting local branches' | |
$LocalBranches = Get-GitBranch | |
Write-Verbose -Message "Local branches found: [$($LocalBranches -join ', ')]" | |
Write-Verbose -Message 'Getting current branch' | |
$CurrentBranch = Get-GitBranch -Current | |
Write-Verbose -Message "Current branch: $CurrentBranch" | |
Write-Verbose -Message 'Checking if branches where specified' | |
if (-not $Branch) { | |
Write-Verbose -Message "No branch specified defaulting to current branch: $CurrentBranch" | |
$Branch = $CurrentBranch | |
} | |
Write-Verbose -Message "Performing action: git.exe fetch $ParentOwner" | |
git.exe fetch $ParentOwner | |
Write-Verbose -Message 'Loop through branches' | |
foreach ($b in $Branch) { | |
Write-Verbose -Message "Processing branch: $b" | |
Write-Verbose -Message "Verify that branch [$b] match a local branch [$($LocalBranches -join ', ')]" | |
if ($b -in $LocalBranches) { | |
Write-Verbose -Message "Verify if branch [$b] is the current branch" | |
if (-not ($b -eq (Get-GitBranch -Current))) { | |
Write-Verbose -Message "Branch [$b] is not the current branch" | |
Write-Verbose -Message "Performing action: git.exe checkout $b" | |
git.exe checkout $b | |
} | |
Write-Verbose -Message "Performing action: git.exe merge $ParentOwner/$b" | |
git.exe merge $ParentOwner/$b | |
Write-Verbose -Message "Performing action: git.exe push origin $b" | |
git.exe push origin $b | |
} else { | |
Write-Warning -Message "Specified branch [$b] is not available in local repository" | |
} | |
} | |
} else { | |
Write-Warning -Message "Remote Origin does not appear to be a fork: $RemoteOriginUrl" | |
} | |
} else { | |
Write-Warning -Message "This does not appear to be a GitHub repository: $p" | |
} | |
} else { | |
Write-Warning -Message "This does not appear to be a Git repository: $p" | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment