diff --git a/CSharp/TfsCmdlets/Cmdlets/Git/GetGitRepository.cs b/CSharp/TfsCmdlets/Cmdlets/Git/GetGitRepository.cs
index 0e9c6e8a..f15cbc15 100644
--- a/CSharp/TfsCmdlets/Cmdlets/Git/GetGitRepository.cs
+++ b/CSharp/TfsCmdlets/Cmdlets/Git/GetGitRepository.cs
@@ -1,5 +1,8 @@
+using System;
using System.Management.Automation;
using Microsoft.TeamFoundation.SourceControl.WebApi;
+using System.Linq;
+using System.Collections.Generic;
namespace TfsCmdlets.Cmdlets.Git
{
@@ -30,6 +33,12 @@ partial class GetGitRepository
///
[Parameter()]
public SwitchParameter IncludeParent { get; set; }
+
+ ///
+ /// Includes repositories in the recycle bin in the search results.
+ ///
+ [Parameter()]
+ public SwitchParameter IncludeRecycleBin { get; set; }
}
[CmdletController(typeof(GitRepository), Client=typeof(IGitHttpClient))]
@@ -37,6 +46,15 @@ partial class GetGitRepositoryController
{
protected override IEnumerable Run()
{
+ // Get recycle bin repositories once if needed
+ IList recycleBinRepos = null;
+ if (IncludeRecycleBin)
+ {
+ recycleBinRepos = Client
+ .GetRecycleBinRepositoriesAsync(Project.Name)
+ .GetResult("Error getting recycle bin repositories");
+ }
+
foreach (var input in Repository)
{
var repository = input switch
@@ -59,6 +77,16 @@ string s when string.IsNullOrEmpty(s) => Project.Name,
yield return Client
.GetRepositoryAsync(Project.Name, guid, includeParent: IncludeParent)
.GetResult($"Error getting repository with ID {guid}");
+
+ // Also check recycle bin for this ID
+ if (IncludeRecycleBin)
+ {
+ var deletedRepo = recycleBinRepos?.FirstOrDefault(r => r.Id == guid);
+ if (deletedRepo != null)
+ {
+ yield return deletedRepo;
+ }
+ }
break;
}
case { } when Default:
@@ -70,30 +98,48 @@ string s when string.IsNullOrEmpty(s) => Project.Name,
}
case string s when !s.IsWildcard():
{
- GitRepository result;
+ GitRepository result = null;
try
{
result = Client
.GetRepositoryAsync(Project.Name, s, includeParent: IncludeParent)
.GetResult($"Error getting repository '{s}'");
+ yield return result;
}
catch
{
// Workaround to retrieve disabled repositories
- result = Client
+ var activeRepo = Client
.GetRepositoriesAsync(Project.Name, includeLinks: true, includeHidden: true)
.GetResult($"Error getting repository(ies) '{s}'")
- .First(r => r.Name.Equals(s, StringComparison.OrdinalIgnoreCase));
+ .FirstOrDefault(r => r.Name.Equals(s, StringComparison.OrdinalIgnoreCase));
- if (IncludeParent)
+ if (activeRepo != null)
{
- result = Client
- .GetRepositoryAsync(Project.Name, result.Id, includeParent: true)
- .GetResult($"Error getting repository(ies) '{s}'");
+ if (IncludeParent)
+ {
+ result = Client
+ .GetRepositoryAsync(Project.Name, activeRepo.Id, includeParent: true)
+ .GetResult($"Error getting repository(ies) '{s}'");
+ yield return result;
+ }
+ else
+ {
+ yield return activeRepo;
+ }
+ }
+ }
+
+ // Also check recycle bin for this name
+ if (IncludeRecycleBin)
+ {
+ var deletedRepo = recycleBinRepos?.FirstOrDefault(r => r.Name.Equals(s, StringComparison.OrdinalIgnoreCase));
+ if (deletedRepo != null)
+ {
+ yield return deletedRepo;
}
}
- yield return result;
break;
}
case string s:
@@ -114,6 +160,15 @@ string s when string.IsNullOrEmpty(s) => Project.Name,
yield return repo;
}
}
+
+ // Also check recycle bin for wildcard patterns
+ if (IncludeRecycleBin)
+ {
+ foreach (var deletedRepo in recycleBinRepos?.Where(r => r.Name.IsLike(s)) ?? Enumerable.Empty())
+ {
+ yield return deletedRepo;
+ }
+ }
break;
}
default:
diff --git a/Docs/Get-TfsGitRepository-RecycleBin.md b/Docs/Get-TfsGitRepository-RecycleBin.md
new file mode 100644
index 00000000..57cf6351
--- /dev/null
+++ b/Docs/Get-TfsGitRepository-RecycleBin.md
@@ -0,0 +1,52 @@
+# Using Get-TfsGitRepository with Recycle Bin
+
+The `Get-TfsGitRepository` cmdlet now supports retrieving repositories from the Recycle Bin using the `-IncludeRecycleBin` parameter.
+
+## Examples
+
+### Get all repositories including those in the recycle bin
+```powershell
+Get-TfsGitRepository -Repository '*' -IncludeRecycleBin -Project 'MyProject'
+```
+
+### Find a specific deleted repository by name
+```powershell
+Get-TfsGitRepository -Repository 'DeletedRepo' -IncludeRecycleBin -Project 'MyProject'
+```
+
+### Find deleted repositories matching a pattern
+```powershell
+Get-TfsGitRepository -Repository 'Old*' -IncludeRecycleBin -Project 'MyProject'
+```
+
+### Find a deleted repository by ID
+```powershell
+Get-TfsGitRepository -Repository '12345678-1234-1234-1234-123456789012' -IncludeRecycleBin -Project 'MyProject'
+```
+
+## Output Types
+
+When `-IncludeRecycleBin` is used, the cmdlet may return two types of objects:
+
+- **GitRepository**: Active repositories
+- **GitDeletedRepository**: Deleted repositories from the recycle bin
+
+### GitDeletedRepository Properties
+
+The `GitDeletedRepository` object includes the following properties:
+
+- `Id`: The repository ID
+- `Name`: The repository name
+- `ProjectReference`: Reference to the team project
+- `DeletedBy`: The user who deleted the repository
+- `CreatedDate`: When the repository was originally created
+- `DeletedDate`: When the repository was deleted
+
+## API Reference
+
+This feature uses the Azure DevOps REST API endpoint:
+```
+GET https://dev.azure.com/{organization}/{project}/_apis/git/recycleBin/repositories?api-version=7.1
+```
+
+For more information, see the [official Azure DevOps REST API documentation](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/get-recycle-bin-repositories?view=azure-devops-rest-7.1).
\ No newline at end of file
diff --git a/PS/_Tests/Git/GetTfsGitRepository-RecycleBin.Tests.ps1 b/PS/_Tests/Git/GetTfsGitRepository-RecycleBin.Tests.ps1
new file mode 100644
index 00000000..d8c12a9a
--- /dev/null
+++ b/PS/_Tests/Git/GetTfsGitRepository-RecycleBin.Tests.ps1
@@ -0,0 +1,76 @@
+& "$(($PSScriptRoot -split '_Tests')[0])/_Tests/_TestSetup.ps1"
+
+Describe (($MyInvocation.MyCommand.Name -split '\.')[-3]) {
+
+ Context 'Get repositories including recycle bin' {
+ # Get-TfsGitRepository
+ # [[-Repository]