Skip to content

Commit 1efd105

Browse files
authored
Merge pull request #1807 from microsoft/milestones/m193
[Release] Milestone M193
2 parents 77bc5a4 + 55ba68d commit 1efd105

32 files changed

Lines changed: 388 additions & 348 deletions

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ jobs:
109109
- name: Run functional tests
110110
shell: cmd
111111
run: |
112-
SET PATH=C:\Program Files\GVFS;%PATH%
112+
SET PATH=C:\Program Files\VFS for Git;%PATH%
113113
SET GIT_TRACE2_PERF=C:\temp\git-trace2.log
114114
ft\GVFS.FunctionalTests.exe /result:TestResult.xml --ci
115115

.github/workflows/release-winget.yaml

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,18 @@ on:
55

66
jobs:
77
release:
8-
runs-on: ubuntu-latest
8+
runs-on: windows-latest
99
steps:
10-
- id: update-winget
11-
name: Update winget repository
12-
uses: mjcheetham/update-winget@v1.2.2
13-
with:
14-
id: Microsoft.VFSforGit
15-
token: ${{ secrets.WINGET_TOKEN }}
16-
releaseAsset: SetupGVFS.([0-9.]*)\.exe
17-
manifestText: |
18-
PackageIdentifier: {{id}}
19-
PackageVersion: {{version}}
20-
PackageName: VFS for Git
21-
Publisher: Microsoft Corporation
22-
Moniker: vfs-for-git
23-
PackageUrl: https://aka.ms/vfs-for-git
24-
Tags:
25-
- vfs for git
26-
- vfs-for-git
27-
- vfsforgit
28-
- gvfs
29-
License: Copyright (C) Microsoft Corporation
30-
ShortDescription: Virtual File System for Git - a tool to scale Git for monorepo scenarios.
31-
Installers:
32-
- Architecture: x64
33-
InstallerUrl: {{url}}
34-
InstallerType: inno
35-
InstallerSha256: {{sha256}}
36-
PackageLocale: en-US
37-
ManifestType: singleton
38-
ManifestVersion: 1.0.0
39-
alwaysUsePullRequest: true
10+
- name: Publish manifest with winget-create
11+
run: |
12+
# Get correct release asset
13+
$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json
14+
$asset = $github.release.assets | Where-Object -Property name -match 'SetupGVFS[\d\.]*.exe'
15+
16+
# Remove 'v' from the version
17+
$version = $github.release.tag_name -replace ".v",""
18+
19+
# Download and run wingetcreate
20+
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
21+
.\wingetcreate.exe update Microsoft.VFSforGit -u $asset.browser_download_url -v $version -o manifests -t "${{ secrets.WINGET_TOKEN }}" -s
22+
shell: powershell

GVFS/FastFetch/CheckoutPrefetcher.cs

Lines changed: 78 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -72,85 +72,99 @@ public override void Prefetch(string branchOrCommit, bool isBranch)
7272
commitToFetch = branchOrCommit;
7373
}
7474

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

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

90-
blobFinder.WaitForCompletion();
91-
this.HasFailures |= blobFinder.HasFailures;
87+
// Start pipeline
88+
downloader.Start();
89+
blobFinder.Start();
90+
checkout.Start();
9291

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

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

99-
packIndexer.WaitForCompletion();
100-
this.HasFailures |= packIndexer.HasFailures;
98+
downloader.WaitForCompletion();
99+
this.HasFailures |= downloader.HasFailures;
101100

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

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

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

117-
using (ITracer activity = this.Tracer.StartActivity("SetUpstream", EventLevel.Informational))
114+
// Update the index - note that this will take some time
115+
EventMetadata updateIndexMetadata = new EventMetadata();
116+
updateIndexMetadata.Add("IndexSigningIsOff", shouldSignIndex);
117+
using (ITracer activity = this.Tracer.StartActivity("UpdateIndex", EventLevel.Informational, Keywords.Telemetry, updateIndexMetadata))
118118
{
119-
string remoteBranch = refs.GetBranchRefPairs().Single().Key;
120-
GitProcess git = new GitProcess(this.Enlistment);
121-
GitProcess.Result result = git.SetUpstream(branchOrCommit, remoteBranch);
122-
if (result.ExitCodeIsFailure)
119+
Index sourceIndex = this.GetSourceIndex();
120+
GitIndexGenerator indexGen = new GitIndexGenerator(this.Tracer, this.Enlistment, shouldSignIndex);
121+
indexGen.CreateFromRef(commitToFetch, indexVersion: 2, isFinal: false);
122+
this.HasFailures |= indexGen.HasFailures;
123+
124+
if (!indexGen.HasFailures)
123125
{
124-
activity.RelatedError("Could not set upstream for {0} to {1}: {2}", branchOrCommit, remoteBranch, result.Errors);
125-
this.HasFailures = true;
126+
Index newIndex = new Index(
127+
this.Enlistment.EnlistmentRoot,
128+
this.Tracer,
129+
indexGen.TemporaryIndexFilePath,
130+
readOnly: false);
131+
132+
// Update from disk only if the caller says it is ok via command line
133+
// or if we updated the whole tree and know that all files are up to date
134+
bool allowIndexMetadataUpdateFromWorkingTree = this.allowIndexMetadataUpdateFromWorkingTree || checkout.UpdatedWholeTree;
135+
newIndex.UpdateFileSizesAndTimes(checkout.AddedOrEditedLocalFiles, allowIndexMetadataUpdateFromWorkingTree, shouldSignIndex, sourceIndex);
136+
137+
// All the slow stuff is over, so we will now move the final index into .git\index, shortly followed by
138+
// updating the ref files and releasing index.lock.
139+
string indexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName);
140+
this.Tracer.RelatedEvent(EventLevel.Informational, "MoveUpdatedIndexToFinalLocation", new EventMetadata() { { "UpdatedIndex", indexGen.TemporaryIndexFilePath }, { "Index", indexPath } });
141+
File.Delete(indexPath);
142+
File.Move(indexGen.TemporaryIndexFilePath, indexPath);
143+
newIndex.WriteFastFetchIndexVersionMarker();
126144
}
127145
}
128-
}
129-
130-
bool shouldSignIndex = !this.GetIsIndexSigningOff();
131146

