summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Strapetz <marc.strapetz@syntevo.com>2012-10-29 16:34:33 +0100
committerChris Aniszczyk <zx@twitter.com>2012-11-21 10:46:02 -0600
commit67edd3eda77fb98673065501a2cf7c9d39db668c (patch)
tree7ec3b83428de58b84343cc6707cab187398e513f
parent8eb4d926371edea2d58dc598e3ebcddacbdc326e (diff)
downloadjgit-67edd3eda77fb98673065501a2cf7c9d39db668c.tar.gz
jgit-67edd3eda77fb98673065501a2cf7c9d39db668c.zip
RevWalk support for shallow clones
StartGenerator now processes .git/shallow to have the RevWalk stop for shallow commits. See RevWalkShallowTest for tests. Bug: 394543 CQ: 6908 Change-Id: Ia5af1dab3fe9c7888f44eeecab1e1bcf2e8e48fe Signed-off-by: Chris Aniszczyk <zx@twitter.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java42
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java195
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java9
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java18
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java17
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java3
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java38
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java6
14 files changed, 318 insertions, 28 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
index 7f440df22a..1720b26bbc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
@@ -48,7 +48,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-
+import java.io.IOException;
import java.util.List;
import org.eclipse.jgit.lib.Constants;
@@ -58,7 +58,7 @@ import org.junit.Test;
public class FooterLineTest extends RepositoryTestCase {
@Test
- public void testNoFooters_EmptyBody() {
+ public void testNoFooters_EmptyBody() throws IOException {
final RevCommit commit = parse("");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -66,7 +66,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_NewlineOnlyBody1() {
+ public void testNoFooters_NewlineOnlyBody1() throws IOException {
final RevCommit commit = parse("\n");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -74,7 +74,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_NewlineOnlyBody5() {
+ public void testNoFooters_NewlineOnlyBody5() throws IOException {
final RevCommit commit = parse("\n\n\n\n\n");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -82,7 +82,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_OneLineBodyNoLF() {
+ public void testNoFooters_OneLineBodyNoLF() throws IOException {
final RevCommit commit = parse("this is a commit");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -90,7 +90,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_OneLineBodyWithLF() {
+ public void testNoFooters_OneLineBodyWithLF() throws IOException {
final RevCommit commit = parse("this is a commit\n");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -98,7 +98,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_ShortBodyNoLF() {
+ public void testNoFooters_ShortBodyNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -106,7 +106,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNoFooters_ShortBodyWithLF() {
+ public void testNoFooters_ShortBodyWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n");
final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers);
@@ -114,7 +114,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testSignedOffBy_OneUserNoLF() {
+ public void testSignedOffBy_OneUserNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by: A. U. Thor <a@example.com>");
final List<FooterLine> footers = commit.getFooterLines();
@@ -130,7 +130,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testSignedOffBy_OneUserWithLF() {
+ public void testSignedOffBy_OneUserWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by: A. U. Thor <a@example.com>\n");
final List<FooterLine> footers = commit.getFooterLines();
@@ -146,7 +146,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testSignedOffBy_IgnoreWhitespace() {
+ public void testSignedOffBy_IgnoreWhitespace() throws IOException {
// We only ignore leading whitespace on the value, trailing
// is assumed part of the value.
//
@@ -165,7 +165,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testEmptyValueNoLF() {
+ public void testEmptyValueNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by:");
final List<FooterLine> footers = commit.getFooterLines();
@@ -181,7 +181,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testEmptyValueWithLF() {
+ public void testEmptyValueWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by:\n");
final List<FooterLine> footers = commit.getFooterLines();
@@ -197,7 +197,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testShortKey() {
+ public void testShortKey() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "K:V\n");
final List<FooterLine> footers = commit.getFooterLines();
@@ -213,7 +213,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNonDelimtedEmail() {
+ public void testNonDelimtedEmail() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Acked-by: re@example.com\n");
final List<FooterLine> footers = commit.getFooterLines();
@@ -229,7 +229,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testNotEmail() {
+ public void testNotEmail() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Acked-by: Main Tain Er\n");
final List<FooterLine> footers = commit.getFooterLines();
@@ -245,7 +245,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testSignedOffBy_ManyUsers() {
+ public void testSignedOffBy_ManyUsers() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block
@@ -281,7 +281,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testSignedOffBy_SkipNonFooter() {
+ public void testSignedOffBy_SkipNonFooter() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block
@@ -314,7 +314,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testFilterFootersIgnoreCase() {
+ public void testFilterFootersIgnoreCase() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block
@@ -332,7 +332,7 @@ public class FooterLineTest extends RepositoryTestCase {
}
@Test
- public void testMatchesBugId() {
+ public void testMatchesBugId() throws IOException {
final RevCommit commit = parse("this is a commit subject for test\n"
+ "\n" // paragraph break, now footers appear in final block
+ "Simple-Bug-Id: 42\n");
@@ -352,7 +352,7 @@ public class FooterLineTest extends RepositoryTestCase {
assertFalse("not CC", line.matches(FooterKey.CC));
}
- private RevCommit parse(final String msg) {
+ private RevCommit parse(final String msg) throws IOException {
final StringBuilder buf = new StringBuilder();
buf.append("tree " + ObjectId.zeroId().name() + "\n");
buf.append("author A. U. Thor <a@example.com> 1 +0000\n");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java
new file mode 100644
index 0000000000..479d9d304a
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2012, Marc Strapetz <marc.strapetz@syntevo.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.revwalk;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lib.*;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+public class RevWalkShallowTest extends RevWalkTestCase {
+
+ // Accessing ==============================================================
+
+ @Test
+ public void testDepth1() throws Exception {
+ final RevCommit a = commit();
+ final RevCommit b = commit(a);
+ final RevCommit c = commit(b);
+ final RevCommit d = commit(c);
+
+ createShallowFile(d);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testDepth2() throws Exception {
+ final RevCommit a = commit();
+ final RevCommit b = commit(a);
+ final RevCommit c = commit(b);
+ final RevCommit d = commit(c);
+
+ createShallowFile(c);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertCommit(c, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testDepth3() throws Exception {
+ final RevCommit a = commit();
+ final RevCommit b = commit(a);
+ final RevCommit c = commit(b);
+ final RevCommit d = commit(c);
+
+ createShallowFile(b);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertCommit(c, rw.next());
+ assertCommit(b, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testMergeCommitOneParentShallow() throws Exception {
+ final RevCommit a = commit();
+ final RevCommit b = commit(a);
+ final RevCommit c = commit(b);
+ final RevCommit d = commit(b);
+ final RevCommit e = commit(d);
+ final RevCommit merge = commit(c, e);
+
+ createShallowFile(e);
+
+ rw.reset();
+ markStart(merge);
+ assertCommit(merge, rw.next());
+ assertCommit(e, rw.next());
+ assertCommit(c, rw.next());
+ assertCommit(b, rw.next());
+ assertCommit(a, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testMergeCommitEntirelyShallow() throws Exception {
+ final RevCommit a = commit();
+ final RevCommit b = commit(a);
+ final RevCommit c = commit(b);
+ final RevCommit d = commit(b);
+ final RevCommit e = commit(d);
+ final RevCommit merge = commit(c, e);
+
+ createShallowFile(c, e);
+
+ rw.reset();
+ markStart(merge);
+ assertCommit(merge, rw.next());
+ assertCommit(e, rw.next());
+ assertCommit(c, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testObjectDirectorySnapshot() throws Exception {
+ RevCommit a = commit();
+ RevCommit b = commit(a);
+ RevCommit c = commit(b);
+ RevCommit d = commit(c);
+
+ createShallowFile(d);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertNull(rw.next());
+
+ rw = createRevWalk();
+ a = rw.lookupCommit(a);
+ b = rw.lookupCommit(b);
+ c = rw.lookupCommit(c);
+ d = rw.lookupCommit(d);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertNull(rw.next());
+
+ createShallowFile(c);
+
+ rw = createRevWalk();
+ a = rw.lookupCommit(a);
+ b = rw.lookupCommit(b);
+ c = rw.lookupCommit(c);
+ d = rw.lookupCommit(d);
+
+ rw.reset();
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertCommit(c, rw.next());
+ assertNull(rw.next());
+ }
+
+ private void createShallowFile(ObjectId... shallowCommits)
+ throws IOException {
+ final StringBuilder builder = new StringBuilder();
+ for (ObjectId commit : shallowCommits)
+ builder.append(commit.getName() + "\n");
+ JGitTestUtil.write(new File(rw.repository.getDirectory(), "shallow"),
+ builder.toString());
+ }
+}
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 e7b1fe8956..3270267881 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -423,6 +423,7 @@ sequenceTooLargeForDiffAlgorithm=Sequence too large for difference algorithm.
serviceNotEnabledNoName=Service not enabled
serviceNotPermitted={0} not permitted
serviceNotPermittedNoName=Service not permitted
+shallowCommitsAlreadyInitialized=Shallow commits have already been initialized
shortCompressedStreamAt=Short compressed stream at {0}
shortReadOfBlock=Short read of block.
shortReadOfOptionalDIRCExtensionExpectedAnotherBytes=Short read of optional DIRC extension {0}; expected another {1} bytes within the section.
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 48963253c6..7caeba8beb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -484,6 +484,7 @@ public class JGitText extends TranslationBundle {
/***/ public String serviceNotEnabledNoName;
/***/ public String serviceNotPermitted;
/***/ public String serviceNotPermittedNoName;
+ /***/ public String shallowCommitsAlreadyInitialized;
/***/ public String shortCompressedStreamAt;
/***/ public String shortReadOfBlock;
/***/ public String shortReadOfOptionalDIRCExtensionExpectedAnotherBytes;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index d5be3157d5..e66e3a8354 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -340,6 +340,9 @@ public final class Constants {
/** Name of the submodules file */
public static final String DOT_GIT_MODULES = ".gitmodules";
+ /** Name of the .git/shallow file */
+ public static final String SHALLOW = "shallow";
+
/**
* Create a new digest function for objects.
*
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
index cd3706bbe3..ee4f3d9e08 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -48,6 +48,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -251,6 +252,14 @@ public abstract class ObjectReader {
IOException;
/**
+ * Returns IDs for those commits which should be considered as shallow.
+ *
+ * @return IDs of shallow commits
+ * @throws IOException
+ */
+ public abstract Set<ObjectId> getShallowCommits() throws IOException;
+
+ /**
* Asynchronous object opening.
*
* @param <T>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
index 05c173888a..6363014415 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
@@ -80,7 +80,11 @@ public class RevCommit extends RevObject {
* available to the caller.
*/
public static RevCommit parse(byte[] raw) {
- return parse(new RevWalk((ObjectReader) null), raw);
+ try {
+ return parse(new RevWalk((ObjectReader) null), raw);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
}
/**
@@ -88,7 +92,7 @@ public class RevCommit extends RevObject {
*
* This method inserts the commit directly into the caller supplied revision
* pool, making it appear as though the commit exists in the repository,
- * even if it doesn't. The repository under the pool is not affected.
+ * even if it doesn't. The repository under the pool is not affected.
*
* @param rw
* the revision pool to allocate the commit within. The commit's
@@ -97,8 +101,10 @@ public class RevCommit extends RevObject {
* the canonical formatted commit to be parsed.
* @return the parsed commit, in an isolated revision pool that is not
* available to the caller.
+ * @throws IOException
+ * in case of RevWalk initialization fails
*/
- public static RevCommit parse(RevWalk rw, byte[] raw) {
+ public static RevCommit parse(RevWalk rw, byte[] raw) throws IOException {
ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
boolean retain = rw.isRetainBody();
rw.setRetainBody(true);
@@ -146,7 +152,11 @@ public class RevCommit extends RevObject {
}
}
- void parseCanonical(final RevWalk walk, final byte[] raw) {
+ void parseCanonical(final RevWalk walk, final byte[] raw)
+ throws IOException {
+ if (!walk.shallowCommitsInitialized)
+ walk.initializeShallowCommits();
+
final MutableObjectId idBuffer = walk.idBuffer;
idBuffer.fromString(raw, 5);
tree = walk.lookupTree(idBuffer);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
index 93428f9851..8e07048e21 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -192,6 +192,8 @@ public class RevWalk implements Iterable<RevCommit> {
private boolean retainBody;
+ boolean shallowCommitsInitialized;
+
/**
* Create a new revision walker for a given repository.
*
@@ -1209,6 +1211,7 @@ public class RevWalk implements Iterable<RevCommit> {
roots.clear();
queue = new DateRevQueue();
pending = new StartGenerator(this);
+ shallowCommitsInitialized = false;
}
/**
@@ -1312,4 +1315,18 @@ public class RevWalk implements Iterable<RevCommit> {
if (carry != 0)
RevCommit.carryFlags(c, carry);
}
+
+ void initializeShallowCommits() throws IOException {
+ if (shallowCommitsInitialized)
+ throw new IllegalStateException(
+ JGitText.get().shallowCommitsAlreadyInitialized);
+
+ shallowCommitsInitialized = true;
+
+ if (reader == null)
+ return;
+
+ for (ObjectId id : reader.getShallowCommits())
+ lookupCommit(id).parents = RevCommit.NO_PARENTS;
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
index 6a76258ed3..b5244d0439 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
@@ -61,6 +61,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
@@ -192,6 +193,11 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs {
throw new MissingObjectException(objectId.copy(), typeHint);
}
+ @Override
+ public Set<ObjectId> getShallowCommits() {
+ return Collections.emptySet();
+ }
+
private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() {
public int compare(FoundObject<?> a, FoundObject<?> b) {
int cmp = a.packIndex - b.packIndex;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
index 8e87b08ee2..37ab0e0860 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
@@ -142,6 +142,11 @@ class CachedObjectDirectory extends FileObjectDatabase {
}
@Override
+ Set<ObjectId> getShallowCommits() throws IOException {
+ return wrapped.getShallowCommits();
+ }
+
+ @Override
Collection<? extends CachedPack> getCachedPacks() throws IOException {
return wrapped.getCachedPacks();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
index f28facbec6..ffbd2edfbd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
@@ -137,6 +137,8 @@ abstract class FileObjectDatabase extends ObjectDatabase {
abstract FS getFS();
+ abstract Set<ObjectId> getShallowCommits() throws IOException;
+
/**
* Open an object from this database.
* <p>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java
index 33a51269de..2393e607e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java
@@ -178,7 +178,8 @@ public class FileRepository extends Repository {
objectDatabase = new ObjectDirectory(repoConfig, //
options.getObjectDirectory(), //
options.getAlternateObjectDirectories(), //
- getFS());
+ getFS(), //
+ new File(getDirectory(), Constants.SHALLOW));
if (objectDatabase.exists()) {
final long repositoryFormatVersion = getConfig().getLong(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
index eab6ed6e70..7b5d3a63c7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
@@ -127,6 +127,12 @@ public class ObjectDirectory extends FileObjectDatabase {
private final UnpackedObjectCache unpackedObjectCache;
+ private final File shallowFile;
+
+ private FileSnapshot shallowFileSnapshot = FileSnapshot.DIRTY;
+
+ private Set<ObjectId> shallowCommitsIds;
+
/**
* Initialize a reference to an on-disk object directory.
*
@@ -139,11 +145,14 @@ public class ObjectDirectory extends FileObjectDatabase {
* @param fs
* the file system abstraction which will be necessary to perform
* certain file system operations.
+ * @param shallowFile
+ * file which contains IDs of shallow commits, null if shallow
+ * commits handling should be turned off
* @throws IOException
* an alternate object cannot be opened.
*/
public ObjectDirectory(final Config cfg, final File dir,
- File[] alternatePaths, FS fs) throws IOException {
+ File[] alternatePaths, FS fs, File shallowFile) throws IOException {
config = cfg;
objects = dir;
infoDirectory = new File(objects, "info");
@@ -154,6 +163,7 @@ public class ObjectDirectory extends FileObjectDatabase {
cachedPacks = new AtomicReference<CachedPackList>();
unpackedObjectCache = new UnpackedObjectCache();
this.fs = fs;
+ this.shallowFile = shallowFile;
alternates = new AtomicReference<AlternateHandle[]>();
if (alternatePaths != null) {
@@ -614,6 +624,30 @@ public class ObjectDirectory extends FileObjectDatabase {
return fs;
}
+ @Override
+ Set<ObjectId> getShallowCommits() throws IOException {
+ if (shallowFile == null || !shallowFile.isFile())
+ return Collections.emptySet();
+
+ if (shallowFileSnapshot == null
+ || shallowFileSnapshot.isModified(shallowFile)) {
+ shallowCommitsIds = new HashSet<ObjectId>();
+
+ final BufferedReader reader = open(shallowFile);
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ shallowCommitsIds.add(ObjectId.fromString(line));
+ } finally {
+ reader.close();
+ }
+
+ shallowFileSnapshot = FileSnapshot.save(shallowFile);
+ }
+
+ return shallowCommitsIds;
+ }
+
private void insertPack(final PackFile pf) {
PackList o, n;
do {
@@ -829,7 +863,7 @@ public class ObjectDirectory extends FileObjectDatabase {
return new AlternateRepository(db);
}
- ObjectDirectory db = new ObjectDirectory(config, objdir, null, fs);
+ ObjectDirectory db = new ObjectDirectory(config, objdir, null, fs, null);
return new AlternateHandle(db);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java
index 0e9970fcc8..5555a3c404 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java
@@ -52,6 +52,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
@@ -130,6 +131,11 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs {
return ldr;
}
+ @Override
+ public Set<ObjectId> getShallowCommits() throws IOException {
+ return db.getShallowCommits();
+ }
+
public long getObjectSize(AnyObjectId objectId, int typeHint)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {