From 3ee3588b86637f97f98f2562171762822cfc2ce6 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 3 Mar 2011 14:36:19 -0800 Subject: [PATCH] RemoteRefUpdate: Accept Ref and ObjectId arguments for source Applications may already have a Ref or ObjectId on hand that they want the remote to be updated to. Instead of converting these into a String and relying on the parsing rules of resolve(), allow the application to supply the Ref or ObjectId directly. Bug: 338839 Change-Id: If5865ac9eb069de1c8f224090b6020fc422f9f12 Signed-off-by: Shawn O. Pearce --- .../jgit/transport/PushProcessTest.java | 10 +- .../jgit/transport/RemoteRefUpdate.java | 112 +++++++++++++++++- 2 files changed, 113 insertions(+), 9 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java index bb009e913..8b904bb2c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java @@ -169,7 +169,7 @@ public void testUpdateCreateRef() throws IOException { */ @Test public void testUpdateDelete() throws IOException { - final RemoteRefUpdate rru = new RemoteRefUpdate(db, null, + final RemoteRefUpdate rru = new RemoteRefUpdate(db, (String) null, "refs/heads/master", false, null, null); final Ref ref = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master", ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9")); @@ -184,7 +184,7 @@ public void testUpdateDelete() throws IOException { */ @Test public void testUpdateDeleteNonExisting() throws IOException { - final RemoteRefUpdate rru = new RemoteRefUpdate(db, null, + final RemoteRefUpdate rru = new RemoteRefUpdate(db, (String) null, "refs/heads/master", false, null, null); testOneUpdateStatus(rru, null, Status.NON_EXISTING, null); } @@ -279,12 +279,12 @@ public void testUpdateRejectedByConnection() throws IOException { */ @Test public void testUpdateMixedCases() throws IOException { - final RemoteRefUpdate rruOk = new RemoteRefUpdate(db, null, + final RemoteRefUpdate rruOk = new RemoteRefUpdate(db, (String) null, "refs/heads/master", false, null, null); final Ref refToChange = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master", ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9")); - final RemoteRefUpdate rruReject = new RemoteRefUpdate(db, null, - "refs/heads/nonexisting", false, null, null); + final RemoteRefUpdate rruReject = new RemoteRefUpdate(db, + (String) null, "refs/heads/nonexisting", false, null, null); refUpdates.add(rruOk); refUpdates.add(rruReject); advertisedRefs.add(refToChange); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java index 406767f84..e91c87302 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java @@ -48,6 +48,7 @@ import org.eclipse.jgit.JGitText; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevWalk; @@ -185,14 +186,117 @@ public RemoteRefUpdate(final Repository localDb, final String srcRef, final String remoteName, final boolean forceUpdate, final String localName, final ObjectId expectedOldObjectId) throws IOException { + this(localDb, srcRef, srcRef != null ? localDb.resolve(srcRef) + : ObjectId.zeroId(), remoteName, forceUpdate, localName, + expectedOldObjectId); + } + + /** + * Construct remote ref update request by providing an update specification. + * Object is created with default {@link Status#NOT_ATTEMPTED} status and no + * message. + * + * @param localDb + * local repository to push from. + * @param srcRef + * source revision. Use null to delete. + * @param remoteName + * full name of a remote ref to update, e.g. "refs/heads/master" + * (no wildcard, no short name). + * @param forceUpdate + * true when caller want remote ref to be updated regardless + * whether it is fast-forward update (old object is ancestor of + * new object). + * @param localName + * optional full name of a local stored tracking branch, to + * update after push, e.g. "refs/remotes/zawir/dirty" (no + * wildcard, no short name); null if no local tracking branch + * should be updated. + * @param expectedOldObjectId + * optional object id that caller is expecting, requiring to be + * advertised by remote side before update; update will take + * place ONLY if remote side advertise exactly this expected id; + * null if caller doesn't care what object id remote side + * advertise. Use {@link ObjectId#zeroId()} when expecting no + * remote ref with this name. + * @throws IOException + * when I/O error occurred during creating + * {@link TrackingRefUpdate} for local tracking branch or srcRef + * can't be resolved to any object. + * @throws IllegalArgumentException + * if some required parameter was null + */ + public RemoteRefUpdate(final Repository localDb, final Ref srcRef, + final String remoteName, final boolean forceUpdate, + final String localName, final ObjectId expectedOldObjectId) + throws IOException { + this(localDb, srcRef != null ? srcRef.getName() : null, + srcRef != null ? srcRef.getObjectId() : null, remoteName, + forceUpdate, localName, expectedOldObjectId); + } + + /** + * Construct remote ref update request by providing an update specification. + * Object is created with default {@link Status#NOT_ATTEMPTED} status and no + * message. + * + * @param localDb + * local repository to push from. + * @param srcRef + * source revision to label srcId with. If null srcId.name() will + * be used instead. + * @param srcId + * The new object that the caller wants remote ref to be after + * update. Use null or {@link ObjectId#zeroId()} for delete + * request. + * @param remoteName + * full name of a remote ref to update, e.g. "refs/heads/master" + * (no wildcard, no short name). + * @param forceUpdate + * true when caller want remote ref to be updated regardless + * whether it is fast-forward update (old object is ancestor of + * new object). + * @param localName + * optional full name of a local stored tracking branch, to + * update after push, e.g. "refs/remotes/zawir/dirty" (no + * wildcard, no short name); null if no local tracking branch + * should be updated. + * @param expectedOldObjectId + * optional object id that caller is expecting, requiring to be + * advertised by remote side before update; update will take + * place ONLY if remote side advertise exactly this expected id; + * null if caller doesn't care what object id remote side + * advertise. Use {@link ObjectId#zeroId()} when expecting no + * remote ref with this name. + * @throws IOException + * when I/O error occurred during creating + * {@link TrackingRefUpdate} for local tracking branch or srcRef + * can't be resolved to any object. + * @throws IllegalArgumentException + * if some required parameter was null + */ + public RemoteRefUpdate(final Repository localDb, final String srcRef, + final ObjectId srcId, final String remoteName, + final boolean forceUpdate, final String localName, + final ObjectId expectedOldObjectId) throws IOException { if (remoteName == null) throw new IllegalArgumentException(JGitText.get().remoteNameCantBeNull); - this.srcRef = srcRef; - this.newObjectId = (srcRef == null ? ObjectId.zeroId() : localDb - .resolve(srcRef)); - if (newObjectId == null) + if (srcId == null && srcRef != null) throw new IOException(MessageFormat.format( JGitText.get().sourceRefDoesntResolveToAnyObject, srcRef)); + + if (srcRef != null) + this.srcRef = srcRef; + else if (srcId != null && !srcId.equals(ObjectId.zeroId())) + this.srcRef = srcId.name(); + else + this.srcRef = null; + + if (srcId != null) + this.newObjectId = srcId; + else + this.newObjectId = ObjectId.zeroId(); + this.remoteName = remoteName; this.forceUpdate = forceUpdate; if (localName != null && localDb != null)