예제 #1
0
        private async Task ExecuteAsync(
            VsrModule module,
            IReadOnlyList <IGitRef> refs,
            IObserver <GitRevision> subject,
            RefFilterOptions refFilterOptions,
            string branchFilter,
            string revisionFilter,
            string pathFilter,
            [CanBeNull] Func <GitRevision, bool> revisionPredicate)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var token = _cancellationTokenSequence.Next();

            var revisionCount = 0;

            await TaskScheduler.Default;

            token.ThrowIfCancellationRequested();

            var branchName = module.IsValidVersionrWorkingDir()
                ? module.GetSelectedBranch()
                : "";

            token.ThrowIfCancellationRequested();

            UpdateSelectedRef(module, refs, branchName);
            var refsByObjectId = refs.ToLookup(head => head.ObjectId);

            token.ThrowIfCancellationRequested();

            var arguments = BuildArguments(refFilterOptions, branchFilter, revisionFilter, pathFilter);

#if TRACE
            var sw = Stopwatch.StartNew();
#endif

            var versions = module.GetLog(1000); // TODO: VSR - limit is in revisionFilter variable

            foreach (var version in versions)
            {
                token.ThrowIfCancellationRequested();

                var revision = new GitRevision(new ObjectId(version.ID))
                {
                    ParentIds           = version.Parent.HasValue ? new[] { new ObjectId(version.Parent.Value) } : null,
                    TreeGuid            = null, // TODO: VSR
                    Author              = version.Author,
                    AuthorEmail         = version.Email,
                    AuthorDate          = version.Timestamp, // TODO: VSR
                    Committer           = version.Author,    // TODO: VSR
                    CommitterEmail      = version.Email,     // TODO: VSR
                    CommitDate          = version.Timestamp,
                    MessageEncoding     = null,              // TODO: VSR
                    Subject             = version.Message,
                    Body                = version.Message,   // TODO: VSR
                    Name                = version.ShortName, // TODO: VSR
                    HasMultiLineMessage = false,             // TODO: VSR - !ReferenceEquals(Subject, Body),
                    HasNotes            = false
                };

                if (revisionPredicate == null || revisionPredicate(revision))
                {
                    // The full commit message body is used initially in InMemFilter, after which it isn't
                    // strictly needed and can be re-populated asynchronously.
                    //
                    // We keep full multiline message bodies within the last six months.
                    // Commits earlier than that have their properties set to null and the
                    // memory will be GCd.
                    if (DateTime.Now - revision.AuthorDate > TimeSpan.FromDays(30 * 6))
                    {
                        revision.Body = null;
                    }

                    // Look up any refs associated with this revision
                    revision.Refs = refsByObjectId[revision.ObjectId].AsReadOnlyList();

                    revisionCount++;

                    subject.OnNext(revision);
                }
            }

            // This property is relatively expensive to call for every revision, so
            // cache it for the duration of the loop.
            var logOutputEncoding = module.LogOutputEncoding;

            if (!token.IsCancellationRequested)
            {
                subject.OnCompleted();
            }
        }