summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md22
-rw-r--r--org.eclipse.jgit.http.test/build.properties3
-rw-r--r--org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java4
-rw-r--r--org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java20
-rw-r--r--org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java64
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsException.java60
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryNotFound.java61
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryReadOnly.java61
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsValidationError.java61
-rw-r--r--org.eclipse.jgit.test/.project3
-rw-r--r--org.eclipse.jgit.test/build.properties3
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java68
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java56
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java84
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java19
18 files changed, 539 insertions, 57 deletions
diff --git a/README.md b/README.md
index 333fa289ff..9aca10f54a 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,6 @@ there, but the automated builds use Maven.
All portions of JGit are covered by the EDL. Absolutely no GPL,
LGPL or EPL contributions are accepted within this package.
-- org.eclipse.jgit.java7
-
- Extensions for users of Java 7.
-
- org.eclipse.jgit.ant
Ant tasks based on JGit.
@@ -59,10 +55,6 @@ Tests
Unit tests for org.eclipse.jgit
-- org.eclipse.jgit.java7.test
-
- Unit tests for Java 7 specific features
-
- org.eclipse.jgit.ant.test
- org.eclipse.jgit.pgm.test
- org.eclipse.jgit.http.test
@@ -73,11 +65,9 @@ Tests
Warnings/Caveats
----------------
-- Native smbolic links are supported, but only if you are using Java 7
- or newer and include the org.eclipse.jgit.java7 jar/bundle in the
- classpath, provided the file system supports them. For Windows you
- must have Windows Vista/Windows 2008 or newer, use a
- non-administrator account and have the SeCreateSymbolicLinkPrivilege.
+- Native smbolic links are supported, provided the file system supports
+ them. For Windows you must have Windows Vista/Windows 2008 or newer,
+ use a non-administrator account and have the SeCreateSymbolicLinkPrivilege.
- Only the timestamp of the index is used by jgit if the index is
dirty.
@@ -153,12 +143,6 @@ Package Features
* Assorted set of command line utilities. Mostly for ad-hoc testing of jgit
log, glog, fetch etc.
-- org.eclipse.jgit.java7/
-
- * Support for symbolic links.
-
- * Optimizations for reading file system attributes
-
- org.eclipse.jgit.ant/
* Ant tasks
diff --git a/org.eclipse.jgit.http.test/build.properties b/org.eclipse.jgit.http.test/build.properties
index 9ffa0caf78..e8bacac9ac 100644
--- a/org.eclipse.jgit.http.test/build.properties
+++ b/org.eclipse.jgit.http.test/build.properties
@@ -1,4 +1,5 @@
-source.. = tst/
+source.. = tst/,\
+ src/
output.. = bin/
bin.includes = META-INF/,\
.,\
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
index 84bb888619..ab5d3e1d90 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
@@ -117,7 +117,9 @@ public abstract class HttpTestCase extends LocalDiskRepositoryTestCase {
protected static void fsck(Repository db, RevObject... tips)
throws Exception {
- new TestRepository(db).fsck(tips);
+ TestRepository<? extends Repository> tr =
+ new TestRepository<Repository>(db);
+ tr.fsck(tips);
}
protected static Set<RefSpec> mirror(String... refs) {
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java
index 30ba22e885..bd6602019f 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsObject.java
@@ -42,7 +42,25 @@
*/
package org.eclipse.jgit.lfs.server;
-class LfsObject {
+/**
+ * LFS object.
+ *
+ */
+public class LfsObject {
String oid;
long size;
+
+ /**
+ * @return the object ID.
+ */
+ public String getOid() {
+ return oid;
+ }
+
+ /**
+ * @return the object size.
+ */
+ public long getSize() {
+ return size;
+ }
}
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
index 7b1a67007d..fdd8649036 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
@@ -43,14 +43,18 @@
package org.eclipse.jgit.lfs.server;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static javax.servlet.http.HttpServletResponse.SC_OK;
-import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+import static org.apache.http.HttpStatus.SC_FORBIDDEN;
+import static org.apache.http.HttpStatus.SC_NOT_FOUND;
+import static org.apache.http.HttpStatus.SC_OK;
+import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE;
+import static org.apache.http.HttpStatus.SC_UNPROCESSABLE_ENTITY;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.List;
@@ -60,6 +64,11 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jgit.lfs.errors.LfsException;
+import org.eclipse.jgit.lfs.errors.LfsRepositoryNotFound;
+import org.eclipse.jgit.lfs.errors.LfsRepositoryReadOnly;
+import org.eclipse.jgit.lfs.errors.LfsValidationError;
+
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -80,7 +89,7 @@ public abstract class LfsProtocolServlet extends HttpServlet {
private Gson gson = createGson();
/**
- * Get the large file repository
+ * Get the large file repository for the given request and path.
*
* @param request
* the request
@@ -89,9 +98,10 @@ public abstract class LfsProtocolServlet extends HttpServlet {
*
* @return the large file repository storing large files or null if the
* request is not supported.
+ * @throws LfsException
*/
protected abstract LargeFileRepository getLargeFileRepository(
- LfsRequest request, String path);
+ LfsRequest request, String path) throws LfsException;
/** LFS request. */
protected static class LfsRequest {
@@ -107,6 +117,15 @@ public abstract class LfsProtocolServlet extends HttpServlet {
public String getOperation() {
return operation;
}
+
+ /**
+ * Get the LFS objects.
+ *
+ * @return the objects
+ */
+ public List<LfsObject> getObjects() {
+ return objects;
+ }
}
@Override
@@ -119,7 +138,22 @@ public abstract class LfsProtocolServlet extends HttpServlet {
LfsRequest request = gson.fromJson(r, LfsRequest.class);
String path = req.getPathInfo();
- LargeFileRepository repo = getLargeFileRepository(request, path);
+ LargeFileRepository repo = null;
+ try {
+ repo = getLargeFileRepository(request, path);
+ } catch (LfsValidationError e) {
+ sendError(res, SC_UNPROCESSABLE_ENTITY, e.getMessage());
+ return;
+ } catch (LfsRepositoryNotFound e) {
+ sendError(res, SC_NOT_FOUND, e.getMessage());
+ return;
+ } catch (LfsRepositoryReadOnly e) {
+ sendError(res, SC_FORBIDDEN, e.getMessage());
+ return;
+ } catch (LfsException e) {
+ sendError(res, SC_SERVICE_UNAVAILABLE, e.getMessage());
+ return;
+ }
if (repo == null) {
res.setStatus(SC_SERVICE_UNAVAILABLE);
return;
@@ -133,7 +167,25 @@ public abstract class LfsProtocolServlet extends HttpServlet {
w.flush();
}
- private static Gson createGson() {
+ static class Error {
+ String message;
+
+ Error(String m) {
+ this.message = m;
+ }
+ }
+
+ private void sendError(HttpServletResponse rsp, int status, String message)
+ throws IOException {
+ rsp.setStatus(status);
+ PrintWriter writer = rsp.getWriter();
+ gson.toJson(new Error(message), writer);
+ writer.flush();
+ writer.close();
+ rsp.flushBuffer();
+ }
+
+ private Gson createGson() {
GsonBuilder gb = new GsonBuilder()
.setFieldNamingPolicy(
FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsException.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsException.java
new file mode 100644
index 0000000000..bd5c1eecc6
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016, David Pursehouse <david.pursehouse@gmail.com>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lfs.errors;
+
+/**
+ * Thrown when an error occurs during LFS operation.
+ *
+ * @since 4.5
+ */
+public class LfsException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param message
+ */
+ public LfsException(String message) {
+ super(message);
+ }
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryNotFound.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryNotFound.java
new file mode 100644
index 0000000000..021a100e63
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryNotFound.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016, David Pursehouse <david.pursehouse@gmail.com>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lfs.errors;
+
+/**
+ * Thrown when the repository does not exist for the user.
+ *
+ * @since 4.5
+ */
+public class LfsRepositoryNotFound extends LfsException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param name
+ *
+ */
+ public LfsRepositoryNotFound(String name) {
+ super("repository " + name + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryReadOnly.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryReadOnly.java
new file mode 100644
index 0000000000..9de334d703
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsRepositoryReadOnly.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016, David Pursehouse <david.pursehouse@gmail.com>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lfs.errors;
+
+/**
+ * Thrown when the user has read, but not write access. Only applicable when the
+ * operation in the request is "upload".
+ *
+ * @since 4.5
+ */
+public class LfsRepositoryReadOnly extends LfsException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param name
+ */
+ public LfsRepositoryReadOnly(String name) {
+ super("repository " + name + "is read-only"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsValidationError.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsValidationError.java
new file mode 100644
index 0000000000..cc02e06c8a
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsValidationError.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016, David Pursehouse <david.pursehouse@gmail.com>
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.lfs.errors;
+
+/**
+ * Thrown when there is a validation error with one or more of the objects in
+ * the request.
+ *
+ * @since 4.5
+ */
+public class LfsValidationError extends LfsException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param message
+ */
+ public LfsValidationError(String message) {
+ super(message);
+ }
+}
diff --git a/org.eclipse.jgit.test/.project b/org.eclipse.jgit.test/.project
index a7ac51e419..80bb7dab4f 100644
--- a/org.eclipse.jgit.test/.project
+++ b/org.eclipse.jgit.test/.project
@@ -2,9 +2,6 @@
<projectDescription>
<name>org.eclipse.jgit.test</name>
<comment></comment>
- <projects>
- <project>org.eclipse.jgit.java7</project>
- </projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
diff --git a/org.eclipse.jgit.test/build.properties b/org.eclipse.jgit.test/build.properties
index 786046c58a..d8c4b2a5c9 100644
--- a/org.eclipse.jgit.test/build.properties
+++ b/org.eclipse.jgit.test/build.properties
@@ -1,6 +1,7 @@
source.. = tst/,\
tst-rsrc/,\
- exttst/
+ exttst/,\
+ src/
bin.includes = META-INF/,\
.,\
plugin.properties
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
index 7cca4b9e4b..68f5dd1e0d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
@@ -45,13 +45,16 @@ package org.eclipse.jgit.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES;
+import java.io.File;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;
@@ -227,4 +230,69 @@ public class CleanCommandTest extends RepositoryTestCase {
assertTrue(cleanedFiles.contains("ignored-dir/"));
}
+ @Test
+ public void testCleanDirsWithSubmodule() throws Exception {
+ SubmoduleAddCommand command = new SubmoduleAddCommand(db);
+ String path = "sub";
+ command.setPath(path);
+ String uri = db.getDirectory().toURI().toString();
+ command.setURI(uri);
+ Repository repo = command.call();
+ repo.close();
+
+ Status beforeCleanStatus = git.status().call();
+ assertTrue(beforeCleanStatus.getAdded().contains(DOT_GIT_MODULES));
+ assertTrue(beforeCleanStatus.getAdded().contains(path));
+
+ Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
+
+ // The submodule should not be cleaned.
+ assertTrue(!cleanedFiles.contains(path + "/"));
+
+ assertTrue(cleanedFiles.contains("File2.txt"));
+ assertTrue(cleanedFiles.contains("File3.txt"));
+ assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
+ assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
+ assertTrue(cleanedFiles.contains("sub-clean/"));
+ assertTrue(cleanedFiles.size() == 4);
+ }
+
+ @Test
+ public void testCleanDirsWithRepository() throws Exception {
+ // Set up a repository inside the outer repository
+ String innerRepoName = "inner-repo";
+ File innerDir = new File(trash, innerRepoName);
+ innerDir.mkdir();
+ InitCommand initRepoCommand = new InitCommand();
+ initRepoCommand.setDirectory(innerDir);
+ initRepoCommand.call();
+
+ Status beforeCleanStatus = git.status().call();
+ Set<String> untrackedFolders = beforeCleanStatus.getUntrackedFolders();
+ Set<String> untrackedFiles = beforeCleanStatus.getUntracked();
+
+ // The inner repository should be listed as an untracked file
+ assertTrue(untrackedFiles.contains(innerRepoName));
+
+ // The inner repository should not be listed as an untracked folder
+ assertTrue(!untrackedFolders.contains(innerRepoName));
+
+ Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
+
+ // The inner repository should not be cleaned.
+ assertTrue(!cleanedFiles.contains(innerRepoName + "/"));
+
+ assertTrue(cleanedFiles.contains("File2.txt"));
+ assertTrue(cleanedFiles.contains("File3.txt"));
+ assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
+ assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
+ assertTrue(cleanedFiles.contains("sub-clean/"));
+ assertTrue(cleanedFiles.size() == 4);
+
+ Set<String> forceCleanedFiles = git.clean().setCleanDirectories(true)
+ .setForce(true).call();
+
+ // The inner repository should be cleaned this time
+ assertTrue(forceCleanedFiles.contains(innerRepoName + "/"));
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
index 50d8310314..3cb4c39c76 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
@@ -566,17 +566,31 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
}
@Test
- public void testShallowIsMinimal() throws Exception {
+ public void testShallowIsMinimalDepth1() throws Exception {
FileRepository repo = setupRepoForShallowFetch();
PackIndex idx = writeShallowPack(repo, 1, wants(c2), NONE, NONE);
+ assertContent(idx, Arrays.asList(c2.getId(), c2.getTree().getId(),
+ contentA.getId(), contentB.getId()));
+
+ // Client already has blobs A and B, verify those are not packed.
+ idx = writeShallowPack(repo, 1, wants(c5), haves(c2), shallows(c2));
+ assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentC.getId(), contentD.getId(), contentE.getId()));
+ }
+
+ @Test
+ public void testShallowIsMinimalDepth2() throws Exception {
+ FileRepository repo = setupRepoForShallowFetch();
+
+ PackIndex idx = writeShallowPack(repo, 2, wants(c2), NONE, NONE);
assertContent(idx,
Arrays.asList(c1.getId(), c2.getId(), c1.getTree().getId(),
c2.getTree().getId(), contentA.getId(),
contentB.getId()));
// Client already has blobs A and B, verify those are not packed.
- idx = writeShallowPack(repo, 1, wants(c5), haves(c1, c2), shallows(c1));
+ idx = writeShallowPack(repo, 2, wants(c5), haves(c1, c2), shallows(c1));
assertContent(idx,
Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
c5.getTree().getId(), contentC.getId(),
@@ -584,33 +598,61 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
}
@Test
- public void testShallowFetchShallowParent() throws Exception {
+ public void testShallowFetchShallowParentDepth1() throws Exception {
FileRepository repo = setupRepoForShallowFetch();
PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
assertContent(idx,
+ Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentA.getId(), contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
+
+ idx = writeShallowPack(repo, 1, wants(c4), haves(c5), shallows(c5));
+ assertContent(idx, Arrays.asList(c4.getId(), c4.getTree().getId()));
+ }
+
+ @Test
+ public void testShallowFetchShallowParentDepth2() throws Exception {
+ FileRepository repo = setupRepoForShallowFetch();
+
+ PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
+ assertContent(idx,
Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
c5.getTree().getId(), contentA.getId(),
contentB.getId(), contentC.getId(), contentD.getId(),
contentE.getId()));
- idx = writeShallowPack(repo, 1, wants(c3), haves(c4, c5), shallows(c4));
+ idx = writeShallowPack(repo, 2, wants(c3), haves(c4, c5), shallows(c4));
assertContent(idx, Arrays.asList(c2.getId(), c3.getId(),
c2.getTree().getId(), c3.getTree().getId()));
}
@Test
- public void testShallowFetchShallowAncestor() throws Exception {
+ public void testShallowFetchShallowAncestorDepth1() throws Exception {
FileRepository repo = setupRepoForShallowFetch();
PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
assertContent(idx,
+ Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentA.getId(), contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
+
+ idx = writeShallowPack(repo, 1, wants(c3), haves(c5), shallows(c5));
+ assertContent(idx, Arrays.asList(c3.getId(), c3.getTree().getId()));
+ }
+
+ @Test
+ public void testShallowFetchShallowAncestorDepth2() throws Exception {
+ FileRepository repo = setupRepoForShallowFetch();
+
+ PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
+ assertContent(idx,
Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
c5.getTree().getId(), contentA.getId(),
contentB.getId(), contentC.getId(), contentD.getId(),
contentE.getId()));
- idx = writeShallowPack(repo, 1, wants(c2), haves(c4, c5), shallows(c4));
+ idx = writeShallowPack(repo, 2, wants(c2), haves(c4, c5), shallows(c4));
assertContent(idx, Arrays.asList(c1.getId(), c2.getId(),
c1.getTree().getId(), c2.getTree().getId()));
}
@@ -645,7 +687,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
Set<? extends ObjectId> shallow) throws IOException {
// During negotiation, UploadPack would have set up a DepthWalk and
// marked the client's "shallow" commits. Emulate that here.
- DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth);
+ DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1);
walk.assumeShallow(shallow);
return writePack(repo, walk, depth, want, have, EMPTY_ID_SET);
}
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 681b6ac9f0..57b5b8d833 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -332,6 +332,7 @@ invalidBooleanValue=Invalid boolean value: {0}.{1}={2}
invalidChannel=Invalid channel {0}
invalidCharacterInBase64Data=Invalid character in Base64 data.
invalidCommitParentNumber=Invalid commit parent number
+invalidDepth=Invalid depth: {0}
invalidEncryption=Invalid encryption
invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense.
invalidGitdirRef = Invalid .git reference in file ''{0}''
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
index 5967128113..7e331fd844 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
@@ -43,6 +43,8 @@
*/
package org.eclipse.jgit.api;
+import static org.eclipse.jgit.lib.Constants.DOT_GIT;
+
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -73,6 +75,8 @@ public class CleanCommand extends GitCommand<Set<String>> {
private boolean ignore = true;
+ private boolean force = false;
+
/**
* @param repo
*/
@@ -121,25 +125,69 @@ public class CleanCommand extends GitCommand<Set<String>> {
for (String file : notIgnoredFiles)
if (paths.isEmpty() || paths.contains(file)) {
- if (!dryRun)
- FileUtils.delete(new File(repo.getWorkTree(), file));
- files.add(file);
+ files = cleanPath(file, files);
}
- if (directories)
- for (String dir : notIgnoredDirs)
- if (paths.isEmpty() || paths.contains(dir)) {
- if (!dryRun)
- FileUtils.delete(new File(repo.getWorkTree(), dir),
- FileUtils.RECURSIVE);
- files.add(dir + "/"); //$NON-NLS-1$
- }
+ for (String dir : notIgnoredDirs)
+ if (paths.isEmpty() || paths.contains(dir)) {
+ files = cleanPath(dir, files);
+ }
} catch (IOException e) {
throw new JGitInternalException(e.getMessage(), e);
}
return files;
}
+ /**
+ * When dryRun is false, deletes the specified path from disk. If dryRun
+ * is true, no paths are actually deleted. In both cases, the paths that
+ * would have been deleted are added to inFiles and returned.
+ *
+ * Paths that are directories are recursively deleted when
+ * {@link #directories} is true.
+ * Paths that are git repositories are recursively deleted when
+ * {@link #directories} and {@link #force} are both true.
+ *
+ * @param path
+ * The path to be cleaned
+ * @param inFiles
+ * A set of strings representing the files that have been cleaned
+ * already, the path to be cleaned will be added to this set
+ * before being returned.
+ *
+ * @return a set of strings with the cleaned path added to it
+ * @throws IOException
+ */
+ private Set<String> cleanPath(String path, Set<String> inFiles)
+ throws IOException {
+ File curFile = new File(repo.getWorkTree(), path);
+ if (curFile.isDirectory()) {
+ if (directories) {
+ // Is this directory a git repository?
+ if (new File(curFile, DOT_GIT).exists()) {
+ if (force) {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.RECURSIVE);
+ }
+ inFiles.add(path + "/"); //$NON-NLS-1$
+ }
+ } else {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.RECURSIVE);
+ }
+ inFiles.add(path + "/"); //$NON-NLS-1$
+ }
+ }
+ } else {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.NONE);
+ }
+ inFiles.add(path);
+ }
+
+ return inFiles;
+ }
+
private Set<String> filterIgnorePaths(Set<String> inputPaths,
Set<String> ignoredNotInIndex, boolean exact) {
if (ignore) {
@@ -196,6 +244,20 @@ public class CleanCommand extends GitCommand<Set<String>> {
}
/**
+ * If force is set, directories that are git repositories will also be
+ * deleted.
+ *
+ * @param force
+ * whether or not to delete git repositories
+ * @return {@code this}
+ * @since 4.5
+ */
+ public CleanCommand setForce(boolean force) {
+ this.force = force;
+ return this;
+ }
+
+ /**
* If dirs is set, in addition to files, also clean directories.
*
* @param dirs
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 127596fe3d..3a636a1538 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -391,6 +391,7 @@ public class JGitText extends TranslationBundle {
/***/ public String invalidChannel;
/***/ public String invalidCharacterInBase64Data;
/***/ public String invalidCommitParentNumber;
+ /***/ public String invalidDepth;
/***/ public String invalidEncryption;
/***/ public String invalidExpandWildcard;
/***/ public String invalidGitdirRef;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index ab879fa9e0..9d331ad9e7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -564,7 +564,8 @@ public class PackWriter implements AutoCloseable {
* Configure this pack for a shallow clone.
*
* @param depth
- * maximum depth to traverse the commit graph
+ * maximum depth of history to return. 1 means return only the
+ * "wants".
* @param unshallow
* objects which used to be shallow on the client, but are being
* extended as part of this fetch
@@ -730,7 +731,7 @@ public class PackWriter implements AutoCloseable {
@NonNull Set<? extends ObjectId> shallow) throws IOException {
ObjectWalk ow;
if (shallowPack) {
- ow = new DepthWalk.ObjectWalk(reader, depth);
+ ow = new DepthWalk.ObjectWalk(reader, depth - 1);
} else {
ow = new ObjectWalk(reader);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index d6c668dbf0..d1fd67e977 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -790,8 +790,9 @@ public class UploadPack {
}
private void processShallow() throws IOException {
+ int walkDepth = depth - 1;
try (DepthWalk.RevWalk depthWalk = new DepthWalk.RevWalk(
- walk.getObjectReader(), depth)) {
+ walk.getObjectReader(), walkDepth)) {
// Find all the commits which will be shallow
for (ObjectId o : wantIds) {
@@ -808,12 +809,14 @@ public class UploadPack {
// Commits at the boundary which aren't already shallow in
// the client need to be marked as such
- if (c.getDepth() == depth && !clientShallowCommits.contains(c))
+ if (c.getDepth() == walkDepth
+ && !clientShallowCommits.contains(c))
pckOut.writeString("shallow " + o.name()); //$NON-NLS-1$
// Commits not on the boundary which are shallow in the client
// need to become unshallowed
- if (c.getDepth() < depth && clientShallowCommits.remove(c)) {
+ if (c.getDepth() < walkDepth
+ && clientShallowCommits.remove(c)) {
unshallowCommits.add(c.copy());
pckOut.writeString("unshallow " + c.name()); //$NON-NLS-1$
}
@@ -948,6 +951,11 @@ public class UploadPack {
if (line.startsWith("deepen ")) { //$NON-NLS-1$
depth = Integer.parseInt(line.substring(7));
+ if (depth <= 0) {
+ throw new PackProtocolException(
+ MessageFormat.format(JGitText.get().invalidDepth,
+ Integer.valueOf(depth)));
+ }
continue;
}
@@ -974,7 +982,8 @@ public class UploadPack {
}
/**
- * Returns the clone/fetch depth. Valid only after calling recvWants().
+ * Returns the clone/fetch depth. Valid only after calling recvWants(). A
+ * depth of 1 means return only the wants.
*
* @return the depth requested by the client, or 0 if unbounded.
* @since 4.0
@@ -1487,7 +1496,7 @@ public class UploadPack {
RevWalk rw = walk;
if (depth > 0) {
pw.setShallowPack(depth, unshallowCommits);
- rw = new DepthWalk.RevWalk(walk.getObjectReader(), depth);
+ rw = new DepthWalk.RevWalk(walk.getObjectReader(), depth - 1);
rw.assumeShallow(clientShallowCommits);
}