示例#1
0
        protected string GetCacheServerUrlFromConfig(string repoUrl)
        {
            GitProcess git             = new GitProcess(this);
            string     cacheConfigName = GetCacheConfigSettingName(repoUrl);

            string cacheServerUrl = git.GetFromConfig(cacheConfigName);

            if (string.IsNullOrWhiteSpace(cacheServerUrl))
            {
                // Try getting from the deprecated setting for compatibility reasons
                cacheServerUrl = StripObjectsEndpointSuffix(git.GetFromConfig(DeprecatedObjectsEndpointGitConfigName));

                // Upgrade for future runs, but not at clone time.
                if (!string.IsNullOrWhiteSpace(cacheServerUrl) && Directory.Exists(this.WorkingDirectoryRoot))
                {
                    git.SetInLocalConfig(cacheConfigName, cacheServerUrl);
                    git.DeleteFromLocalConfig(DeprecatedObjectsEndpointGitConfigName);
                }
            }

            // Default to uncached url
            if (string.IsNullOrWhiteSpace(cacheServerUrl))
            {
                return(repoUrl);
            }

            return(cacheServerUrl);
        }
示例#2
0
        private static string GetValueFromConfig(GitProcess git, string configName, bool localOnly)
        {
            GitProcess.ConfigResult result =
                localOnly
                ? git.GetFromLocalConfig(configName)
                : git.GetFromConfig(configName);

            if (!result.TryParseAsString(out string value, out string error))
            {
                throw new InvalidRepoException(error);
            }

            return(value);
        }
示例#3
0
        private string GetFromConfig(GitProcess git, string configName)
        {
            GitProcess.Result result = git.GetFromConfig(configName);

            // Git returns non-zero for non-existent settings and errors.
            if (!result.HasErrors)
            {
                return(result.Output.TrimEnd('\n'));
            }
            else if (result.Errors.Any())
            {
                throw new InvalidRepoException("Error while reading '" + configName + "' from config: " + result.Errors);
            }

            return(null);
        }
示例#4
0
        private bool GetIsIndexSigningOff()
        {
            // The first bit of core.gvfs is set if index signing is turned off.
            const uint CoreGvfsUnsignedIndexFlag = 1;

            GitProcess git = new GitProcess(this.Enlistment);

            GitProcess.Result configCoreGvfs = git.GetFromConfig("core.gvfs");
            uint valueCoreGvfs;

            // No errors getting the configuration and it is either "true" or numeric with the right bit set.
            return(!configCoreGvfs.HasErrors &&
                   !string.IsNullOrEmpty(configCoreGvfs.Output) &&
                   (configCoreGvfs.Output.Equals("true", StringComparison.OrdinalIgnoreCase) ||
                    (uint.TryParse(configCoreGvfs.Output, out valueCoreGvfs) &&
                     ((valueCoreGvfs & CoreGvfsUnsignedIndexFlag) == CoreGvfsUnsignedIndexFlag))));
        }
示例#5
0
        private static string GetValueFromConfig(GitProcess git, string configName, bool localOnly)
        {
            GitProcess.Result result =
                localOnly
                ? git.GetFromLocalConfig(configName)
                : git.GetFromConfig(configName);

            if (!result.HasErrors)
            {
                return(result.Output.TrimEnd('\n'));
            }
            else if (result.Errors.Any())
            {
                throw new InvalidRepoException("Error while reading '" + configName + "' from config: " + result.Errors);
            }

            return(null);
        }
示例#6
0
        private static bool TryGetFromGitConfig(GitProcess git, string configName, int defaultValue, int minValue, out int value, out string error)
        {
            value = defaultValue;
            error = string.Empty;

            GitProcess.Result result = git.GetFromConfig(configName);
            if (result.HasErrors)
            {
                if (result.Errors.Any())
                {
                    error = "Error while reading '" + configName + "' from config: " + result.Errors;
                    return(false);
                }

                // Git returns non-zero for non-existent settings and errors.
                return(true);
            }

            string valueString = result.Output.TrimEnd('\n');

            if (string.IsNullOrWhiteSpace(valueString))
            {
                // Use default value
                return(true);
            }

            if (!int.TryParse(valueString, out value))
            {
                error = string.Format("Misconfigured config setting {0}, could not parse value {1}", configName, valueString);
                return(false);
            }

            if (value < minValue)
            {
                error = string.Format("Invalid value {0} for setting {1}, value must be greater than or equal to {2}", value, configName, minValue);
                return(false);
            }

            return(true);
        }
 private static bool TryGetFromGitConfig(GitProcess git, string configName, int defaultValue, int minValue, out int value, out string error)
 {
     GitProcess.ConfigResult result = git.GetFromConfig(configName);
     return(result.TryParseAsInt(defaultValue, minValue, out value, out error));
 }
示例#8
0
        /// <param name="branchOrCommit">A specific branch to filter for, or null for all branches returned from info/refs</param>
        public override void FastFetch(string branchOrCommit, bool isBranch)
        {
            if (string.IsNullOrWhiteSpace(branchOrCommit))
            {
                throw new FetchException("Must specify branch or commit to fetch");
            }

            GitRefs refs = null;
            string  commitToFetch;

            if (isBranch)
            {
                refs = this.HttpGitObjects.QueryInfoRefs(branchOrCommit);
                if (refs == null)
                {
                    throw new FetchException("Could not query info/refs from: {0}", this.Enlistment.RepoUrl);
                }
                else if (refs.Count == 0)
                {
                    throw new FetchException("Could not find branch {0} in info/refs from: {1}", branchOrCommit, this.Enlistment.RepoUrl);
                }

                commitToFetch = refs.GetTipCommitIds().Single();
            }
            else
            {
                commitToFetch = branchOrCommit;
            }

            this.DownloadMissingCommit(commitToFetch, this.GitObjects);

            // Configure pipeline
            // Checkout uses DiffHelper when running checkout.Start(), which we use instead of LsTreeHelper like in FetchHelper.cs
            // Checkout diff output => FindMissingBlobs => BatchDownload => IndexPack => Checkout available blobs
            CheckoutJob            checkout    = new CheckoutJob(this.checkoutThreadCount, this.PathWhitelist, commitToFetch, this.Tracer, this.Enlistment);
            FindMissingBlobsJob    blobFinder  = new FindMissingBlobsJob(this.SearchThreadCount, checkout.RequiredBlobs, checkout.AvailableBlobShas, this.Tracer, this.Enlistment);
            BatchObjectDownloadJob downloader  = new BatchObjectDownloadJob(this.DownloadThreadCount, this.ChunkSize, blobFinder.DownloadQueue, checkout.AvailableBlobShas, this.Tracer, this.Enlistment, this.HttpGitObjects, this.GitObjects);
            IndexPackJob           packIndexer = new IndexPackJob(this.IndexThreadCount, downloader.AvailablePacks, checkout.AvailableBlobShas, this.Tracer, this.GitObjects);

            // Start pipeline
            downloader.Start();
            blobFinder.Start();
            checkout.Start();

            blobFinder.WaitForCompletion();
            this.HasFailures |= blobFinder.HasFailures;

            // Delay indexing. It interferes with FindMissingBlobs, and doesn't help Bootstrapping.
            packIndexer.Start();

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

            packIndexer.WaitForCompletion();
            this.HasFailures |= packIndexer.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;

            if (!this.SkipConfigUpdate && !this.HasFailures)
            {
                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 |= !RefSpecHelpers.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.HasErrors)
                        {
                            activity.RelatedError("Could not set upstream for {0} to {1}: {2}", branchOrCommit, remoteBranch, result.Errors);
                            this.HasFailures = true;
                        }
                    }
                }

                // Update the index
                using (ITracer activity = this.Tracer.StartActivity("UpdateIndex", EventLevel.Informational))
                {
                    // The first bit of core.gvfs is set if index signing is turned off.
                    const uint CoreGvfsUnsignedIndexFlag = 1;

                    GitProcess git = new GitProcess(this.Enlistment);

                    // Only update the index if index signing is turned off.

                    // The first bit of core.gvfs is set if signing is turned off.
                    GitProcess.Result configCoreGvfs = git.GetFromConfig("core.gvfs");
                    uint valueCoreGvfs;

                    // No errors getting the configuration *and it is either "true" or numeric with the right bit set.
                    bool indexSigningIsTurnedOff =
                        !configCoreGvfs.HasErrors &&
                        !string.IsNullOrEmpty(configCoreGvfs.Output) &&
                        (configCoreGvfs.Output.Equals("true", StringComparison.OrdinalIgnoreCase) ||
                         (uint.TryParse(configCoreGvfs.Output, out valueCoreGvfs) &&
                          ((valueCoreGvfs & CoreGvfsUnsignedIndexFlag) == CoreGvfsUnsignedIndexFlag)));

                    // Create the index object now so it can track the current index
                    Index index = indexSigningIsTurnedOff ? new Index(this.Enlistment.EnlistmentRoot, activity) : null;

                    GitProcess.Result result;
                    using (ITracer updateIndexActivity = this.Tracer.StartActivity("ReadTree", EventLevel.Informational))
                    {
                        result = git.ReadTree("HEAD");
                    }

                    if (result.HasErrors)
                    {
                        activity.RelatedError("Could not read HEAD tree to update index: " + result.Errors);
                        this.HasFailures = true;
                    }
                    else
                    {
                        if (index != null)
                        {
                            // 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;

                            // Update
                            index.UpdateFileSizesAndTimes(allowIndexMetadataUpdateFromWorkingTree);
                        }
                        else
                        {
                            activity.RelatedEvent(EventLevel.Informational, "Core.gvfs is not set, so not updating index entries with file times and sizes.", null);
                        }
                    }
                }
            }
        }