diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2012-05-22 16:22:41 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2012-05-22 16:28:34 -0700 |
commit | d8d649a43eb6b72f97979112066378748d0cabaf (patch) | |
tree | d2e0ef070667bd97460db3cb9b93c96925c3a182 | |
parent | 04fa307a70f8bc4f47a95fb18f74b0c9763d059b (diff) | |
download | jgit-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.java | 10 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java | 41 |
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: |