diff options
Diffstat (limited to 'org.eclipse.jgit/src')
5 files changed, 93 insertions, 8 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java index aba86fc361..cf7bc1f263 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -297,6 +297,7 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> { command.setTagOpt( fetchAll ? TagOpt.FETCH_TAGS : TagOpt.AUTO_FOLLOW); } + command.setInitialBranch(branch); configure(command); return command.call(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java index 033dd60c3b..90c1515b06 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java @@ -74,6 +74,8 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { private boolean isForceUpdate; + private String initialBranch; + /** * Callback for status of fetch operation. * @@ -209,7 +211,7 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { transport.setFetchThin(thin); configure(transport); FetchResult result = transport.fetch(monitor, - applyOptions(refSpecs)); + applyOptions(refSpecs), initialBranch); if (!repo.isBare()) { fetchSubmodules(result); } @@ -488,6 +490,24 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { } /** + * Set the initial branch + * + * @param branch + * the initial branch to check out when cloning the repository. + * Can be specified as ref name (<code>refs/heads/master</code>), + * branch name (<code>master</code>) or tag name + * (<code>v1.2.3</code>). The default is to use the branch + * pointed to by the cloned repository's HEAD and can be + * requested by passing {@code null} or <code>HEAD</code>. + * @return {@code this} + * @since 5.11 + */ + public FetchCommand setInitialBranch(String branch) { + this.initialBranch = branch; + return this; + } + + /** * Register a progress callback. * * @param callback diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index aaba8d6243..af7d50aae2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -596,6 +596,7 @@ public class JGitText extends TranslationBundle { /***/ public String reftableDirExists; /***/ public String reftableRecordsMustIncrease; /***/ public String refUpdateReturnCodeWas; + /***/ public String remoteBranchNotFound; /***/ public String remoteConfigHasNoURIAssociated; /***/ public String remoteDoesNotHaveSpec; /***/ public String remoteDoesNotSupportSmartHTTPPush; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index bdebfa607b..34bad6e029 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -48,6 +48,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.util.StringUtils; class FetchProcess { /** Transport we will fetch over. */ @@ -79,7 +80,8 @@ class FetchProcess { toFetch = f; } - void execute(ProgressMonitor monitor, FetchResult result) + void execute(ProgressMonitor monitor, FetchResult result, + String initialBranch) throws NotSupportedException, TransportException { askFor.clear(); localUpdates.clear(); @@ -89,7 +91,7 @@ class FetchProcess { Throwable e1 = null; try { - executeImp(monitor, result); + executeImp(monitor, result, initialBranch); } catch (NotSupportedException | TransportException err) { e1 = err; throw err; @@ -107,9 +109,22 @@ class FetchProcess { } } + private boolean isInitialBranchMissing(Map<String, Ref> refsMap, + String initialBranch) { + if (StringUtils.isEmptyOrNull(initialBranch) || refsMap.isEmpty()) { + return false; + } + if (refsMap.containsKey(initialBranch) + || refsMap.containsKey(Constants.R_HEADS + initialBranch) + || refsMap.containsKey(Constants.R_TAGS + initialBranch)) { + return false; + } + return true; + } + private void executeImp(final ProgressMonitor monitor, - final FetchResult result) throws NotSupportedException, - TransportException { + final FetchResult result, String initialBranch) + throws NotSupportedException, TransportException { final TagOpt tagopt = transport.getTagOpt(); String getTags = (tagopt == TagOpt.NO_TAGS) ? null : Constants.R_TAGS; String getHead = null; @@ -126,7 +141,12 @@ class FetchProcess { } conn = transport.openFetch(toFetch, getTags, getHead); try { - result.setAdvertisedRefs(transport.getURI(), conn.getRefsMap()); + Map<String, Ref> refsMap = conn.getRefsMap(); + if (isInitialBranchMissing(refsMap, initialBranch)) { + throw new TransportException(MessageFormat.format( + JGitText.get().remoteBranchNotFound, initialBranch)); + } + result.setAdvertisedRefs(transport.getURI(), refsMap); result.peerUserAgent = conn.getPeerUserAgent(); final Set<Ref> matched = new HashSet<>(); for (RefSpec spec : toFetch) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index 1c998f4e8c..5b781ac25f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -1231,9 +1231,52 @@ public abstract class Transport implements AutoCloseable { * the remote connection could not be established or object * copying (if necessary) failed or update specification was * incorrect. + * @since 5.11 + */ + public FetchResult fetch(final ProgressMonitor monitor, + Collection<RefSpec> toFetch) + throws NotSupportedException, TransportException { + return fetch(monitor, toFetch, null); + } + + /** + * Fetch objects and refs from the remote repository to the local one. + * <p> + * This is a utility function providing standard fetch behavior. Local + * tracking refs associated with the remote repository are automatically + * updated if this transport was created from a + * {@link org.eclipse.jgit.transport.RemoteConfig} with fetch RefSpecs + * defined. + * + * @param monitor + * progress monitor to inform the user about our processing + * activity. Must not be null. Use + * {@link org.eclipse.jgit.lib.NullProgressMonitor} if progress + * updates are not interesting or necessary. + * @param toFetch + * specification of refs to fetch locally. May be null or the + * empty collection to use the specifications from the + * RemoteConfig. Source for each RefSpec can't be null. + * @param branch + * the initial branch to check out when cloning the repository. + * Can be specified as ref name (<code>refs/heads/master</code>), + * branch name (<code>master</code>) or tag name + * (<code>v1.2.3</code>). The default is to use the branch + * pointed to by the cloned repository's HEAD and can be + * requested by passing {@code null} or <code>HEAD</code>. + * @return information describing the tracking refs updated. + * @throws org.eclipse.jgit.errors.NotSupportedException + * this transport implementation does not support fetching + * objects. + * @throws org.eclipse.jgit.errors.TransportException + * the remote connection could not be established or object + * copying (if necessary) failed or update specification was + * incorrect. + * @since 5.11 */ public FetchResult fetch(final ProgressMonitor monitor, - Collection<RefSpec> toFetch) throws NotSupportedException, + Collection<RefSpec> toFetch, String branch) + throws NotSupportedException, TransportException { if (toFetch == null || toFetch.isEmpty()) { // If the caller did not ask for anything use the defaults. @@ -1263,7 +1306,7 @@ public abstract class Transport implements AutoCloseable { } final FetchResult result = new FetchResult(); - new FetchProcess(this, toFetch).execute(monitor, result); + new FetchProcess(this, toFetch).execute(monitor, result, branch); local.autoGC(monitor); |