From d6b7139cd85f718fa241b51628835a21c5d81833 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sat, 5 Feb 2011 19:00:15 -0800 Subject: [PATCH] UploadPack: Avoid walking the entire project history If the client presents a common commit on a side branch, and there is a want for a disconnected branch UploadPack was walking back on the entire history of the disconnected branch because it never would find the common commit. Limit our search back along any given want to be no earlier than the oldest common commit received via a "have" line from our client. This prevents us from looking at all of the project history. Bug: 301639 Change-Id: Iffaaa2250907150d6efa1cf2f2fcf59851d5267d Signed-off-by: Shawn O. Pearce Signed-off-by: Chris Aniszczyk --- .../revwalk/filter/CommitTimeRevFilter.java | 40 +++++++++++++++++-- .../eclipse/jgit/transport/UploadPack.java | 13 ++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java index 0e6c478cc..858bec4c0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java @@ -63,7 +63,18 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @return a new filter to select commits on or before ts. */ public static final RevFilter before(final Date ts) { - return new Before(ts.getTime()); + return before(ts.getTime()); + } + + /** + * Create a new filter to select commits before a given date/time. + * + * @param ts + * the point in time to cut on, in milliseconds + * @return a new filter to select commits on or before ts. + */ + public static final RevFilter before(final long ts) { + return new Before(ts); } /** @@ -74,7 +85,18 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @return a new filter to select commits on or after ts. */ public static final RevFilter after(final Date ts) { - return new After(ts.getTime()); + return after(ts.getTime()); + } + + /** + * Create a new filter to select commits after a given date/time. + * + * @param ts + * the point in time to cut on, in milliseconds. + * @return a new filter to select commits on or after ts. + */ + public static final RevFilter after(final long ts) { + return new After(ts); } /** @@ -86,7 +108,19 @@ public abstract class CommitTimeRevFilter extends RevFilter { * @return a new filter to select commits between the given date/times. */ public static final RevFilter between(final Date since, final Date until) { - return new Between(since.getTime(), until.getTime()); + return between(since.getTime(), until.getTime()); + } + + /** + * Create a new filter to select commits after or equal a given date/time since + * and before or equal a given date/time until. + * + * @param since the point in time to cut on, in milliseconds. + * @param until the point in time to cut off, in millisconds. + * @return a new filter to select commits between the given date/times. + */ + public static final RevFilter between(final long since, final long until) { + return new Between(since, until); } final int when; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 63fa503b1..52d7c3753 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -71,6 +71,7 @@ import org.eclipse.jgit.revwalk.RevFlagSet; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter; import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackWriter; import org.eclipse.jgit.transport.BasePackFetchConnection.MultiAck; @@ -153,6 +154,9 @@ public class UploadPack { /** Objects on both sides, these don't have to be sent. */ private final List commonBase = new ArrayList(); + /** Commit time of the oldest common commit, in seconds. */ + private int oldestTime; + /** null if {@link #commonBase} should be examined again. */ private Boolean okToGiveUp; @@ -517,6 +521,13 @@ public class UploadPack { } last = obj; + + if (obj instanceof RevCommit) { + RevCommit c = (RevCommit) obj; + if (oldestTime == 0 || c.getCommitTime() < oldestTime) + oldestTime = c.getCommitTime(); + } + if (obj.has(PEER_HAS)) continue; @@ -606,6 +617,8 @@ public class UploadPack { walk.resetRetain(SAVE); walk.markStart((RevCommit) want); + if (oldestTime != 0) + walk.setRevFilter(CommitTimeRevFilter.after(oldestTime * 1000L)); for (;;) { final RevCommit c = walk.next(); if (c == null)