Skip to content

Instantly share code, notes, and snippets.

@WimObiwan
Last active April 24, 2017 09:29
Show Gist options
  • Save WimObiwan/630be4db6599b09d6f51dc79f383c8b8 to your computer and use it in GitHub Desktop.
Save WimObiwan/630be4db6599b09d6f51dc79f383c8b8 to your computer and use it in GitHub Desktop.
[CmdletBinding()]
Param (
[string] $RepositoryPath = '.'
)
function Split-GitPath ([string] $path) {
$pos = $path.LastIndexOf('/')
if ($pos -eq -1) {
''
} else {
$path.Substring(0, $pos)
}
}
$RepositoryPath = Resolve-Path $RepositoryPath
pushd .
cd $RepositoryPath
$objects_map = @{}
Write-Progress -Activity 'Scanning GIT objects'
@(git rev-list --objects --all) | %{ if ($_ -match '^(\w+)(?: (.*))?$') { $objects_map.Add($Matches[1], $Matches[2]) } }
Write-Progress -Activity 'Scanning GIT pack files'
$blobs = @(dir .\.git\objects\pack\pack-*.idx | %{ git verify-pack -v $_ | ?{ $_ -match '^\w+ blob ' } })
$files = @{}
$cnt = 0
$blobs | %{
$cnt++
Write-Progress -Activity "Merging $($blobs.Count) blobs from pack files with $($objects_map.Count) file objects" -PercentComplete ($cnt * 100 / $blobs.Count)
if ($_ -match '^(\w+) blob (\d+) (\d+) \d+(?: (\d+) \w+)?$') {
$hash = $Matches[1]
$size = [long]$Matches[2]
$size_in_pack = [int]$Matches[3]
$is_diff = ($Matches[4] -ne $null -and $Matches[4] -ne '')
$filename = $objects_map[$hash]
if ($filename) {
#Write-Host "$filename $is_diff $size $size_in_pack"
$exists = Test-Path $filename
$file = $files[$filename]
if ($file -eq $null) {
$file = New-Object psobject
$file | Add-Member 'FileName' $FileName
$file | Add-Member 'SizeTotal' 0
$file | Add-Member 'SizeDiff' 0
$file | Add-Member 'SizeInPackTotal' 0
$file | Add-Member 'SizeInPackDiff' 0
$file | Add-Member 'Exists' $exists
$file | Add-Member 'VersionsTotal' 0
$file | Add-Member 'VersionsDiff' 0
$files.Add($FileName, $file)
}
$file.VersionsTotal += 1
$file.SizeTotal += $size
$file.SizeInPackTotal += $size_in_pack
if ($is_diff) {
$file.VersionsDiff += 1
$file.SizeDiff += $size
$file.SizeInPackDiff += $size_in_pack
}
}
}
}
$files.Values
$cnt = 0
$directories = @{}
$files.Values | %{
$file = $_
$cnt++
Write-Progress -Activity "Aggregating $($files.Count) files into directories" -PercentComplete ($cnt * 100 / $files.Count)
#Write-Host "$($file.Filename)"
$parent = Split-GitPath $file.Filename
do {
$directory_title = $parent + '/.(total)'
#Write-Host "$($file.Filename) ==> $directory_title"
if ($parent -eq '') {
$exists = $true
} else {
$exists = Test-Path $parent
}
$directory = $directories[$directory_title]
if ($directory -eq $null) {
$directory = New-Object psobject
$directory | Add-Member 'FileName' $directory_title
$directory | Add-Member 'SizeTotal' 0
$directory | Add-Member 'SizeDiff' 0
$directory | Add-Member 'SizeInPackTotal' 0
$directory | Add-Member 'SizeInPackDiff' 0
$directory | Add-Member 'Exists' $exists
$directory | Add-Member 'VersionsTotal' 0
$directory | Add-Member 'VersionsDiff' 0
$directories.Add($directory_title, $directory)
}
$directory.SizeTotal += $file.SizeTotal
$directory.SizeDiff += $file.SizeDiff
$directory.SizeInPackTotal += $file.SizeInPackTotal
$directory.SizeInPackDiff += $file.SizeInPackDiff
$directory.VersionsTotal += $file.VersionsTotal
$directory.VersionsDiff += $file.VersionsDiff
if ($file.Exists) {
$directory_title = $parent + '/.(total-current)'
$exists = Test-Path $directory_title
$directory = $directories[$directory_title]
if ($directory -eq $null) {
$directory = New-Object psobject
$directory | Add-Member 'FileName' $directory_title
$directory | Add-Member 'SizeTotal' 0
$directory | Add-Member 'SizeDiff' 0
$directory | Add-Member 'SizeInPackTotal' 0
$directory | Add-Member 'SizeInPackDiff' 0
$directory | Add-Member 'Exists' $true
$directory | Add-Member 'VersionsTotal' 0
$directory | Add-Member 'VersionsDiff' 0
$directories.Add($directory_title, $directory)
}
$directory.SizeTotal += $file.SizeTotal
$directory.SizeDiff += $file.SizeDiff
$directory.SizeInPackTotal += $file.SizeInPackTotal
$directory.SizeInPackDiff += $file.SizeInPackDiff
$directory.VersionsTotal += $file.VersionsTotal
$directory.VersionsDiff += $file.VersionsDiff
} else {
$directory_title = $parent + '/.(total-old)'
$exists = Test-Path $directory_title
$directory = $directories[$directory_title]
if ($directory -eq $null) {
$directory = New-Object psobject
$directory | Add-Member 'FileName' $directory_title
$directory | Add-Member 'SizeTotal' 0
$directory | Add-Member 'SizeDiff' 0
$directory | Add-Member 'SizeInPackTotal' 0
$directory | Add-Member 'SizeInPackDiff' 0
$directory | Add-Member 'Exists' $false
$directory | Add-Member 'VersionsTotal' 0
$directory | Add-Member 'VersionsDiff' 0
$directories.Add($directory_title, $directory)
}
$directory.SizeTotal += $file.SizeTotal
$directory.SizeDiff += $file.SizeDiff
$directory.SizeInPackTotal += $file.SizeInPackTotal
$directory.SizeInPackDiff += $file.SizeInPackDiff
$directory.VersionsTotal += $file.VersionsTotal
$directory.VersionsDiff += $file.VersionsDiff
}
if ($parent -eq '') {
break
}
$parent = Split-GitPath $parent
} while ($true)
}
$directories.Values
popd

