Beispiel #1
0
        /// <summary>
        /// Uses a <see cref="PrefetchPacksDeserializer"/> to read the packs from the stream.
        /// </summary>
        private RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult DeserializePrefetchPacks(
            HttpGitObjects.GitEndPointResponseData response, ref long latestTimestamp)
        {
            using (ITracer activity = this.Tracer.StartActivity(nameof(this.DeserializePrefetchPacks), EventLevel.Informational))
            {
                PrefetchPacksDeserializer deserializer = new PrefetchPacksDeserializer(response.Stream);

                foreach (PrefetchPacksDeserializer.PackAndIndex pack in deserializer.EnumeratePacks())
                {
                    string packName     = string.Format("{0}-{1}-{2}.pack", GVFSConstants.PrefetchPackPrefix, pack.Timestamp, pack.UniqueId);
                    string packFullPath = Path.Combine(this.Enlistment.GitPackRoot, packName);
                    string idxName      = string.Format("{0}-{1}-{2}.idx", GVFSConstants.PrefetchPackPrefix, pack.Timestamp, pack.UniqueId);
                    string idxFullPath  = Path.Combine(this.Enlistment.GitPackRoot, idxName);

                    EventMetadata data = new EventMetadata();
                    data["timestamp"] = pack.Timestamp.ToString();
                    data["uniqueId"]  = pack.UniqueId;
                    activity.RelatedEvent(EventLevel.Informational, "Receiving Pack/Index", data);

                    // Write the pack
                    // If it fails, TryWriteNamedPackOrIdx cleans up the packfile and we retry the prefetch
                    if (!this.TryWriteNamedPackOrIdx(activity, pack.PackStream, packFullPath))
                    {
                        return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(null, true));
                    }

                    // We will try to build an index if the server does not send one
                    if (pack.IndexStream == null)
                    {
                        if (!this.TryBuildIndex(activity, pack, packFullPath))
                        {
                            return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(null, true));
                        }
                    }
                    else if (!this.TryWriteNamedPackOrIdx(activity, pack.IndexStream, idxFullPath))
                    {
                        // Try to build the index manually, then retry the prefetch
                        if (this.TryBuildIndex(activity, pack, packFullPath))
                        {
                            // If we were able to recreate the failed index
                            // we can start the prefetch at the next timestamp
                            latestTimestamp = pack.Timestamp;
                        }

                        // The download stream will not be in a good state if the index download fails.
                        // So we have to restart the prefetch
                        return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(null, true));
                    }

                    latestTimestamp = pack.Timestamp;
                }

                return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(
                           new HttpGitObjects.GitObjectTaskResult(true)));
            }
        }
Beispiel #2
0
        public virtual string WriteTempPackFile(HttpGitObjects.GitEndPointResponseData response)
        {
            string fileName = Path.GetRandomFileName();
            string fullPath = Path.Combine(this.Enlistment.GitPackRoot, fileName);

            this.TryWriteNamedPackOrIdx(
                tracer: null,
                source: response.Stream,
                targetFullPath: fullPath,
                throwOnError: true);
            return(fullPath);
        }
Beispiel #3
0
        private RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult TrySavePackOrLooseObject(IEnumerable <string> objectShas, bool unpackObjects, HttpGitObjects.GitEndPointResponseData responseData)
        {
            if (responseData.ContentType == HttpGitObjects.ContentType.LooseObject)
            {
                List <string> objectShaList = objectShas.Distinct().ToList();
                if (objectShaList.Count != 1)
                {
                    return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(new InvalidOperationException("Received loose object when multiple objects were requested."), shouldRetry : false));
                }

                this.WriteLooseObject(this.Enlistment.WorkingDirectoryRoot, responseData.Stream, objectShaList[0]);
            }
            else if (responseData.ContentType == HttpGitObjects.ContentType.BatchedLooseObjects)
            {
                BatchedLooseObjectDeserializer deserializer = new BatchedLooseObjectDeserializer(
                    responseData.Stream,
                    (stream, sha) => this.WriteLooseObject(this.Enlistment.WorkingDirectoryRoot, stream, sha));
                deserializer.ProcessObjects();
            }
            else
            {
                GitProcess.Result result = this.TryAddPackFile(responseData.Stream, unpackObjects);
                if (result.HasErrors)
                {
                    return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(new InvalidOperationException("Could not add pack file: " + result.Errors), shouldRetry : false));
                }
            }

            return(new RetryWrapper <HttpGitObjects.GitObjectTaskResult> .CallbackResult(new HttpGitObjects.GitObjectTaskResult(true)));
        }