132-
// Update the index
133-
EventMetadata updateIndexMetadata = new EventMetadata();
134-
updateIndexMetadata.Add("IndexSigningIsOff", shouldSignIndex);
135-
using (ITracer activity = this.Tracer.StartActivity("UpdateIndex", EventLevel.Informational, Keywords.Telemetry, updateIndexMetadata))
136-
{
137-
Index sourceIndex = this.GetSourceIndex();
138-
GitIndexGenerator indexGen = new GitIndexGenerator(this.Tracer, this.Enlistment, shouldSignIndex);
139-
indexGen.CreateFromHeadTree(indexVersion: 2);
140-
this.HasFailures |= indexGen.HasFailures;
141-
142-
if (!indexGen.HasFailures)
147+
if (!this.HasFailures)
143148
{
144-
Index newIndex = new Index(
145-
this.Enlistment.EnlistmentRoot,
146-
this.Tracer,
147-
Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName),
148-
readOnly: false);
149-
150-
// Update from disk only if the caller says it is ok via command line
151-
// or if we updated the whole tree and know that all files are up to date
152-
bool allowIndexMetadataUpdateFromWorkingTree = this.allowIndexMetadataUpdateFromWorkingTree || checkout.UpdatedWholeTree;
153-
newIndex.UpdateFileSizesAndTimes(checkout.AddedOrEditedLocalFiles, allowIndexMetadataUpdateFromWorkingTree, shouldSignIndex, sourceIndex);
149+
this.UpdateRefs(branchOrCommit, isBranch, refs);
150+
151+
if (isBranch)
152+
{
153+
// Update the refspec before setting the upstream or git will complain the remote branch doesn't exist
154+
this.HasFailures |= !this.UpdateRefSpec(this.Tracer, this.Enlistment, branchOrCommit, refs);
155+
156+
using (ITracer activity = this.Tracer.StartActivity("SetUpstream", EventLevel.Informational))
157+
{
158+
string remoteBranch = refs.GetBranchRefPairs().Single().Key;
159+
GitProcess git = new GitProcess(this.Enlistment);
160+
GitProcess.Result result = git.SetUpstream(branchOrCommit, remoteBranch);
161+
if (result.ExitCodeIsFailure)
162+
{
163+
activity.RelatedError("Could not set upstream for {0} to {1}: {2}", branchOrCommit, remoteBranch, result.Errors);
164+
this.HasFailures = true;
165+
}
166+
}
167+
}
154168
}
155169
}
156170
}
@@ -183,18 +197,10 @@ protected override void UpdateRefs(string branchOrCommit, bool isBranch, GitRefs
183197
private Index GetSourceIndex()
184198
{
185199
string indexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName);
186-
string backupIndexPath = Path.Combine(this.Enlistment.DotGitRoot, GVFSConstants.DotGit.IndexName + ".backup");
187200

188201
if (File.Exists(indexPath))
189202
{
190-
// Note that this moves the current index, leaving nothing behind
191-
// This is intentional as we only need it for the purpose of updating the
192-
// new index and leaving it behind can make updating slower.
193-
this.Tracer.RelatedEvent(EventLevel.Informational, "CreateBackup", new EventMetadata() { { "BackupIndexName", backupIndexPath } });
194-
File.Delete(backupIndexPath);
195-
File.Move(indexPath, backupIndexPath);
196-
197-
Index output = new Index(this.Enlistment.EnlistmentRoot, this.Tracer, backupIndexPath, readOnly: true);
203+
Index output = new Index(this.Enlistment.EnlistmentRoot, this.Tracer, indexPath, readOnly: true);
198204
output.Parse();
199205
return output;
200206
}

0 commit comments

Comments
 (0)