Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c220b09
Download all trees for non-prefetched commits when root tree is downl…
tyrielv Jun 27, 2025
fb77a47
Prefetch in background when cloning if pack indexes are not trusted
tyrielv Jun 27, 2025
2ad18e8
Merge pull request #1849 from tyrielv/async-prefetch
tyrielv Jul 9, 2025
8ac9ad0
Revise commit batch
Jul 10, 2025
240f73e
Update to windows-2025, upgrade to .NET 4.7.1
Jul 23, 2025
d6f30ef
Make expected versions consistent
tyrielv Aug 12, 2025
3e720b9
Merge pull request #1852 from tyrielv/upgrade-workflow-image
mjcheetham Aug 13, 2025
170745b
GitVersion: support release candidate versions
mjcheetham Aug 7, 2025
e30e98f
GitVersion: drop unused installer version parsing
mjcheetham Aug 7, 2025
60f78a4
Merge pull request #1854 from mjcheetham/version-parsing
mjcheetham Aug 13, 2025
8a98e51
build: stop creating/uploading GVFS.Installers nupkg
mjcheetham Jul 28, 2025
f215829
build: download microsoft/git installers from GitHub
mjcheetham Jul 28, 2025
3d6f13d
ft: install arch-specific msftgit and print OS version
mjcheetham Jul 28, 2025
e66befe
ft: run functional tests on ARM64
mjcheetham Jul 28, 2025
3b6c223
Functional Tests: refactor out output filtering
mjcheetham Jul 28, 2025
7e4e345
Functional Tests: when filtering Git output, retain newlines faithfully
dscho Aug 13, 2025
23001d5
Functional Tests: support retaining empty lines in FilterMessages()
dscho Aug 13, 2025
3c364c3
Functional Tests: account for 'partially-hydrated checkout' messages
mjcheetham Jul 28, 2025
c69ba8e
Functional Tests: heed Postel's law regarding `core.FSMonitor`
dscho Aug 13, 2025
f2bc533
Merge pull request #1853 from mjcheetham/gh-msgit
mjcheetham Aug 14, 2025
6635341
Merge remote-tracking branch 'upstream/master' into commit-batch
tyrielv Aug 14, 2025
86f7b43
Download all trees for non-prefetched commits when root tree is downl…
tyrielv Aug 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .azure-pipelines/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 5.0.201
version: 8.0.413

- task: CmdLine@2
displayName: Build VFS for Git
Expand Down
53 changes: 41 additions & 12 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,38 @@ on:
branches: [ master, releases/shipped ]
push:
branches: [ master, releases/shipped ]
workflow_dispatch:
inputs:
git_version:
description: 'Microsoft Git version tag to include in the build (leave empty for default)'
required: false
type: string

env:
GIT_VERSION: ${{ github.event.inputs.git_version || 'v2.50.1.vfs.0.1' }}

jobs:
validate:
runs-on: windows-2025
name: Validation
steps:
- name: Checkout source
uses: actions/checkout@v4

