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>tags/v2.2.0.201212191850-r
@@ -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"); |
@@ -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()); | |||
} | |||
} |
@@ -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. |
@@ -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; |
@@ -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. | |||
* |
@@ -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; | |||
@@ -250,6 +251,14 @@ public abstract class ObjectReader { | |||
throws MissingObjectException, IncorrectObjectTypeException, | |||
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. | |||
* |
@@ -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); |
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -141,6 +141,11 @@ class CachedObjectDirectory extends FileObjectDatabase { | |||
return wrapped.getFS(); | |||
} | |||
@Override | |||
Set<ObjectId> getShallowCommits() throws IOException { | |||
return wrapped.getShallowCommits(); | |||
} | |||
@Override | |||
Collection<? extends CachedPack> getCachedPacks() throws IOException { | |||
return wrapped.getCachedPacks(); |
@@ -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> |
@@ -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( |
@@ -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); | |||
} | |||
@@ -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 { |