Public/Get-GitChangedFile.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
function Get-GitChangedFile {
    <#
    .SYNOPSIS
        Get a list of files changed in a git commit

    .FUNCTIONALITY
        CI/CD

    .DESCRIPTION
        Get a list of files changed in a git commit

    .PARAMETER Path
        Path to git repo. Defaults to the current working path

    .PARAMETER Commit
        Commit hash

    .PARAMETER Include
        If specified, only return files that are '-like'
        an item in the -Include

    .PARAMETER Exclude
        If specified, exclude any files that are '-like'
        an item in the -Include

    .EXAMPLE
        Get-GitChangedFile
        # Get files changed in the most recent commit
        # Use the current directory as the git repo path

    .EXAMPLE
        Get-GitChangedFile -Path \\Path\To\Git\Repo
        # Get files changed in the most recent commit
        # Use \\Path\To\Git\Repo as the git repo path

    .Example
        Get-GitChangedFile -Commit 3d6b25ebbc6bbf961a4c1045548bc9ff90879bc6

        # Get files changed in commit 3d6b25ebbc6bbf961a4c1045548bc9ff90879bc6,
        # Use the current directory as the git repo path

    .LINK
        https://github.com/RamblingCookieMonster/BuildHelpers

    .LINK
        about_BuildHelpers
    #>

    [cmdletbinding()]
    param(
        [validateScript({ Test-Path $_ -PathType Container })]
        $Path = $PWD.Path,

        $Commit,

        [string[]]$Include,

        [string[]]$Exclude
    )
    $Path = (Resolve-Path $Path).Path
    $GitPathRaw = Invoke-Git rev-parse --show-toplevel -Path $Path
    Write-Verbose "Found git root [$GitPathRaw]"
    $GitPath = Resolve-Path $GitPathRaw
    if(Test-Path $GitPath)
    {
        Write-Verbose "Using [$GitPath] as repo root"
    }
    else
    {
        throw "Could not find root of git repo under [$Path]. Tried [$GitPath]"
    }

    if(-not $PSBoundParameters.ContainsKey('Commit'))
    {
        $Commit = Invoke-Git rev-parse HEAD -Path $GitPath
    }
    if(-not $Commit)
    {
        return
    }

    [string[]]$Files = Invoke-Git "diff-tree --no-commit-id --name-only -r $Commit" -Path $GitPath
    if($Files.Count -gt 0)
    {
        $Params = @{Collection = $Files}
        Write-Verbose "Found [$($Files.Count)] files with raw values:`n$($Files | Foreach {"'$_'"} | Out-String)"
        if($Include)
        {
            $Files = Invoke-LikeFilter @params -FilterArray $Include
        }
        if($Exclude)
        {
            $Files = Invoke-LikeFilter @params -FilterArray $Exclude -Not
        }
        foreach($item in $Files)
        {
            ( Resolve-Path (Join-Path $GitPath $Item) ).Path
        }
    }
    else
    {
        Write-Warning "Something went wrong, no files returned:`nIs [$Path], with repo root [$GitPath] a valid git path?"
    }
}