- name: Validate Microsoft Git version
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
& "$env:GITHUB_WORKSPACE\.github\workflows\scripts\validate_release.ps1" `
-Repository microsoft/git `
-Tag $env:GIT_VERSION && `
Write-Host ::notice title=Validation::Using microsoft/git version $env:GIT_VERSION

build:
runs-on: windows-2019
runs-on: windows-2025
name: Build and Unit Test
needs: validate

strategy:
matrix:
Expand All @@ -24,7 +51,7 @@ jobs:
- name: Install .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 5.0.201
dotnet-version: 8.0.413

- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v2.0.0
Expand All @@ -41,6 +68,13 @@ jobs:
shell: cmd
run: src\scripts\CreateBuildArtifacts.bat ${{ matrix.configuration }} artifacts

- name: Download microsoft/git installers
shell: cmd
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release download %GIT_VERSION% --repo microsoft/git --pattern "Git*.exe" --dir artifacts\GVFS.Installers

- name: Upload functional tests drop
uses: actions/upload-artifact@v4
with:
Expand All @@ -59,20 +93,15 @@ jobs:
name: Installers_${{ matrix.configuration }}
path: artifacts\GVFS.Installers

- name: Upload NuGet packages
uses: actions/upload-artifact@v4
with:
name: NuGetPackages_${{ matrix.configuration }}
path: artifacts\NuGetPackages

functional_test:
runs-on: windows-2019
runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
name: Functional Tests
needs: build

strategy:
matrix:
configuration: [ Debug, Release ]
architecture: [ x86_64, arm64 ]

steps:
- name: Download installers
Expand Down Expand Up @@ -103,7 +132,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: InstallationLogs_${{ matrix.configuration }}
name: InstallationLogs_${{ matrix.configuration }}_${{ matrix.architecture }}
path: install\logs

- name: Run functional tests
Expand All @@ -117,14 +146,14 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: FunctionalTests_Results_${{ matrix.configuration }}
name: FunctionalTests_Results_${{ matrix.configuration }}_${{ matrix.architecture }}
path: TestResult.xml

- name: Upload Git trace2 output
if: always()
uses: actions/upload-artifact@v4
with:
name: GitTrace2_${{ matrix.configuration }}
name: GitTrace2_${{ matrix.configuration }}_${{ matrix.architecture }}
path: C:\temp\git-trace2.log

- name: ProjFS details (post-test)
Expand Down
124 changes: 124 additions & 0 deletions .github/workflows/scripts/validate_release.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
param(
[Parameter(Mandatory=$true)]
[string]$Tag,

[Parameter(Mandatory=$true)]
[string]$Repository
)

function Write-GitHubActionsCommand {
param(
[Parameter(Mandatory=$true)]
[string]$Command,

[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$true)]
[string]$Title
)

Write-Host "::$Command title=$Title::$Message"
}


function Write-GitHubActionsWarning {
param(
[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$false)]
[string]$Title = "Warning"
)

if ($env:GITHUB_ACTIONS -eq "true") {
Write-GitHubActionsCommand -Command "warning" -Message $Message -Title $Title
} else {
Write-Host "! Warning: $Message" -ForegroundColor Yellow
}
}

function Write-GitHubActionsError {
param(
[Parameter(Mandatory=$true)]
[string]$Message,

[Parameter(Mandatory=$false)]
[string]$Title = "Error"
)

if ($env:GITHUB_ACTIONS -eq "true") {
Write-GitHubActionsCommand -Command "error" -Message $Message -Title $Title
} else {
Write-Host "x Error: $Message" -ForegroundColor Red
}
}

if ([string]::IsNullOrWhiteSpace($Tag)) {
Write-GitHubActionsError -Message "Tag parameter is required"
exit 1
}

if ([string]::IsNullOrWhiteSpace($Repository)) {
Write-GitHubActionsError -Message "Repository parameter is required"
exit 1
}

Write-Host "Validating $Repository release '$Tag'..."

# Prepare headers for GitHub API
$headers = @{
'Accept' = 'application/vnd.github.v3+json'
'User-Agent' = 'VFSForGit-Build'
}

if ($env:GITHUB_TOKEN) {
$headers['Authorization'] = "Bearer $env:GITHUB_TOKEN"
}

# Check if the tag exists in microsoft/git repository
try {
$releaseResponse = Invoke-RestMethod `
-Uri "https://api.github.com/repos/$Repository/releases/tags/$Tag" `
-Headers $headers

Write-Host "✓ Tag '$Tag' found in $Repository" -ForegroundColor Green
Write-Host " Release : $($releaseResponse.name)"
Write-Host " Published : $($releaseResponse.published_at.ToString('u'))"

# Check if this a pre-release
if ($releaseResponse.prerelease -eq $true) {
Write-GitHubActionsWarning `
-Message "Using a pre-released version of $Repository" `
-Title "Pre-release $Repository version"
}

# Get the latest release for comparison
try {
$latestResponse = Invoke-RestMethod `
-Uri "https://api.github.com/repos/$Repository/releases/latest" `
-Headers $headers
$latestTag = $latestResponse.tag_name

# Check if this is the latest release
if ($Tag -eq $latestTag) {
Write-Host "✓ Using the latest release" -ForegroundColor Green
exit 0
}

# Not the latest!
$warningTitle = "Outdated $Repository release"
$warningMsg = "Not using latest release of $Repository (latest: $latestTag)"
Write-GitHubActionsWarning -Message $warningMsg -Title $warningTitle
} catch {
Write-GitHubActionsWarning -Message "Could not check latest release info for ${Repository}: $($_.Exception.Message)"
}
} catch {
if ($_.Exception.Response.StatusCode -eq 404) {
Write-GitHubActionsError -Message "Tag '$Tag' does not exist in $Repository"
exit 1
} else {
Write-GitHubActionsError -Message "Error validating release '$Tag': $($_.Exception.Message)"
exit 1
}
}
13 changes: 7 additions & 6 deletions .vsconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
"version": "1.0",
"components": [
"Microsoft.Component.MSBuild",
"Microsoft.VisualStudio.Workload.NativeDesktop"
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.1.SDK",
"Microsoft.Net.Core.Component.SDK.8.0",
"Microsoft.VisualStudio.Component.VC.v143.x86.x64",
"Microsoft.VisualStudio.Component.Windows11SDK.26100",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.Net.Core.Component.SDK.2.1",
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.1.SDK",
"Microsoft.VisualStudio.Workload.NetCoreTools"
]
}
2 changes: 1 addition & 1 deletion GVFS/FastFetch/FastFetch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
<TargetFramework>net471</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Expand Down
13 changes: 13 additions & 0 deletions GVFS/GVFS.Common/Enlistment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,18 @@ public virtual GitProcess CreateGitProcess()
{
return new GitProcess(this);
}

public bool GetTrustPackIndexesConfig()
{
var gitProcess = this.CreateGitProcess();
bool trustPackIndexes = true;
if (gitProcess.TryGetFromConfig(GVFSConstants.GitConfig.TrustPackIndexes, forceOutsideEnlistment: false, out var valueString)
&& bool.TryParse(valueString, out var trustPackIndexesConfig))
{
trustPackIndexes = trustPackIndexesConfig;
}

return trustPackIndexes;
}
}
}
3 changes: 2 additions & 1 deletion GVFS/GVFS.Common/GVFS.Common.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<TargetFramework>net471</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

Expand All @@ -13,6 +13,7 @@
</ItemGroup>

<ItemGroup>
<Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
</ItemGroup>

Expand Down
7 changes: 1 addition & 6 deletions GVFS/GVFS.Common/Git/GitObjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,7 @@ public virtual bool TryDownloadPrefetchPacks(GitProcess gitProcess, long latestT
* pack file and an index file that do not match.
* Eventually we will make this the default, but it has a high performance cost for the first prefetch after
* cloning a large repository, so it must be explicitly enabled for now. */
bool trustPackIndexes = true;
if (gitProcess.TryGetFromConfig(GVFSConstants.GitConfig.TrustPackIndexes, forceOutsideEnlistment: false, out var valueString)
&& bool.TryParse(valueString, out var trustPackIndexesConfig))
{
trustPackIndexes = trustPackIndexesConfig;
}
bool trustPackIndexes = this.Enlistment.GetTrustPackIndexesConfig();
metadata.Add("trustPackIndexes", trustPackIndexes);

long requestId = HttpRequestor.GetNewRequestId();
Expand Down
11 changes: 7 additions & 4 deletions GVFS/GVFS.Common/Git/GitRepo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using static GVFS.Common.Git.LibGit2Repo;

namespace GVFS.Common.Git
{
Expand Down Expand Up @@ -60,9 +61,9 @@ public void OpenRepo()
this.libgit2RepoInvoker?.InitializeSharedRepo();
}

public bool TryGetIsBlob(string sha, out bool isBlob)
public bool TryGetObjectType(string sha, out Native.ObjectTypes? objectType)
{
return this.libgit2RepoInvoker.TryInvoke(repo => repo.IsBlob(sha), out isBlob);
return this.libgit2RepoInvoker.TryInvoke(repo => repo.GetObjectType(sha), out objectType);
}

public virtual bool TryCopyBlobContentStream(string blobSha, Action<Stream, long> writeAction)
Expand All @@ -86,10 +87,12 @@ public virtual bool TryCopyBlobContentStream(string blobSha, Action<Stream, long
return copyBlobResult;
}

public virtual bool CommitAndRootTreeExists(string commitSha)
public virtual bool CommitAndRootTreeExists(string commitSha, out string rootTreeSha)
{
bool output = false;
this.libgit2RepoInvoker.TryInvoke(repo => repo.CommitAndRootTreeExists(commitSha), out output);
string treeShaLocal = null;
this.libgit2RepoInvoker.TryInvoke(repo => repo.CommitAndRootTreeExists(commitSha, out treeShaLocal), out output);
rootTreeSha = treeShaLocal;
return output;
}

Expand Down
Loading
Loading