summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2012-05-22 16:22:41 -0700
committerShawn O. Pearce <spearce@spearce.org>2012-05-22 16:28:34 -0700
commitd8d649a43eb6b72f97979112066378748d0cabaf (patch)
treed2e0ef070667bd97460db3cb9b93c96925c3a182
parent04fa307a70f8bc4f47a95fb18f74b0c9763d059b (diff)
downloadjgit-d8d649a43eb6b72f97979112066378748d0cabaf.tar.gz
jgit-d8d649a43eb6b72f97979112066378748d0cabaf.zip
Expose ReceiveCommand.updateType to check for UPDATE_NONFASTFORWARD
When a command's type is UPDATE, JGit might not yet be sure if it is a fast-forward or not. Expose a utility method to compute the exact type by performing the merge base test, allowing the type to be switched to UPDATE_NONFASTFORWARD if old ObjectId is not contained in new ObjectId. BaseReceivePack already does this test when validating the incoming command list, so provide a package level backdoor to set the type and avoid needing to redo the merge test later. Change-Id: If5a6fcc50dc4d6f96e9bb0bb7bba15ebe8b86377
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java41
2 files changed, 46 insertions, 5 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 a0b1c58c67..9d72ef8680 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -1086,11 +1086,11 @@ public abstract class BaseReceivePack {
if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
try {
- if (!walk.isMergedInto((RevCommit) oldObj,
- (RevCommit) newObj)) {
- cmd
- .setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
- }
+ if (walk.isMergedInto((RevCommit) oldObj,
+ (RevCommit) newObj))
+ cmd.setTypeFastForwardUpdate();
+ else
+ cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
} catch (MissingObjectException e) {
cmd.setResult(Result.REJECTED_MISSING_OBJECT, e
.getMessage());
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 96814c85a8..26bbcdcbc8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
@@ -49,9 +49,13 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevWalk;
/**
* A command being processed by {@link BaseReceivePack}.
@@ -157,6 +161,8 @@ public class ReceiveCommand {
private String message;
+ private boolean typeIsCorrect;
+
/**
* Create a new command for {@link BaseReceivePack}.
*
@@ -265,6 +271,36 @@ public class ReceiveCommand {
}
/**
+ * Update the type of this command by checking for fast-forward.
+ * <p>
+ * If the command's current type is UPDATE, a merge test will be performed
+ * using the supplied RevWalk to determine if {@link #getOldId()} is fully
+ * merged into {@link #getNewId()}. If some commits are not merged the
+ * update type is changed to {@link Type#UPDATE_NONFASTFORWARD}.
+ *
+ * @param walk
+ * an instance to perform the merge test with. The caller must
+ * allocate and release this object.
+ * @throws IOException
+ * either oldId or newId is not accessible in the repository
+ * used by the RevWalk. This usually indicates data corruption,
+ * and the command cannot be processed.
+ */
+ public void updateType(RevWalk walk) throws IOException {
+ if (typeIsCorrect)
+ return;
+ if (type == Type.UPDATE && !AnyObjectId.equals(oldId, newId)) {
+ RevObject o = walk.parseAny(oldId);
+ RevObject n = walk.parseAny(newId);
+ if (!(o instanceof RevCommit)
+ || !(n instanceof RevCommit)
+ || !walk.isMergedInto((RevCommit) o, (RevCommit) n))
+ setType(Type.UPDATE_NONFASTFORWARD);
+ }
+ typeIsCorrect = true;
+ }
+
+ /**
* Execute this command during a receive-pack session.
* <p>
* Sets the status of the command as a side effect.
@@ -314,6 +350,11 @@ public class ReceiveCommand {
type = t;
}
+ void setTypeFastForwardUpdate() {
+ type = Type.UPDATE;
+ typeIsCorrect = true;
+ }
+
private void setResult(final RefUpdate.Result r) {
switch (r) {
case NOT_ATTEMPTED: