Skip to content

Commit

Permalink
Merge pull request #1807 from microsoft/milestones/m193
Browse files Browse the repository at this point in the history
[Release] Milestone M193
  • Loading branch information
vdye authored Mar 12, 2024
2 parents 77bc5a4 + 55ba68d commit 1efd105
Show file tree
Hide file tree
Showing 32 changed files with 388 additions and 348 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
- name: Run functional tests
shell: cmd
run: |
SET PATH=C:\Program Files\GVFS;%PATH%
SET PATH=C:\Program Files\VFS for Git;%PATH%
SET GIT_TRACE2_PERF=C:\temp\git-trace2.log
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci
Expand Down
45 changes: 14 additions & 31 deletions .github/workflows/release-winget.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,18 @@ on:

jobs:
release:
runs-on: ubuntu-latest
runs-on: windows-latest
steps:
- id: update-winget
name: Update winget repository
uses: mjcheetham/update-winget@v1.2.2
with:
id: Microsoft.VFSforGit
token: ${{ secrets.WINGET_TOKEN }}
releaseAsset: SetupGVFS.([0-9.]*)\.exe
manifestText: |
PackageIdentifier: {{id}}
PackageVersion: {{version}}
PackageName: VFS for Git
Publisher: Microsoft Corporation
Moniker: vfs-for-git
PackageUrl: https://aka.ms/vfs-for-git
Tags:
- vfs for git
- vfs-for-git
- vfsforgit
- gvfs
License: Copyright (C) Microsoft Corporation
ShortDescription: Virtual File System for Git - a tool to scale Git for monorepo scenarios.
Installers:
- Architecture: x64
InstallerUrl: {{url}}
InstallerType: inno
InstallerSha256: {{sha256}}
PackageLocale: en-US
ManifestType: singleton
ManifestVersion: 1.0.0
alwaysUsePullRequest: true
- name: Publish manifest with winget-create
run: |
# Get correct release asset
$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json
$asset = $github.release.assets | Where-Object -Property name -match 'SetupGVFS[\d\.]*.exe'
# Remove 'v' from the version
$version = $github.release.tag_name -replace ".v",""
# Download and run wingetcreate
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
.\wingetcreate.exe update Microsoft.VFSforGit -u $asset.browser_download_url -v $version -o manifests -t "${{ secrets.WINGET_TOKEN }}" -s
shell: powershell
150 changes: 78 additions & 72 deletions GVFS/FastFetch/CheckoutPrefetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,85 +72,99 @@ public override void Prefetch(string branchOrCommit, bool isBranch)
commitToFetch = branchOrCommit;
}

this.DownloadMissingCommit(commitToFetch, this.GitObjects);

// Configure pipeline
// Checkout uses DiffHelper when running checkout.Start(), which we use instead of LsTreeHelper
// Checkout diff output => FindBlobs => BatchDownload => IndexPack => Checkout available blobs
CheckoutStage checkout = new CheckoutStage(this.checkoutThreadCount, this.FolderList, commitToFetch, this.Tracer, this.Enlistment, this.forceCheckout);
FindBlobsStage blobFinder = new FindBlobsStage(this.SearchThreadCount, checkout.RequiredBlobs, checkout.AvailableBlobShas, this.Tracer, this.Enlistment);
BatchObjectDownloadStage downloader = new BatchObjectDownloadStage(this.DownloadThreadCount, this.ChunkSize, blobFinder.MissingBlobs, checkout.AvailableBlobShas, this.Tracer, this.Enlistment, this.ObjectRequestor, this.GitObjects);
IndexPackStage packIndexer = new IndexPackStage(this.IndexThreadCount, downloader.AvailablePacks, checkout.AvailableBlobShas, this.Tracer, this.GitObjects);
using (new IndexLock(this.Enlistment.EnlistmentRoot, this.Tracer))
{
this.DownloadMissingCommit(commitToFetch, this.GitObjects);

// Start pipeline
downloader.Start();
blobFinder.Start();
checkout.Start();
// Configure pipeline
// Checkout uses DiffHelper when running checkout.Start(), which we use instead of LsTreeHelper
// Checkout diff output => FindBlobs => BatchDownload => IndexPack => Checkout available blobs
CheckoutStage checkout = new CheckoutStage(this.checkoutThreadCount, this.FolderList, commitToFetch, this.Tracer, this.Enlistment, this.forceCheckout);
FindBlobsStage blobFinder = new FindBlobsStage(this.SearchThreadCount, checkout.RequiredBlobs, checkout.AvailableBlobShas, this.Tracer, this.Enlistment);
BatchObjectDownloadStage downloader = new BatchObjectDownloadStage(this.DownloadThreadCount, this.ChunkSize, blobFinder.MissingBlobs, checkout.AvailableBlobShas, this.Tracer, this.Enlistment, this.ObjectRequestor, this.GitObjects);
IndexPackStage packIndexer = new IndexPackStage(this.IndexThreadCount, downloader.AvailablePacks, checkout.AvailableBlobShas, this.Tracer, this.GitObjects);

blobFinder.WaitForCompletion();
this.HasFailures |= blobFinder.HasFailures;
// Start pipeline
downloader.Start();
blobFinder.Start();
checkout.Start();

// Delay indexing. It interferes with FindMissingBlobs, and doesn't help Bootstrapping.
packIndexer.Start();
blobFinder.WaitForCompletion();
this.HasFailures |= blobFinder.HasFailures;

downloader.WaitForCompletion();
this.HasFailures |= downloader.HasFailures;
// Delay indexing. It interferes with FindMissingBlobs, and doesn't help Bootstrapping.
packIndexer.Start();

packIndexer.WaitForCompletion();
this.HasFailures |= packIndexer.HasFailures;
downloader.WaitForCompletion();
this.HasFailures |= downloader.HasFailures;

// Since pack indexer is the last to finish before checkout finishes, it should propagate completion.
// This prevents availableObjects from completing before packIndexer can push its objects through this link.
checkout.AvailableBlobShas.CompleteAdding();
checkout.WaitForCompletion();
this.HasFailures |= checkout.HasFailures;
packIndexer.WaitForCompletion();
this.HasFailures |= packIndexer.HasFailures;

if (!this.SkipConfigUpdate && !this.HasFailures)
{
this.UpdateRefs(branchOrCommit, isBranch, refs);
// Since pack indexer is the last to finish before checkout finishes, it should propagate completion.
// This prevents availableObjects from completing before packIndexer can push its objects through this link.
checkout.AvailableBlobShas.CompleteAdding();
checkout.WaitForCompletion();
this.HasFailures |= checkout.HasFailures;

if (isBranch)
if (!this.SkipConfigUpdate && !this.HasFailures)
{
// Update the refspec before setting the upstream or git will complain the remote branch doesn't exist
this.HasFailures |= !this.UpdateRefSpec(this.Tracer, this.Enlistment, branchOrCommit, refs);
bool shouldSignIndex = !this.GetIsIndexSigningOff();

using (ITracer activity = this.Tracer.StartActivity("SetUpstream", EventLevel.Informational))
// Update the index - note that this will take some time
EventMetadata updateIndexMetadata = new EventMetadata();
updateIndexMetadata.Add("IndexSigningIsOff", shouldSignIndex);
using (ITracer activity = this.Tracer.StartActivity("UpdateIndex", EventLevel.Informational, Keywords.Telemetry, updateIndexMetadata))
{
string remoteBranch = refs.GetBranchRefPairs().Single().Key;
GitProcess git = new GitProcess(this.Enlistment);
GitProcess.Result result = git.SetUpstream(branchOrCommit, remoteBranch);
if (result.ExitCodeIsFailure)
Index sourceIndex = this.GetSourceIndex();
GitIndexGenerator indexGen = new GitIndexGenerator(this.Tracer, this.Enlistment, shouldSignIndex);
indexGen.CreateFromRef(commitToFetch, indexVersion: 2, isFinal: false);
this.HasFailures |= indexGen.HasFailures;

if (!indexGen.HasFailures)
{
activity.RelatedError("Could not set upstream for {0} to {1}: {2}", branchOrCommit, remoteBranch, result.Errors);
this.HasFailures = true;
Index newIndex = new Index(
this.Enlistment.EnlistmentRoot,
this.Tracer,
indexGen.TemporaryIndexFilePath,
readOnly: false);

// Update from disk only if the caller says it is ok via command line
// or if we updated the whole tree and know that all files are up to date
bool allowIndexMetadataUpdateFromWorkingTree = this.allowIndexMetadataUpdateFromWorkingTree || checkout.UpdatedWholeTree;
newIndex.UpdateFileSizesAndTimes(checkout.AddedOrEditedLocalFiles, allowIndexMetadataUpdateFromWorkingTree, shouldSignIndex, sourceIndex);

// All the slow stuff is over, so we will now move the final index into .git\index, shortly followed by
// updating the ref files and releasing index.lock.
string indexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName);
this.Tracer.RelatedEvent(EventLevel.Informational, "MoveUpdatedIndexToFinalLocation", new EventMetadata() { { "UpdatedIndex", indexGen.TemporaryIndexFilePath }, { "Index", indexPath } });
File.Delete(indexPath);
File.Move(indexGen.TemporaryIndexFilePath, indexPath);
newIndex.WriteFastFetchIndexVersionMarker();
}
}
}

bool shouldSignIndex = !this.GetIsIndexSigningOff();

// Update the index
EventMetadata updateIndexMetadata = new EventMetadata();
updateIndexMetadata.Add("IndexSigningIsOff", shouldSignIndex);
using (ITracer activity = this.Tracer.StartActivity("UpdateIndex", EventLevel.Informational, Keywords.Telemetry, updateIndexMetadata))
{
Index sourceIndex = this.GetSourceIndex();
GitIndexGenerator indexGen = new GitIndexGenerator(this.Tracer, this.Enlistment, shouldSignIndex);
indexGen.CreateFromHeadTree(indexVersion: 2);
this.HasFailures |= indexGen.HasFailures;

if (!indexGen.HasFailures)
if (!this.HasFailures)
{
Index newIndex = new Index(
this.Enlistment.EnlistmentRoot,
this.Tracer,
Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName),
readOnly: false);

// Update from disk only if the caller says it is ok via command line
// or if we updated the whole tree and know that all files are up to date
bool allowIndexMetadataUpdateFromWorkingTree = this.allowIndexMetadataUpdateFromWorkingTree || checkout.UpdatedWholeTree;
newIndex.UpdateFileSizesAndTimes(checkout.AddedOrEditedLocalFiles, allowIndexMetadataUpdateFromWorkingTree, shouldSignIndex, sourceIndex);
this.UpdateRefs(branchOrCommit, isBranch, refs);

if (isBranch)
{
// Update the refspec before setting the upstream or git will complain the remote branch doesn't exist
this.HasFailures |= !this.UpdateRefSpec(this.Tracer, this.Enlistment, branchOrCommit, refs);

using (ITracer activity = this.Tracer.StartActivity("SetUpstream", EventLevel.Informational))
{
string remoteBranch = refs.GetBranchRefPairs().Single().Key;
GitProcess git = new GitProcess(this.Enlistment);
GitProcess.Result result = git.SetUpstream(branchOrCommit, remoteBranch);
if (result.ExitCodeIsFailure)
{
activity.RelatedError("Could not set upstream for {0} to {1}: {2}", branchOrCommit, remoteBranch, result.Errors);
this.HasFailures = true;
}
}
}
}
}
}
Expand Down Expand Up @@ -183,18 +197,10 @@ protected override void UpdateRefs(string branchOrCommit, bool isBranch, GitRefs
private Index GetSourceIndex()
{
string indexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName);
string backupIndexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName + ".backup");

if (File.Exists(indexPath))
{
// Note that this moves the current index, leaving nothing behind
// This is intentional as we only need it for the purpose of updating the
// new index and leaving it behind can make updating slower.
this.Tracer.RelatedEvent(EventLevel.Informational, "CreateBackup", new EventMetadata() { { "BackupIndexName", backupIndexPath } });
File.Delete(backupIndexPath);
File.Move(indexPath, backupIndexPath);

Index output = new Index(this.Enlistment.EnlistmentRoot, this.Tracer, backupIndexPath, readOnly: true);
Index output = new Index(this.Enlistment.EnlistmentRoot, this.Tracer, indexPath, readOnly: true);
output.Parse();
return output;
}
Expand Down
Loading

0 comments on commit 1efd105

Please sign in to comment.