Add --force flag to fast fetch#159
Conversation
GVFS/FastFetch/CheckoutPrefetcher.cs
Outdated
| // Checkout uses DiffHelper when running checkout.Start(), which we use instead of LsTreeHelper | ||
| // Checkout diff output => FindMissingBlobs => BatchDownload => IndexPack => Checkout available blobs | ||
| CheckoutJob checkout = new CheckoutJob(this.checkoutThreadCount, this.FolderList, commitToFetch, this.Tracer, this.Enlistment); | ||
| CheckoutJob checkout = new CheckoutJob(this.checkoutThreadCount, this.FolderList, commitToFetch, this.Tracer, this.Enlistment, force: force); |
There was a problem hiding this comment.
Nit: there's no need for a named parameter here
GVFS/FastFetch/FastFetchVerb.cs
Outdated
| "force", | ||
| Required = false, | ||
| Default = false, | ||
| HelpText = "Force FastFetch to download content as if the current repository was just initialized.")] |
There was a problem hiding this comment.
It's not really "downloading" that's the issue, it's checking out the files.This flag only does anything if you also specify --checkout right? I think that also suggests that the flag should be called --force-checkout
There was a problem hiding this comment.
Hmm, currently it controls the diff for both the --checkout and non checkout cases. There are 2 blob fetchers for each case. This usage is really just for checkout though so I like the idea of calling it --force-checkout and then limiting it to the checkout path.
GVFS/FastFetch/FastFetchVerb.cs
Outdated
| { | ||
| bool isBranch = this.Commit == null; | ||
| prefetcher.Prefetch(commitish, isBranch); | ||
| prefetcher.Prefetch(commitish, isBranch, force: this.Force); |
There was a problem hiding this comment.
In general, you only need to use named parameters when passing in a literal. No need when the param name and variable name are equally descriptive.
|
|
||
| /// <param name="branchOrCommit">A specific branch to filter for, or null for all branches returned from info/refs</param> | ||
| public virtual void Prefetch(string branchOrCommit, bool isBranch) | ||
| public virtual void Prefetch(string branchOrCommit, bool isBranch, bool force = false) |
There was a problem hiding this comment.
There's no need for a default value for this parameter. There's only one caller of this method, and it passes in a value.
| out int downloadedBlobCount, | ||
| out int readFileCount) | ||
| out int readFileCount, | ||
| bool force = false) |
There was a problem hiding this comment.
Seeing the force flag passed around everywhere makes me think that a slight redesign is in order here.
It's actually kind of meaningless to pass in force=true when dealing with the BlobPrefetcher directly. That flag only makes sense when doing a checkout, via fastfetch, so it seems like it should only be a parameter to the constructor of CheckoutPrefetcher. That constructor can then pass a flag to the base constructor telling it to ignore the shallow file, but no caller of BlobPrefetcher should have access to that.
| // Use the shallow file to find a recent commit to diff against to try and reduce the number of SHAs to check | ||
| DiffHelper blobEnumerator = new DiffHelper(this.Tracer, this.Enlistment, this.FileList, this.FolderList); | ||
| if (File.Exists(shallowFile)) | ||
| // Use the shallow file to find a recent commit to diff against to try and reduce the number of SHAs to check. |
There was a problem hiding this comment.
I think all of this logic of looking for the shallow file only applies to fastfetch, meaning you could move this into a method of CheckoutPrefetcher that overrides an empty virtual method in this class. With that approach, you can keep the force logic completely contained within CheckoutPrefetcher and not even pass that flag to its base constructor.
| private int maxParallel; | ||
|
|
||
| public CheckoutJob(int maxParallel, IEnumerable<string> folderList, string targetCommitSha, ITracer tracer, Enlistment enlistment) | ||
| public CheckoutJob(int maxParallel, IEnumerable<string> folderList, string targetCommitSha, ITracer tracer, Enlistment enlistment, bool force = false) |
There was a problem hiding this comment.
I think this class should never have been moved to GVFS.Common. It is only used by CheckoutPrefetcher, so it can be moved back into the FastFetch project. This wasn't your change, but would you mind cleaning that up? (Again, the goal being to contain the force logic rather than spread it all over)
There was a problem hiding this comment.
Responding to last 3 comments - all sounds good. Thanks for the quick review!
GVFS/FastFetch/FastFetchVerb.cs
Outdated
| Required = false, | ||
| Default = false, | ||
| HelpText = "Force FastFetch to download content as if the current repository was just initialized.")] | ||
| public bool Force { get; set; } |
There was a problem hiding this comment.
We should have logic down below that enforces that --force (or --force-checkout) must be paired with --checkout
|
@sanoursa I've factored the |
sanoursa
left a comment
There was a problem hiding this comment.
The latest changes look good to me, thanks for the cleanup
GVFS/FastFetch/FastFetchVerb.cs
Outdated
| Default = false, | ||
| HelpText = "Force FastFetch to fetch and checkout content as if the current repo had just been initialized." + | ||
| "This allows you to include more folders from the repo that were not originally checked out." + | ||
| "Can only be used with --checkout")] |
There was a problem hiding this comment.
Nit: Add line breaks between the lines of the message
There was a problem hiding this comment.
@sanoursa Adding actual line breaks in the help messages causes it to render oddly on the CLI, it wraps at the correct indentation level though.
There was a problem hiding this comment.
Got it, yea if the CLI is already handling multiline help messages, then leave it alone :-). I think then the only issue with your original string was that there was no space after the .'s
GVFS/FastFetch/FastFetchVerb.cs
Outdated
| "force-checkout", | ||
| Required = false, | ||
| Default = false, | ||
| HelpText = "Force FastFetch to fetch and checkout content as if the current repo had just been initialized." + |
There was a problem hiding this comment.
I don't think this flag actually affects what we "fetch", at least not directly. It does affect what files we want to checkout, but if we already have the blobs, we're not going to re-download them.
| // Use the shallow file to find a recent commit to diff against to try and reduce the number of SHAs to check | ||
| DiffHelper blobEnumerator = new DiffHelper(this.Tracer, this.Enlistment, this.FileList, this.FolderList); | ||
| // Use the shallow file to find a recent commit to diff against to try and reduce the number of SHAs to check. | ||
| // Unless force flag has been given, in which case treat as if it's a fresh repo. |
There was a problem hiding this comment.
We don't know anything about the force flag here
|
Please make sure to run the full functional tests as well, since the required set of functional tests don't actually execute the fastfetch test cases |
|
Full Functional Test Suite has passed. |
cfb1c05 to
f41452d
Compare
Includes changes from microsoft#158 and microsoft#159. Signed-off-by: Derrick Stolee <dstolee@microsoft.com>

Adding
--forceto FastFetchThis adds a
--forceoption when using FastFetch. This will cause FastFetch to treat the repo as if it had just been initialized meaning new folders can be fetched after the initial FastFetch is run. You can effectively grow the number of folders a FastFetched repo has.This is required for boot-strapping scenarios where the set of desired folders to fetch must be dynamically computed after an initial fast fetch.