summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2021-01-24 00:17:13 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2021-02-22 23:11:44 +0100
commit64cb7148ac64855feb7f7649d1d168d7c6d37860 (patch)
tree1fdf66e54abe9ce87d65247c1918c5ad8db5cb56 /org.eclipse.jgit/src
parent704ccdc096e4f5cf2670c5c58eaf19fe1fdf4df3 (diff)
downloadjgit-64cb7148ac64855feb7f7649d1d168d7c6d37860.tar.gz
jgit-64cb7148ac64855feb7f7649d1d168d7c6d37860.zip
Fail clone if initial branch doesn't exist in remote repository
jgit clone --branch foo <url> did not fail if the remote branch "foo" didn't exist in the remote repository being cloned. Bug: 546580 Change-Id: I55648ad3a39da4a5711dfa8e6d6682bb8190a6d6 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java22
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java30
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java47
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);