]> source.dussan.org Git - jgit.git/commitdiff
Expose ReceiveCommand.updateType to check for UPDATE_NONFASTFORWARD 85/6085/1
authorShawn O. Pearce <spearce@spearce.org>
Tue, 22 May 2012 23:22:41 +0000 (16:22 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Tue, 22 May 2012 23:28:34 +0000 (16:28 -0700)
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

org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java

index a0b1c58c67c9a56b181a1d487ea31f1974bdf702..9d72ef8680bc2f451de3cf5960d7d24927583893 100644 (file)
@@ -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());
index 96814c85a85b528fdb19df8f83398beca7efefac..26bbcdcbc83c7cd64ceb9507f5eccaeca1f1912e 100644 (file)
@@ -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}.
         *
@@ -264,6 +270,36 @@ public class ReceiveCommand {
                message = m;
        }
 
+       /**
+        * 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>
@@ -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: