Browse Source

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 <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
stable-0.12
Shawn O. Pearce 14 years ago committed by Chris Aniszczyk
parent
commit
d6b7139cd8
  1. 40
      org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java
  2. 13
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

40
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 <code>ts</code>.
*/
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 <code>ts</code>.
*/
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 <code>ts</code>.
*/
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 <code>ts</code>.
*/
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 <code>since</code>
* and before or equal a given date/time <code>until</code>.
*
* @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;

13
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<RevObject> commonBase = new ArrayList<RevObject>();
/** 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)

Loading…
Cancel
Save