aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/transport
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2012-05-22 16:45:06 -0700
committerShawn O. Pearce <spearce@spearce.org>2012-05-22 16:45:06 -0700
commit17be66acdbe662b42a263be77c435945902df968 (patch)
tree7aa8eba2102d90bee3c0044f65f0903ada077402 /org.eclipse.jgit/src/org/eclipse/jgit/transport
parentd8d649a43eb6b72f97979112066378748d0cabaf (diff)
downloadjgit-17be66acdbe662b42a263be77c435945902df968.tar.gz
jgit-17be66acdbe662b42a263be77c435945902df968.zip
Batch reference updates together for storage
clone, fetch and push can all update multiple references in a single command invocation. Rather than performing sequential iteration of each reference change inside of the application code, push this down into the reference database where the implementation can take advantage of the batch size and optimize itself. For the local filesystem implementation the obvious optimization is to write a packed-refs file when the repository is completely empty. The initial clone, fetch or push into the destination may have hundreds of new references. Writing all of these as loose files is not efficient. This optimization is not implemented in this commit and is left as an exercise for the reader to supply in a future commit to JGit. To make the API changes simple, define the BatchRefUpdate type and implementation using the existing sequential behavior. Change-Id: I8e1674f091e05e24e3ff56ccbc687a6d18a6a61e
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/transport')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java19
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java16
2 files changed, 27 insertions, 8 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
index 9d72ef8680..e375221eeb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -67,6 +67,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Config.SectionParser;
import org.eclipse.jgit.lib.Constants;
@@ -1139,12 +1140,20 @@ public abstract class BaseReceivePack {
pm.setDelayStart(250, TimeUnit.MILLISECONDS);
updating = pm;
}
- updating.beginTask(JGitText.get().updatingReferences, toApply.size());
- for (ReceiveCommand cmd : toApply) {
- updating.update(1);
- cmd.execute(this);
+
+ BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate();
+ batch.setAllowNonFastForwards(isAllowNonFastForwards());
+ batch.setRefLogIdent(getRefLogIdent());
+ batch.setRefLogMessage("push", true);
+ batch.addCommand(toApply);
+ try {
+ batch.execute(walk, updating);
+ } catch (IOException err) {
+ for (ReceiveCommand cmd : toApply) {
+ if (cmd.getResult() == Result.NOT_ATTEMPTED)
+ cmd.reject(err);
+ }
}
- updating.endTask();
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
index 26bbcdcbc8..4c7ffeccee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
@@ -337,8 +337,7 @@ public class ReceiveCommand {
break;
}
} catch (IOException err) {
- setResult(Result.REJECTED_OTHER_REASON, MessageFormat.format(
- JGitText.get().lockError, err.getMessage()));
+ reject(err);
}
}
@@ -355,7 +354,13 @@ public class ReceiveCommand {
typeIsCorrect = true;
}
- private void setResult(final RefUpdate.Result r) {
+ /**
+ * Set the result of this command.
+ *
+ * @param r
+ * the new result code for this command.
+ */
+ public void setResult(RefUpdate.Result r) {
switch (r) {
case NOT_ATTEMPTED:
setResult(Result.NOT_ATTEMPTED);
@@ -387,6 +392,11 @@ public class ReceiveCommand {
}
}
+ void reject(IOException err) {
+ setResult(Result.REJECTED_OTHER_REASON, MessageFormat.format(
+ JGitText.get().lockError, err.getMessage()));
+ }
+
@Override
public String toString() {
return getType().name() + ": " + getOldId().name() + " "