Browse Source

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>
stable-2.2
Marc Strapetz 12 years ago committed by Chris Aniszczyk
parent
commit
67edd3eda7
  1. 42
      org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
  2. 195
      org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java
  3. 1
      org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
  4. 1
      org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
  5. 3
      org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
  6. 9
      org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
  7. 14
      org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
  8. 17
      org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
  9. 6
      org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
  10. 5
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
  11. 2
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
  12. 3
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java
  13. 38
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
  14. 6
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCursor.java

42
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.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List; import java.util.List;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
@ -58,7 +58,7 @@ import org.junit.Test;
public class FooterLineTest extends RepositoryTestCase { public class FooterLineTest extends RepositoryTestCase {
@Test @Test
public void testNoFooters_EmptyBody() { public void testNoFooters_EmptyBody() throws IOException {
final RevCommit commit = parse(""); final RevCommit commit = parse("");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -66,7 +66,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_NewlineOnlyBody1() { public void testNoFooters_NewlineOnlyBody1() throws IOException {
final RevCommit commit = parse("\n"); final RevCommit commit = parse("\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -74,7 +74,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_NewlineOnlyBody5() { public void testNoFooters_NewlineOnlyBody5() throws IOException {
final RevCommit commit = parse("\n\n\n\n\n"); final RevCommit commit = parse("\n\n\n\n\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -82,7 +82,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_OneLineBodyNoLF() { public void testNoFooters_OneLineBodyNoLF() throws IOException {
final RevCommit commit = parse("this is a commit"); final RevCommit commit = parse("this is a commit");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -90,7 +90,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_OneLineBodyWithLF() { public void testNoFooters_OneLineBodyWithLF() throws IOException {
final RevCommit commit = parse("this is a commit\n"); final RevCommit commit = parse("this is a commit\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -98,7 +98,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_ShortBodyNoLF() { public void testNoFooters_ShortBodyNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit"); final RevCommit commit = parse("subject\n\nbody of commit");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -106,7 +106,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNoFooters_ShortBodyWithLF() { public void testNoFooters_ShortBodyWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n"); final RevCommit commit = parse("subject\n\nbody of commit\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
assertNotNull(footers); assertNotNull(footers);
@ -114,7 +114,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testSignedOffBy_OneUserNoLF() { public void testSignedOffBy_OneUserNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by: A. U. Thor <a@example.com>"); + "Signed-off-by: A. U. Thor <a@example.com>");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -130,7 +130,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testSignedOffBy_OneUserWithLF() { public void testSignedOffBy_OneUserWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by: A. U. Thor <a@example.com>\n"); + "Signed-off-by: A. U. Thor <a@example.com>\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -146,7 +146,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testSignedOffBy_IgnoreWhitespace() { public void testSignedOffBy_IgnoreWhitespace() throws IOException {
// We only ignore leading whitespace on the value, trailing // We only ignore leading whitespace on the value, trailing
// is assumed part of the value. // is assumed part of the value.
// //
@ -165,7 +165,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testEmptyValueNoLF() { public void testEmptyValueNoLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by:"); + "Signed-off-by:");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -181,7 +181,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testEmptyValueWithLF() { public void testEmptyValueWithLF() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Signed-off-by:\n"); + "Signed-off-by:\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -197,7 +197,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testShortKey() { public void testShortKey() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "K:V\n"); + "K:V\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -213,7 +213,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNonDelimtedEmail() { public void testNonDelimtedEmail() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Acked-by: re@example.com\n"); + "Acked-by: re@example.com\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -229,7 +229,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testNotEmail() { public void testNotEmail() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
+ "Acked-by: Main Tain Er\n"); + "Acked-by: Main Tain Er\n");
final List<FooterLine> footers = commit.getFooterLines(); final List<FooterLine> footers = commit.getFooterLines();
@ -245,7 +245,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testSignedOffBy_ManyUsers() { public void testSignedOffBy_ManyUsers() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n" + "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block + "\n" // paragraph break, now footers appear in final block
@ -281,7 +281,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testSignedOffBy_SkipNonFooter() { public void testSignedOffBy_SkipNonFooter() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n" + "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block + "\n" // paragraph break, now footers appear in final block
@ -314,7 +314,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testFilterFootersIgnoreCase() { public void testFilterFootersIgnoreCase() throws IOException {
final RevCommit commit = parse("subject\n\nbody of commit\n" final RevCommit commit = parse("subject\n\nbody of commit\n"
+ "Not-A-Footer-Line: this line must not be read as a footer\n" + "Not-A-Footer-Line: this line must not be read as a footer\n"
+ "\n" // paragraph break, now footers appear in final block + "\n" // paragraph break, now footers appear in final block
@ -332,7 +332,7 @@ public class FooterLineTest extends RepositoryTestCase {
} }
@Test @Test
public void testMatchesBugId() { public void testMatchesBugId() throws IOException {
final RevCommit commit = parse("this is a commit subject for test\n" final RevCommit commit = parse("this is a commit subject for test\n"
+ "\n" // paragraph break, now footers appear in final block + "\n" // paragraph break, now footers appear in final block
+ "Simple-Bug-Id: 42\n"); + "Simple-Bug-Id: 42\n");
@ -352,7 +352,7 @@ public class FooterLineTest extends RepositoryTestCase {
assertFalse("not CC", line.matches(FooterKey.CC)); 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(); final StringBuilder buf = new StringBuilder();
buf.append("tree " + ObjectId.zeroId().name() + "\n"); buf.append("tree " + ObjectId.zeroId().name() + "\n");
buf.append("author A. U. Thor <a@example.com> 1 +0000\n"); buf.append("author A. U. Thor <a@example.com> 1 +0000\n");

195
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());
}
}

1
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 serviceNotEnabledNoName=Service not enabled
serviceNotPermitted={0} not permitted serviceNotPermitted={0} not permitted
serviceNotPermittedNoName=Service not permitted serviceNotPermittedNoName=Service not permitted
shallowCommitsAlreadyInitialized=Shallow commits have already been initialized
shortCompressedStreamAt=Short compressed stream at {0} shortCompressedStreamAt=Short compressed stream at {0}
shortReadOfBlock=Short read of block. shortReadOfBlock=Short read of block.
shortReadOfOptionalDIRCExtensionExpectedAnotherBytes=Short read of optional DIRC extension {0}; expected another {1} bytes within the section. shortReadOfOptionalDIRCExtensionExpectedAnotherBytes=Short read of optional DIRC extension {0}; expected another {1} bytes within the section.

1
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java

@ -484,6 +484,7 @@ public class JGitText extends TranslationBundle {
/***/ public String serviceNotEnabledNoName; /***/ public String serviceNotEnabledNoName;
/***/ public String serviceNotPermitted; /***/ public String serviceNotPermitted;
/***/ public String serviceNotPermittedNoName; /***/ public String serviceNotPermittedNoName;
/***/ public String shallowCommitsAlreadyInitialized;
/***/ public String shortCompressedStreamAt; /***/ public String shortCompressedStreamAt;
/***/ public String shortReadOfBlock; /***/ public String shortReadOfBlock;
/***/ public String shortReadOfOptionalDIRCExtensionExpectedAnotherBytes; /***/ public String shortReadOfOptionalDIRCExtensionExpectedAnotherBytes;

3
org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java

@ -340,6 +340,9 @@ public final class Constants {
/** Name of the submodules file */ /** Name of the submodules file */
public static final String DOT_GIT_MODULES = ".gitmodules"; 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. * Create a new digest function for objects.
* *

9
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.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
@ -250,6 +251,14 @@ public abstract class ObjectReader {
throws MissingObjectException, IncorrectObjectTypeException, throws MissingObjectException, IncorrectObjectTypeException,
IOException; 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. * Asynchronous object opening.
* *

14
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java

@ -80,7 +80,11 @@ public class RevCommit extends RevObject {
* available to the caller. * available to the caller.
*/ */
public static RevCommit parse(byte[] raw) { public static RevCommit parse(byte[] raw) {
try {
return parse(new RevWalk((ObjectReader) null), raw); return parse(new RevWalk((ObjectReader) null), raw);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} }
/** /**
@ -97,8 +101,10 @@ public class RevCommit extends RevObject {
* the canonical formatted commit to be parsed. * the canonical formatted commit to be parsed.
* @return the parsed commit, in an isolated revision pool that is not * @return the parsed commit, in an isolated revision pool that is not
* available to the caller. * 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(); ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
boolean retain = rw.isRetainBody(); boolean retain = rw.isRetainBody();
rw.setRetainBody(true); 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; final MutableObjectId idBuffer = walk.idBuffer;
idBuffer.fromString(raw, 5); idBuffer.fromString(raw, 5);
tree = walk.lookupTree(idBuffer); tree = walk.lookupTree(idBuffer);

17
org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java

@ -192,6 +192,8 @@ public class RevWalk implements Iterable<RevCommit> {
private boolean retainBody; private boolean retainBody;
boolean shallowCommitsInitialized;
/** /**
* Create a new revision walker for a given repository. * Create a new revision walker for a given repository.
* *
@ -1209,6 +1211,7 @@ public class RevWalk implements Iterable<RevCommit> {
roots.clear(); roots.clear();
queue = new DateRevQueue(); queue = new DateRevQueue();
pending = new StartGenerator(this); pending = new StartGenerator(this);
shallowCommitsInitialized = false;
} }
/** /**
@ -1312,4 +1315,18 @@ public class RevWalk implements Iterable<RevCommit> {
if (carry != 0) if (carry != 0)
RevCommit.carryFlags(c, carry); 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;
}
} }

6
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.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -192,6 +193,11 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs {
throw new MissingObjectException(objectId.copy(), typeHint); 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<?>>() { private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() {
public int compare(FoundObject<?> a, FoundObject<?> b) { public int compare(FoundObject<?> a, FoundObject<?> b) {
int cmp = a.packIndex - b.packIndex; int cmp = a.packIndex - b.packIndex;

5
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java

@ -141,6 +141,11 @@ class CachedObjectDirectory extends FileObjectDatabase {
return wrapped.getFS(); return wrapped.getFS();
} }
@Override
Set<ObjectId> getShallowCommits() throws IOException {
return wrapped.getShallowCommits();
}
@Override @Override
Collection<? extends CachedPack> getCachedPacks() throws IOException { Collection<? extends CachedPack> getCachedPacks() throws IOException {
return wrapped.getCachedPacks(); return wrapped.getCachedPacks();

2
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java

@ -137,6 +137,8 @@ abstract class FileObjectDatabase extends ObjectDatabase {
abstract FS getFS(); abstract FS getFS();
abstract Set<ObjectId> getShallowCommits() throws IOException;
/** /**
* Open an object from this database. * Open an object from this database.
* <p> * <p>

3
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepository.java

@ -178,7 +178,8 @@ public class FileRepository extends Repository {
objectDatabase = new ObjectDirectory(repoConfig, // objectDatabase = new ObjectDirectory(repoConfig, //
options.getObjectDirectory(), // options.getObjectDirectory(), //
options.getAlternateObjectDirectories(), // options.getAlternateObjectDirectories(), //
getFS()); getFS(), //
new File(getDirectory(), Constants.SHALLOW));
if (objectDatabase.exists()) { if (objectDatabase.exists()) {
final long repositoryFormatVersion = getConfig().getLong( final long repositoryFormatVersion = getConfig().getLong(

38
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 UnpackedObjectCache unpackedObjectCache;
private final File shallowFile;
private FileSnapshot shallowFileSnapshot = FileSnapshot.DIRTY;
private Set<ObjectId> shallowCommitsIds;
/** /**
* Initialize a reference to an on-disk object directory. * Initialize a reference to an on-disk object directory.
* *
@ -139,11 +145,14 @@ public class ObjectDirectory extends FileObjectDatabase {
* @param fs * @param fs
* the file system abstraction which will be necessary to perform * the file system abstraction which will be necessary to perform
* certain file system operations. * certain file system operations.
* @param shallowFile
* file which contains IDs of shallow commits, null if shallow
* commits handling should be turned off
* @throws IOException * @throws IOException
* an alternate object cannot be opened. * an alternate object cannot be opened.
*/ */
public ObjectDirectory(final Config cfg, final File dir, public ObjectDirectory(final Config cfg, final File dir,
File[] alternatePaths, FS fs) throws IOException { File[] alternatePaths, FS fs, File shallowFile) throws IOException {
config = cfg; config = cfg;
objects = dir; objects = dir;
infoDirectory = new File(objects, "info"); infoDirectory = new File(objects, "info");
@ -154,6 +163,7 @@ public class ObjectDirectory extends FileObjectDatabase {
cachedPacks = new AtomicReference<CachedPackList>(); cachedPacks = new AtomicReference<CachedPackList>();
unpackedObjectCache = new UnpackedObjectCache(); unpackedObjectCache = new UnpackedObjectCache();
this.fs = fs; this.fs = fs;
this.shallowFile = shallowFile;
alternates = new AtomicReference<AlternateHandle[]>(); alternates = new AtomicReference<AlternateHandle[]>();
if (alternatePaths != null) { if (alternatePaths != null) {
@ -614,6 +624,30 @@ public class ObjectDirectory extends FileObjectDatabase {
return fs; 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) { private void insertPack(final PackFile pf) {
PackList o, n; PackList o, n;
do { do {
@ -829,7 +863,7 @@ public class ObjectDirectory extends FileObjectDatabase {
return new AlternateRepository(db); 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); return new AlternateHandle(db);
} }

6
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.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -130,6 +131,11 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs {
return ldr; return ldr;
} }
@Override
public Set<ObjectId> getShallowCommits() throws IOException {
return db.getShallowCommits();
}
public long getObjectSize(AnyObjectId objectId, int typeHint) public long getObjectSize(AnyObjectId objectId, int typeHint)
throws MissingObjectException, IncorrectObjectTypeException, throws MissingObjectException, IncorrectObjectTypeException,
IOException { IOException {

Loading…
Cancel
Save