Skip to content

Commit 9288450

Browse files
Add -MergedAfter / -MergedBefore to Get-GitlabMergeRequest
GitLab's REST API has no server-side merge-date filter, so the new parameters apply a client-side filter on MergedAt after the listing call returns. Bare dates (YYYY-MM-DD) are interpreted as whole-day inclusive for parity with GitHub's `merged:` search qualifier: `-MergedBefore 2026-04-21` includes MRs merged any time that day. Enables year-to-date delivery analytics that filter on merge timing independent of state, matching the capability pwsh-github added in 0.9.0.
1 parent aa1139d commit 9288450

4 files changed

Lines changed: 151 additions & 22 deletions

File tree

docs/MergeRequests/Get-GitlabMergeRequest.md

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ external help file: GitlabCli-Help.xml
44
HelpUri: https://chris-peterson.github.io/pwsh-gitlab/#/MergeRequests/Get-GitlabMergeRequest
55
Locale: en-US
66
Module Name: GitlabCli
7-
ms.date: 04/07/2026
7+
ms.date: 04/21/2026
88
PlatyPS schema version: 2024-05-01
99
title: Get-GitlabMergeRequest
1010
---
@@ -21,47 +21,50 @@ Retrieves merge requests from GitLab.
2121

2222
```
2323
Get-GitlabMergeRequest [[-MergeRequestId] <string>] [-ProjectId <string>] [-State <string>]
24-
[-CreatedAfter <string>] [-CreatedBefore <string>] [-IsDraft <bool>] [-SourceBranch <string>]
25-
[-TargetBranch <string>] [-IncludeChangeSummary] [-IncludeDiffs] [-IncludeApprovals]
26-
[-ReviewerUsername <string>] [-Scope <string>] [-MaxPages <uint>] [-All] [-SiteUrl <string>]
27-
[<CommonParameters>]
24+
[-CreatedAfter <string>] [-CreatedBefore <string>] [-MergedAfter <string>] [-MergedBefore <string>]
25+
[-IsDraft <bool>] [-SourceBranch <string>] [-TargetBranch <string>] [-IncludeChangeSummary]
26+
[-IncludeDiffs] [-IncludeApprovals] [-ReviewerUsername <string>] [-Scope <string>]
27+
[-MaxPages <uint>] [-All] [-SiteUrl <string>] [<CommonParameters>]
2828
```
2929

3030
### ByGroupId
3131

3232
```
3333
Get-GitlabMergeRequest [-GroupId] <string> [-State <string>] [-CreatedAfter <string>]
34-
[-CreatedBefore <string>] [-IsDraft <bool>] [-SourceBranch <string>] [-TargetBranch <string>]
35-
[-IncludeChangeSummary] [-IncludeDiffs] [-IncludeApprovals] [-ReviewerUsername <string>]
36-
[-Scope <string>] [-MaxPages <uint>] [-All] [-SiteUrl <string>] [<CommonParameters>]
34+
[-CreatedBefore <string>] [-MergedAfter <string>] [-MergedBefore <string>] [-IsDraft <bool>]
35+
[-SourceBranch <string>] [-TargetBranch <string>] [-IncludeChangeSummary] [-IncludeDiffs]
36+
[-IncludeApprovals] [-ReviewerUsername <string>] [-Scope <string>] [-MaxPages <uint>] [-All]
37+
[-SiteUrl <string>] [<CommonParameters>]
3738
```
3839

3940
### ByUrl
4041

4142
```
4243
Get-GitlabMergeRequest [-Url] <string> [-State <string>] [-CreatedAfter <string>]
43-
[-CreatedBefore <string>] [-IsDraft <bool>] [-SourceBranch <string>] [-TargetBranch <string>]
44-
[-IncludeChangeSummary] [-IncludeDiffs] [-IncludeApprovals] [-ReviewerUsername <string>]
45-
[-Scope <string>] [-MaxPages <uint>] [-All] [-SiteUrl <string>] [<CommonParameters>]
44+
[-CreatedBefore <string>] [-MergedAfter <string>] [-MergedBefore <string>] [-IsDraft <bool>]
45+
[-SourceBranch <string>] [-TargetBranch <string>] [-IncludeChangeSummary] [-IncludeDiffs]
46+
[-IncludeApprovals] [-ReviewerUsername <string>] [-Scope <string>] [-MaxPages <uint>] [-All]
47+
[-SiteUrl <string>] [<CommonParameters>]
4648
```
4749

4850
### ByUser
4951

5052
```
5153
Get-GitlabMergeRequest [-State <string>] [-CreatedAfter <string>] [-CreatedBefore <string>]
52-
[-IsDraft <bool>] [-SourceBranch <string>] [-TargetBranch <string>] [-IncludeChangeSummary]
53-
[-IncludeDiffs] [-IncludeApprovals] [-Username <string>] [-Role <string>]
54-
[-ReviewerUsername <string>] [-Scope <string>] [-MaxPages <uint>] [-All] [-SiteUrl <string>]
55-
[<CommonParameters>]
54+
[-MergedAfter <string>] [-MergedBefore <string>] [-IsDraft <bool>] [-SourceBranch <string>]
55+
[-TargetBranch <string>] [-IncludeChangeSummary] [-IncludeDiffs] [-IncludeApprovals]
56+
[-Username <string>] [-Role <string>] [-ReviewerUsername <string>] [-Scope <string>]
57+
[-MaxPages <uint>] [-All] [-SiteUrl <string>] [<CommonParameters>]
5658
```
5759

5860
### Mine
5961

6062
```
6163
Get-GitlabMergeRequest [-State <string>] [-CreatedAfter <string>] [-CreatedBefore <string>]
62-
[-IsDraft <bool>] [-SourceBranch <string>] [-TargetBranch <string>] [-IncludeChangeSummary]
63-
[-IncludeDiffs] [-IncludeApprovals] [-ReviewerUsername <string>] [-Mine] [-Scope <string>]
64-
[-MaxPages <uint>] [-All] [-SiteUrl <string>] [<CommonParameters>]
64+
[-MergedAfter <string>] [-MergedBefore <string>] [-IsDraft <bool>] [-SourceBranch <string>]
65+
[-TargetBranch <string>] [-IncludeChangeSummary] [-IncludeDiffs] [-IncludeApprovals]
66+
[-ReviewerUsername <string>] [-Mine] [-Scope <string>] [-MaxPages <uint>] [-All]
67+
[-SiteUrl <string>] [<CommonParameters>]
6568
```
6669

6770
## ALIASES
@@ -309,6 +312,48 @@ AcceptedValues: []
309312
HelpMessage: ''
310313
```
311314

315+
### -MergedAfter
316+
317+
Filter merge requests merged on or after this date (client-side). Accepts a bare date (YYYY-MM-DD) or a full ISO timestamp. Bare dates are interpreted as start-of-day.
318+
319+
```yaml
320+
Type: System.String
321+
DefaultValue: ''
322+
SupportsWildcards: false
323+
Aliases: []
324+
ParameterSets:
325+
- Name: (All)
326+
Position: Named
327+
IsRequired: false
328+
ValueFromPipeline: false
329+
ValueFromPipelineByPropertyName: false
330+
ValueFromRemainingArguments: false
331+
DontShow: false
332+
AcceptedValues: []
333+
HelpMessage: ''
334+
```
335+
336+
### -MergedBefore
337+
338+
Filter merge requests merged on or before this date (client-side). Accepts a bare date (YYYY-MM-DD) or a full ISO timestamp. Bare dates are interpreted as end-of-day, matching the inclusive semantics of GitHub's `merged:` search qualifier.
339+
340+
```yaml
341+
Type: System.String
342+
DefaultValue: ''
343+
SupportsWildcards: false
344+
Aliases: []
345+
ParameterSets:
346+
- Name: (All)
347+
Position: Named
348+
IsRequired: false
349+
ValueFromPipeline: false
350+
ValueFromPipelineByPropertyName: false
351+
ValueFromRemainingArguments: false
352+
DontShow: false
353+
AcceptedValues: []
354+
HelpMessage: ''
355+
```
356+
312357
### -MergeRequestId
313358

314359
The internal ID of a specific merge request to retrieve. Alias: Id.

src/GitlabCli/GitlabCli.psd1

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@{
2-
ModuleVersion = '1.170.1'
2+
ModuleVersion = '1.171.0'
33

44
RequiredModules = @(
55
@{
@@ -31,9 +31,10 @@
3131
)
3232
ReleaseNotes =
3333
@'
34-
### Fixes
35-
- `Get-GitlabMergeRequest` no longer requires being inside a git repo
36-
when querying globally (e.g. `-ReviewerUsername` without `-ProjectId`)
34+
### Features
35+
- `Get-GitlabMergeRequest` gains `-MergedAfter` / `-MergedBefore`
36+
for filtering by merge date. Bare dates are whole-day inclusive,
37+
matching the semantics of GitHub's `merged:` search qualifier.
3738
'@
3839
}
3940
}

src/GitlabCli/MergeRequests.psm1

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ function Get-GitlabMergeRequest {
3333
[GitlabDate()][string]
3434
$CreatedBefore,
3535

36+
[Parameter()]
37+
[string]
38+
$MergedAfter,
39+
40+
[Parameter()]
41+
[string]
42+
$MergedBefore,
43+
3644
[TrueOrFalse()][bool]
3745
$IsDraft,
3846

@@ -179,6 +187,25 @@ function Get-GitlabMergeRequest {
179187
}
180188
}
181189

190+
# GitLab's REST API has no merged-date filter, so apply client-side.
191+
# Bare dates are interpreted as whole days for parity with GitHub's `merged:`
192+
# qualifier: -MergedAfter '2026-01-01' includes MRs merged any time that day;
193+
# -MergedBefore '2026-04-21' includes MRs merged any time that day.
194+
if ($MergedAfter -or $MergedBefore) {
195+
$MergedAfterDate = if ($MergedAfter) { [datetime]$MergedAfter } else { $null }
196+
$MergedBeforeDate = if ($MergedBefore) {
197+
$d = [datetime]$MergedBefore
198+
if ($MergedBefore -notmatch 'T') { $d.AddDays(1).AddTicks(-1) } else { $d }
199+
} else { $null }
200+
$MergeRequests = $MergeRequests | Where-Object {
201+
if (-not $_.MergedAt) { return $false }
202+
$MergedAt = [datetime]$_.MergedAt
203+
if ($MergedAfterDate -and $MergedAt -lt $MergedAfterDate) { return $false }
204+
if ($MergedBeforeDate -and $MergedAt -gt $MergedBeforeDate) { return $false }
205+
$true
206+
}
207+
}
208+
182209
$MergeRequests | Sort-Object ProjectPath
183210
}
184211

tests/Get-GitlabMergeRequest.Tests.ps1

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,60 @@ Describe "Get-GitlabMergeRequest" {
183183
}
184184
}
185185
}
186+
187+
Context "-MergedAfter / -MergedBefore" {
188+
It "Should filter MRs merged before the MergedAfter cutoff" {
189+
Mock -CommandName Invoke-GitlabApi -ModuleName $TestModuleName -MockWith {
190+
@(
191+
[PSCustomObject]@{ MergedAt = '2023-06-15T00:00:00Z'; ProjectPath = 'p' },
192+
[PSCustomObject]@{ MergedAt = '2024-06-15T00:00:00Z'; ProjectPath = 'p' }
193+
)
194+
}
195+
196+
$result = Get-GitlabMergeRequest -Mine -MergedAfter '2024-01-01'
197+
198+
$result.Count | Should -Be 1
199+
$result[0].MergedAt | Should -Be '2024-06-15T00:00:00Z'
200+
}
201+
202+
It "Should filter MRs merged after the MergedBefore cutoff" {
203+
Mock -CommandName Invoke-GitlabApi -ModuleName $TestModuleName -MockWith {
204+
@(
205+
[PSCustomObject]@{ MergedAt = '2024-06-15T00:00:00Z'; ProjectPath = 'p' },
206+
[PSCustomObject]@{ MergedAt = '2025-06-15T00:00:00Z'; ProjectPath = 'p' }
207+
)
208+
}
209+
210+
$result = Get-GitlabMergeRequest -Mine -MergedBefore '2024-12-31'
211+
212+
$result.Count | Should -Be 1
213+
$result[0].MergedAt | Should -Be '2024-06-15T00:00:00Z'
214+
}
215+
216+
It "Should treat bare-date MergedBefore as whole-day inclusive" {
217+
Mock -CommandName Invoke-GitlabApi -ModuleName $TestModuleName -MockWith {
218+
@(
219+
[PSCustomObject]@{ MergedAt = '2024-12-31T23:30:00Z'; ProjectPath = 'p' }
220+
)
221+
}
222+
223+
$result = Get-GitlabMergeRequest -Mine -MergedBefore '2024-12-31'
224+
225+
$result.Count | Should -Be 1
226+
}
227+
228+
It "Should exclude unmerged MRs when MergedAfter is set" {
229+
Mock -CommandName Invoke-GitlabApi -ModuleName $TestModuleName -MockWith {
230+
@(
231+
[PSCustomObject]@{ MergedAt = $null; ProjectPath = 'p' },
232+
[PSCustomObject]@{ MergedAt = '2024-06-15T00:00:00Z'; ProjectPath = 'p' }
233+
)
234+
}
235+
236+
$result = Get-GitlabMergeRequest -Mine -MergedAfter '2024-01-01'
237+
238+
$result.Count | Should -Be 1
239+
$result[0].MergedAt | Should -Be '2024-06-15T00:00:00Z'
240+
}
241+
}
186242
}

0 commit comments

Comments
 (0)