First download Get-GitRepositorySizes.ps1 and put in e.g. c:\scripts\

Fill $items with all size information:

cd \SourceGIT\ContactCentre
git checkout master
$items = $(c:\scripts\Get-GitRepositorySizes.ps1)

Extract useful information: All files/directories bigger than 5 MB:

$items | ?{ $_.SizeTotal -gt 5000000 } | sort FileName | Format-Table `
    -AutoSize | Out-File c:\temp\ContactCentre-Sizes-5MB.txt

Top level directory info:

$items | ?{ $_.FileName -match '^[^/]+/.(.*)$'} | sort SizeTotal -descending | Format-Table -AutoSize

Explanation of fictive items:

  • .(total-current): recursive directory size of files that currently exist in the branch that is checked out.
  • .(total-old): recursive directory size of files that don't exist in the branch that is checked out (e.g. deleted files).
  • .(total): sum of .(total-current) and .(total-old).

Explanation of most important columns:

  • SizeTotal: Total size in the repository history.
  • SizeInPackTotal: Compressed size in the repository history.
  • VersionsTotal: Total number of versions in the repository history.
  • Exists: This item exists in the current checkout.

Other columns:

  • SizeDiff: Size optimized by GIT diffs (also included in Total above).
  • SizeInPackDiff: Compressed size optimized by GIT diffs (also included in Total above).
  • VersionsDiff: Number of versions that were optimized by GIT diffs (also included in Total above).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment