Implementation of C Git --dry-run behavior for push operation. It allows investigating possible push result, while not performing real push operation - not updating remote refs. Signed-off-by: Marek Zawirski <marek.zawirski@xxxxxxxxx> --- .../src/org/spearce/jgit/pgm/Push.java | 4 ++ .../org/spearce/jgit/transport/PushProcess.java | 18 +++++++- .../src/org/spearce/jgit/transport/Transport.java | 40 ++++++++++++++++++-- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java index a952309..f5b24c6 100644 --- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java +++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java @@ -85,6 +85,9 @@ class Push extends TextBuiltin { @Option(name = "--receive-pack", metaVar = "path") private String receivePack; + + @Option(name = "--dry-run") + private boolean dryRun = Transport.DEFAULT_DRY_RUN; private boolean shownURI; @@ -102,6 +105,7 @@ class Push extends TextBuiltin { transport.setPushThin(thin); if (receivePack != null) transport.setOptionReceivePack(receivePack); + transport.setDryRun(dryRun); final Collection<RemoteRefUpdate> toPush = transport .findRemoteRefUpdatesFor(refSpecs); diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/PushProcess.java b/org.spearce.jgit/src/org/spearce/jgit/transport/PushProcess.java index 6a2176f..cafec05 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/PushProcess.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/PushProcess.java @@ -100,7 +100,10 @@ class PushProcess { /** * Perform push operation between local and remote repository - set remote * refs appropriately, send needed objects and update local tracking refs. - * + * <p> + * When {@link Transport#isDryRun()} is true, result of this operation is + * just estimation of real operation result, no real action is performed. + * * @param monitor * progress monitor used for feedback about operation. * @return result of push operation with complete status description. @@ -118,12 +121,15 @@ class PushProcess { monitor.endTask(); final Map<String, RemoteRefUpdate> preprocessed = prepareRemoteUpdates(); - if (!preprocessed.isEmpty()) + if (transport.isDryRun()) + modifyUpdatesForDryRun(); + else if (!preprocessed.isEmpty()) connection.push(monitor, preprocessed); } finally { connection.close(); } - updateTrackingRefs(); + if (!transport.isDryRun()) + updateTrackingRefs(); return prepareOperationResult(); } @@ -191,6 +197,12 @@ class PushProcess { return result; } + private void modifyUpdatesForDryRun() { + for (final RemoteRefUpdate rru : toPush.values()) + if (rru.getStatus() == Status.NOT_ATTEMPTED) + rru.setStatus(Status.OK); + } + private void updateTrackingRefs() { for (final RemoteRefUpdate rru : toPush.values()) { final Status status = rru.getStatus(); diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java index 73aa771..98853e6 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java @@ -236,6 +236,11 @@ public abstract class Transport { public static final RefSpec REFSPEC_PUSH_ALL = new RefSpec( "refs/heads/*:refs/heads/*"); + /** + * Default setting for {@link #dryRun} option. + */ + public static final boolean DEFAULT_DRY_RUN = false; + /** The repository this transport fetches into, or pushes out of. */ protected final Repository local; @@ -271,6 +276,9 @@ public abstract class Transport { /** Should push produce thin-pack when sending objects to remote repository. */ private boolean pushThin = DEFAULT_PUSH_THIN; + /** Should push just check for operation result, not really push. */ + private boolean dryRun = DEFAULT_DRY_RUN; + /** * Create a new transport instance. * @@ -426,6 +434,27 @@ public abstract class Transport { } /** + * @return true if push operation should just check for possible result and + * not really update remote refs, false otherwise - when push should + * act normally. + */ + public boolean isDryRun() { + return dryRun; + } + + /** + * Set dry run option for push operation. + * + * @param dryRun + * true if push operation should just check for possible result + * and not really update remote refs, false otherwise - when push + * should act normally. + */ + public void setDryRun(final boolean dryRun) { + this.dryRun = dryRun; + } + + /** * Fetch objects and refs from the remote repository to the local one. * <p> * This is a utility function providing standard fetch behavior. Local @@ -495,10 +524,13 @@ public abstract class Transport { * operation result is provided after execution. * <p> * For setting up remote ref update specification from ref spec, see helper - * method {@link #findRemoteRefUpdatesFor(Collection)}, predefined refspecs ({@link #REFSPEC_TAGS}, - * {@link #REFSPEC_PUSH_ALL}) or consider using directly - * {@link RemoteRefUpdate} for more possibilities. - * + * method {@link #findRemoteRefUpdatesFor(Collection)}, predefined refspecs + * ({@link #REFSPEC_TAGS}, {@link #REFSPEC_PUSH_ALL}) or consider using + * directly {@link RemoteRefUpdate} for more possibilities. + * <p> + * When {@link #isDryRun()} is true, result of this operation is just + * estimation of real operation result, no real action is performed. + * * @see RemoteRefUpdate * * @param monitor -- 1.5.6.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html