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 <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2011-03-03 14:36:19 -08:00
parent a468cb57c2
commit 3ee3588b86
2 changed files with 113 additions and 9 deletions

View File

@ -169,7 +169,7 @@ public void testUpdateCreateRef() throws IOException {
*/ */
@Test @Test
public void testUpdateDelete() throws IOException { 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); "refs/heads/master", false, null, null);
final Ref ref = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master", final Ref ref = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master",
ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9")); ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9"));
@ -184,7 +184,7 @@ public void testUpdateDelete() throws IOException {
*/ */
@Test @Test
public void testUpdateDeleteNonExisting() throws IOException { 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); "refs/heads/master", false, null, null);
testOneUpdateStatus(rru, null, Status.NON_EXISTING, null); testOneUpdateStatus(rru, null, Status.NON_EXISTING, null);
} }
@ -279,12 +279,12 @@ public void testUpdateRejectedByConnection() throws IOException {
*/ */
@Test @Test
public void testUpdateMixedCases() throws IOException { 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); "refs/heads/master", false, null, null);
final Ref refToChange = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master", final Ref refToChange = new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, "refs/heads/master",
ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9")); ObjectId.fromString("2c349335b7f797072cf729c4f3bb0914ecb6dec9"));
final RemoteRefUpdate rruReject = new RemoteRefUpdate(db, null, final RemoteRefUpdate rruReject = new RemoteRefUpdate(db,
"refs/heads/nonexisting", false, null, null); (String) null, "refs/heads/nonexisting", false, null, null);
refUpdates.add(rruOk); refUpdates.add(rruOk);
refUpdates.add(rruReject); refUpdates.add(rruReject);
advertisedRefs.add(refToChange); advertisedRefs.add(refToChange);

View File

@ -48,6 +48,7 @@
import org.eclipse.jgit.JGitText; import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk; 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 remoteName, final boolean forceUpdate,
final String localName, final ObjectId expectedOldObjectId) final String localName, final ObjectId expectedOldObjectId)
throws IOException { 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) if (remoteName == null)
throw new IllegalArgumentException(JGitText.get().remoteNameCantBeNull); throw new IllegalArgumentException(JGitText.get().remoteNameCantBeNull);
this.srcRef = srcRef; if (srcId == null && srcRef != null)
this.newObjectId = (srcRef == null ? ObjectId.zeroId() : localDb
.resolve(srcRef));
if (newObjectId == null)
throw new IOException(MessageFormat.format( throw new IOException(MessageFormat.format(
JGitText.get().sourceRefDoesntResolveToAnyObject, srcRef)); 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.remoteName = remoteName;
this.forceUpdate = forceUpdate; this.forceUpdate = forceUpdate;
if (localName != null && localDb != null) if (localName != null && localDb != null)