Skip to content

Instantly share code, notes, and snippets.

@chamindac
Created October 23, 2018 13:38
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 chamindac/ceff993f04ed0aa5a1b592f25ee1d2e3 to your computer and use it in GitHub Desktop.
Save chamindac/ceff993f04ed0aa5a1b592f25ee1d2e3 to your computer and use it in GitHub Desktop.
Get most frequently modified Azure DevOps git repo files in a Team Project .\GetMostFrequentlyModifiedFiles.ps1 -token 'yourPAT' -fromDate '5/02/2018' -collectionUri 'https://dev.azure.com/yourAccount' -teamProjectName 'yourteamProject' -repoName @('repo1*', '*corereop*') -branchNameFilter @('master*','develop*')
param(
[Parameter(Mandatory=$true)]
[string] $token,
[Parameter(Mandatory=$true)]
[string] $fromDate,
[Parameter(Mandatory=$true)]
[string] $collectionUri,
[Parameter(Mandatory=$true)]
[string] $teamProjectName,
[string []] $repoNameFilter = @('*'),
[string[]] $branchNameFilter = @('*')
)
$User=""
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$token)));
$header = @{Authorization=("Basic {0}" -f $base64AuthInfo)};
$reportName = 'MostFrequentlyModifiedFiles.csv'
If (Test-Path $reportName){
Remove-Item $reportName
}
$tabName = "FileCommitsTable"
#Create Table object
$FileCommitsTable = New-Object system.Data.DataTable “$tabName”
#Define Columns
$colKey = New-Object system.Data.DataColumn Key,([string])
$colFilePath = New-Object system.Data.DataColumn FilePath,([string])
$colBranchName = New-Object system.Data.DataColumn BranchName,([string])
$colRepoName = New-Object system.Data.DataColumn RepoName,([string])
$colCommitCount = New-Object system.Data.DataColumn CommitCount,([int])
$colLastCommitOn = New-Object system.Data.DataColumn LastCommitOn,([datetime])
$colLastCommitter = New-Object system.Data.DataColumn LastCommitter,([string])
$colLastCommitComment = New-Object system.Data.DataColumn LastCommitComment,([string])
$colRepoUrl = New-Object system.Data.DataColumn RepoUrl,([string])
$colBranchUrl = New-Object system.Data.DataColumn BranchUrl,([string])
$colLastCommitUrl = New-Object system.Data.DataColumn LastCommitUrl,([string])
#Add the Columns
$FileCommitsTable.columns.add($colKey)
$FileCommitsTable.columns.add($colFilePath)
$FileCommitsTable.columns.add($colBranchName)
$FileCommitsTable.columns.add($colRepoName)
$FileCommitsTable.columns.add($colCommitCount)
$FileCommitsTable.columns.add($colLastCommitOn)
$FileCommitsTable.columns.add($colLastCommitter)
$FileCommitsTable.columns.add($colLastCommitComment)
$FileCommitsTable.columns.add($colRepoUrl)
$FileCommitsTable.columns.add($colBranchUrl)
$FileCommitsTable.columns.add($colLastCommitUrl)
$FileCommitsTable.primarykey = $FileCommitsTable.columns[0];
#Git
$Uri = $collectionUri + '/' + $teamProjectName +'/_apis/git/repositories?api-version=4.1'
$gitRepos = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -Headers $header
foreach($gitRepo in $gitRepos.value)
{
$processThisRepo = $false;
foreach($repoNameFilterItem in $repoNameFilter)
{
if($gitRepo.Name -like $repoNameFilterItem)
{
$processThisRepo = $true;
break;
}
}
If ($processThisRepo)
{
Write-Host ('Processing repo:' + $gitRepo.Name)
$Uri = $collectionUri + '/' + $teamProjectName +'/_apis/git/repositories/' + $gitRepo.id + '/refs?includeLinks=true&includeStatuses=true&latestStatusesOnly=true&peelTags=true&api-version=4.1'
$repoBranches = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -Headers $header
foreach($repoBranch in $repoBranches.value)
{
if ($repoBranch.name -like 'refs/heads/*')
{
$processThisBranch = $false;
$branchName = $repoBranch.name -replace 'refs/heads/', '';
$branchUrl = $collectionUri + '/' + $teamProjectName + '/_git/' + $sortedRepo.key + '?version=GB' + $branchName
foreach($branchNameFilterItem in $branchNameFilter)
{
if($branchName -like $branchNameFilterItem)
{
$processThisBranch = $true;
break;
}
}
If ($processThisBranch)
{
Write-Host ('Processing branch:' + $branchName)
$top=100;
$skip=0;
while($true)
{
$Uri = $collectionUri + '/' + $teamProjectName + '/_apis/git/repositories/' + $gitRepo.id + '/commits?searchCriteria.includeLinks=true&searchCriteria.compareVersion.version=' + $branchName + '&searchCriteria.compareVersion.versionType=branch&searchCriteria.fromDate=' + $fromDate + '&searchCriteria.$skip=' + $skip + '&searchCriteria.$top=' + $top + '&api-version=4.1'
$commits = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -Headers $header
$skip+=$top;
if($commits.count -le 0)
{
break;
}
foreach($commit in $commits.value) {
$Uri = $commit._links.changes.href
$changes = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -Headers $header
foreach($change in $changes) {
if (($change.changes.GetEnumerator().Item.gitObjectType -notcontains 'tree').count -gt 0)
{
if ($change.changes.Count -gt 1)
{
$fileChanges = $change.changes.GetEnumerator().Item.Where({$_.gitObjectType -ne 'tree'})
}
else
{
$fileChanges = $change.changes.Where({$_.gitObjectType -ne 'tree'})[0].item
}
foreach ($fileChange in $fileChanges){
$fileKey = $gitRepo.Name + $branchName + $fileChange.path
if ($FileCommitsTable.Rows.Key -contains $fileKey)
{
$row = $FileCommitsTable.Rows.Where({$_.Key -eq $fileKey}).foreach({$_.CommitCount += 1})
}
else
{
#Create a row
$row = $FileCommitsTable.NewRow()
#Enter data in the row
$row.Key = $fileKey;
$row.FilePath = $fileChange.path
$row.BranchName = $branchName
$row.RepoName = $gitRepo.Name
$row.CommitCount = 1
$row.LastCommitOn = $commit.committer.date
$row.LastCommitter = $commit.committer.name
$row.LastCommitComment = $commit.comment
$row.RepoUrl = $gitRepo.remoteUrl
$row.BranchUrl = $branchUrl
$row.LastCommitUrl = $collectionUri + '/' + $teamProjectName +'/_git/' + $gitRepo.id + '/commit/'+ $commit.commitId
#Add the row to the table
$FileCommitsTable.Rows.Add($row);
}
}
}
}
}
}
}
}
}
}
}
$SortedFileCommits = ($FileCommitsTable |sort CommitCount -Descending | Select-Object CommitCount, FilePath, BranchName, RepoName, LastCommitOn, LastCommitter, LastCommitComment, BranchUrl, RepoUrl, LastCommitUrl)
$SortedFileCommits | export-csv $reportName -notypeinformation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment