From 84272bab5ab7976c284ffaa0b4ebcdc504d711dc Mon Sep 17 00:00:00 2001 From: Arkady Shapkin Date: Fri, 24 Jan 2014 17:42:37 +0400 Subject: [PATCH] GetChangesets() asks changesets by parts --- GitTfs.VsCommon/TfsHelper.Common.cs | 8 +++---- .../TfsHelper.PostVs2010.Common.cs | 24 +++++++++++++++++++ GitTfs/Core/GitTfsRemote.cs | 7 ++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/GitTfs.VsCommon/TfsHelper.Common.cs b/GitTfs.VsCommon/TfsHelper.Common.cs index 0b1aa68e..60642a77 100644 --- a/GitTfs.VsCommon/TfsHelper.Common.cs +++ b/GitTfs.VsCommon/TfsHelper.Common.cs @@ -115,11 +115,11 @@ namespace Sep.Git.Tfs.VsCommon get { return _linking ?? (_linking = GetService()); } } - public IEnumerable GetChangesets(string path, long startVersion, IGitTfsRemote remote) + public virtual IEnumerable GetChangesets(string path, long startVersion, IGitTfsRemote remote) { - var changesets = VersionControl.QueryHistory(path, VersionSpec.Latest, 0, RecursionType.Full, + var changesets = Retry.Do(() => VersionControl.QueryHistory(path, VersionSpec.Latest, 0, RecursionType.Full, null, new ChangesetVersionSpec((int)startVersion), VersionSpec.Latest, int.MaxValue, true, true, true) - .Cast().OrderBy(changeset => changeset.ChangesetId).ToArray(); + .Cast().OrderBy(changeset => changeset.ChangesetId).ToArray()); // don't take the enumerator produced by a foreach statement or a yield statement, as there are references // to the old (iterated) elements and thus the referenced changesets won't be disposed until all elements were iterated. @@ -194,7 +194,7 @@ namespace Sep.Git.Tfs.VsCommon } } - private ITfsChangeset BuildTfsChangeset(Changeset changeset, IGitTfsRemote remote) + protected ITfsChangeset BuildTfsChangeset(Changeset changeset, IGitTfsRemote remote) { var tfsChangeset = _container.With(this).With(_bridge.Wrap(changeset)).GetInstance(); tfsChangeset.Summary = new TfsChangesetInfo { ChangesetId = changeset.ChangesetId, Remote = remote }; diff --git a/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs b/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs index 61fd5870..2e79ed3d 100644 --- a/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs +++ b/GitTfs.VsCommon/TfsHelper.PostVs2010.Common.cs @@ -31,6 +31,30 @@ namespace Sep.Git.Tfs.VsCommon } } + public override IEnumerable GetChangesets(string path, long startVersion, IGitTfsRemote remote) + { + const int batchCount = 100; + var start = (int)startVersion; + Changeset[] changesets; + do + { + var startChangeset = new ChangesetVersionSpec(start); + changesets = Retry.Do(() => VersionControl.QueryHistory(path, VersionSpec.Latest, 0, RecursionType.Full, + null, startChangeset, null, batchCount, true, true, true, true) + .Cast().ToArray()); + if (changesets.Length > 0) + start = changesets[changesets.Length - 1].ChangesetId + 1; + + // don't take the enumerator produced by a foreach statement or a yield statement, as there are references + // to the old (iterated) elements and thus the referenced changesets won't be disposed until all elements were iterated. + for (int i = 0; i < changesets.Length; i++) + { + yield return BuildTfsChangeset(changesets[i], remote); + changesets[i] = null; + } + } while (changesets.Length == batchCount); + } + public override IEnumerable GetAllTfsRootBranchesOrderedByCreation() { return VersionControl.QueryRootBranchObjects(RecursionType.Full) diff --git a/GitTfs/Core/GitTfsRemote.cs b/GitTfs/Core/GitTfsRemote.cs index e2cc6548..26b44973 100644 --- a/GitTfs/Core/GitTfsRemote.cs +++ b/GitTfs/Core/GitTfsRemote.cs @@ -312,13 +312,15 @@ namespace Sep.Git.Tfs.Core public IFetchResult FetchWithMerge(long mergeChangesetId, bool stopOnFailMergeCommit = false, params string[] parentCommitsHashes) { var fetchResult = new FetchResult{IsSuccess = true}; - var fetchedChangesets = FetchChangesets().ToList(); - fetchResult.NewChangesetCount = fetchedChangesets.Count; + var fetchedChangesets = FetchChangesets(); + int count = 0; foreach (var changeset in fetchedChangesets) { + count++; var log = Apply(MaxCommitHash, changeset); if (changeset.IsMergeChangeset && !ProcessMergeChangeset(changeset, stopOnFailMergeCommit, log)) { + fetchResult.NewChangesetCount = count; fetchResult.IsSuccess = false; fetchResult.LastFetchedChangesetId = MaxChangesetId; return fetchResult; @@ -333,6 +335,7 @@ namespace Sep.Git.Tfs.Core ProcessChangeset(changeset, log); DoGcIfNeeded(); } + fetchResult.NewChangesetCount = count; return fetchResult; }