Browse Source

Merge branch 'stable-1.0'

* stable-1.0:
  DHT: Support removing a repository name
  DHT: Fix thread-safety issue in AbstractWriteBuffer
  jgit.sh: Implement pager support
  Change EditList to extend ArrayList
  Ensure the HTTP request is fully consumed
  Make sure test repositories are closed
  Fix CloneCommand not to fetch into remote tracking branches when bare
  Update Eclipse IP log for 1.0

Change-Id: I6340d551482e1dda01f82496296d2038b07fa68b
stable-1.1
Shawn O. Pearce 14 years ago
parent
commit
690c268c79
  1. 6
      .eclipse_iplog
  2. 11
      org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
  3. 37
      org.eclipse.jgit.pgm/jgit.sh
  4. 17
      org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/RepositoryIndexTable.java
  5. 14
      org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/cache/CacheRepositoryIndexTable.java
  6. 12
      org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/memory/MemRepositoryIndexTable.java
  7. 25
      org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java
  8. 79
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
  9. 5
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java
  10. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java
  11. 4
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
  12. 32
      org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java
  13. 20
      org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
  14. 56
      org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java
  15. 36
      org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
  16. 1
      org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
  17. 11
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

6
.eclipse_iplog

@ -120,9 +120,3 @@
license = Apache License, 2.0 license = Apache License, 2.0
use = unmodified source & binary use = unmodified source & binary
state = approved state = approved
[CQ "5135"]
description = Protocol Buffers Version: 2.4.0a (ATO CQ4876)
license = New BSD license
use = unmodified source & binary
state = approved

11
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java

@ -302,6 +302,17 @@ public abstract class LocalDiskRepositoryTestCase {
return db; return db;
} }
/**
* Adds a repository to the list of repositories which is closed at the end
* of the tests
*
* @param r
* the repository to be closed
*/
public void addRepoToClose(Repository r) {
toClose.add(r);
}
/** /**
* Creates a new unique directory for a test repository * Creates a new unique directory for a test repository
* *

37
org.eclipse.jgit.pgm/jgit.sh

@ -41,6 +41,20 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmd=
for a in "$@"
do
case "$a" in
-*) continue ;;
*) cmd=$a; break; ;;
esac
done
use_pager=
case "$cmd" in
diff) use_pager=1 ;;
log) use_pager=1 ;;
esac
this_script=`which "$0" 2>/dev/null` this_script=`which "$0" 2>/dev/null`
[ $? -gt 0 -a -f "$0" ] && this_script="$0" [ $? -gt 0 -a -f "$0" ] && this_script="$0"
@ -58,7 +72,7 @@ CYGWIN*)
cp=`cygpath --windows --mixed --path "$cp"` cp=`cygpath --windows --mixed --path "$cp"`
;; ;;
Darwin) Darwin)
if test -e /System/Library/Frameworks/JavaVM.framework if [ -e /System/Library/Frameworks/JavaVM.framework ]
then then
java_args=' java_args='
-Dcom.apple.mrj.application.apple.menu.about.name=JGit -Dcom.apple.mrj.application.apple.menu.about.name=JGit
@ -74,10 +88,25 @@ CLASSPATH="$cp"
export CLASSPATH export CLASSPATH
java=java java=java
if test -n "$JAVA_HOME" if [ -n "$JAVA_HOME" ]
then then
java="$JAVA_HOME/bin/java" java="$JAVA_HOME/bin/java"
fi fi
exec "$java" $java_args org.eclipse.jgit.pgm.Main "$@" if [ -n "$use_pager" ]
exit 1 then
use_pager=${GIT_PAGER:-${PAGER:-less}}
[ cat = "$use_pager" ] && use_pager=
fi
if [ -n "$use_pager" ]
then
LESS=${LESS:-FSRX}
export LESS
"$java" $java_args org.eclipse.jgit.pgm.Main "$@" | $use_pager
exit
else
exec "$java" $java_args org.eclipse.jgit.pgm.Main "$@"
exit 1
fi

17
org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/RepositoryIndexTable.java

@ -87,4 +87,21 @@ public interface RepositoryIndexTable {
*/ */
public void putUnique(RepositoryName name, RepositoryKey key) public void putUnique(RepositoryName name, RepositoryKey key)
throws DhtException, TimeoutException; throws DhtException, TimeoutException;
/**
* Remove the association of a name to an identifier.
* <p>
* This method must use some sort of transaction system to ensure the name
* is removed only if it currently references {@code key}. This may require
* running some sort of lock management service in parallel to the database.
*
* @param name
* name of the repository.
* @param key
* internal key defining the repository.
* @throws DhtException
* @throws TimeoutException
*/
public void remove(RepositoryName name, RepositoryKey key)
throws DhtException, TimeoutException;
} }

14
org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/cache/CacheRepositoryIndexTable.java vendored

@ -128,4 +128,18 @@ public class CacheRepositoryIndexTable implements RepositoryIndexTable {
throw new TimeoutException(); throw new TimeoutException();
} }
} }
public void remove(RepositoryName name, RepositoryKey key)
throws DhtException, TimeoutException {
db.remove(name, key);
Sync<Void> sync = Sync.create();
CacheKey memKey = ns.key(name);
client.modify(singleton(Change.remove(memKey)), sync);
try {
sync.get(options.getTimeout());
} catch (InterruptedException e) {
throw new TimeoutException();
}
}
} }

12
org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/memory/MemRepositoryIndexTable.java

@ -78,4 +78,16 @@ final class MemRepositoryIndexTable implements RepositoryIndexTable {
throw new DhtException(MessageFormat.format( throw new DhtException(MessageFormat.format(
DhtText.get().repositoryAlreadyExists, name.asString())); DhtText.get().repositoryAlreadyExists, name.asString()));
} }
public void remove(RepositoryName name, RepositoryKey key)
throws DhtException, TimeoutException {
boolean ok = table.compareAndSet(
name.asBytes(),
colId.name(),
key.asBytes(),
null);
if (!ok)
throw new DhtException(MessageFormat.format(
DhtText.get().repositoryAlreadyExists, name.asString()));
}
} }

25
org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/spi/util/AbstractWriteBuffer.java

@ -82,6 +82,8 @@ public abstract class AbstractWriteBuffer implements WriteBuffer {
private final List<Future<?>> running; private final List<Future<?>> running;
private final Object runningLock;
private final Semaphore spaceAvailable; private final Semaphore spaceAvailable;
private int queuedCount; private int queuedCount;
@ -102,6 +104,7 @@ public abstract class AbstractWriteBuffer implements WriteBuffer {
this.executor = executor; this.executor = executor;
this.bufferSize = bufferSize; this.bufferSize = bufferSize;
this.running = new LinkedList<Future<?>>(); this.running = new LinkedList<Future<?>>();
this.runningLock = new Object();
this.spaceAvailable = new Semaphore(bufferSize); this.spaceAvailable = new Semaphore(bufferSize);
} }
@ -189,14 +192,18 @@ public abstract class AbstractWriteBuffer implements WriteBuffer {
} }
} }
checkRunningTasks(true); synchronized (runningLock) {
checkRunningTasks(true);
}
} finally { } finally {
flushing = false; flushing = false;
} }
} }
public void abort() throws DhtException { public void abort() throws DhtException {
checkRunningTasks(true); synchronized (runningLock) {
checkRunningTasks(true);
}
} }
private void acquireSpace(int sz) throws DhtException { private void acquireSpace(int sz) throws DhtException {
@ -259,9 +266,11 @@ public abstract class AbstractWriteBuffer implements WriteBuffer {
return; return;
} }
if (!flushing) synchronized (runningLock) {
checkRunningTasks(false); if (!flushing)
running.add(executor.submit(op)); checkRunningTasks(false);
running.add(executor.submit(op));
}
} }
/** /**
@ -284,8 +293,10 @@ public abstract class AbstractWriteBuffer implements WriteBuffer {
int size) throws DhtException { int size) throws DhtException {
int permits = permitsForSize(size); int permits = permitsForSize(size);
WrappedCallback<T> op = new WrappedCallback<T>(callback, permits); WrappedCallback<T> op = new WrappedCallback<T>(callback, permits);
checkRunningTasks(false); synchronized (runningLock) {
running.add(op); checkRunningTasks(false);
running.add(op);
}
return op; return op;
} }

79
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java

@ -49,12 +49,14 @@ import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.api.ListBranchCommand.ListMode; import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.lib.RepositoryTestCase;
@ -99,6 +101,7 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI("file://" command.setURI("file://"
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2); assertNotNull(git2);
ObjectId id = git2.getRepository().resolve("tag-for-blob"); ObjectId id = git2.getRepository().resolve("tag-for-blob");
assertNotNull(id); assertNotNull(id);
@ -133,9 +136,51 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI("file://" command.setURI("file://"
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(),
"refs/heads/master");
assertEquals(
"refs/heads/master, refs/remotes/origin/master, refs/remotes/origin/test",
allRefNames(git2.branchList().setListMode(ListMode.ALL)
.call()));
// Same thing, but now without checkout
directory = createTempDirectory("testCloneRepositoryWithBranch_bare");
command = Git.cloneRepository();
command.setBranch("refs/heads/master");
command.setDirectory(directory);
command.setURI("file://"
+ git.getRepository().getWorkTree().getPath());
command.setNoCheckout(true);
git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2); assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), assertEquals(git2.getRepository().getFullBranch(),
"refs/heads/master"); "refs/heads/master");
assertEquals(
"refs/remotes/origin/master, refs/remotes/origin/test",
allRefNames(git2.branchList().setListMode(ListMode.ALL)
.call()));
// Same thing, but now test with bare repo
directory = createTempDirectory("testCloneRepositoryWithBranch_bare");
command = Git.cloneRepository();
command.setBranch("refs/heads/master");
command.setDirectory(directory);
command.setURI("file://"
+ git.getRepository().getWorkTree().getPath());
command.setBare(true);
git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(),
"refs/heads/master");
assertEquals("refs/heads/master, refs/heads/test", allRefNames(git2
.branchList().setListMode(ListMode.ALL).call()));
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); fail(e.getMessage());
} }
@ -153,16 +198,46 @@ public class CloneCommandTest extends RepositoryTestCase {
command.setURI("file://" command.setURI("file://"
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2); assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(), assertEquals(git2.getRepository().getFullBranch(),
"refs/heads/master"); "refs/heads/master");
assertEquals(1, git2.branchList().setListMode(ListMode.REMOTE) assertEquals("refs/remotes/origin/master",
.call().size()); allRefNames(git2.branchList()
.setListMode(ListMode.REMOTE).call()));
// Same thing, but now test with bare repo
directory = createTempDirectory("testCloneRepositoryWithBranch_bare");
command = Git.cloneRepository();
command.setBranch("refs/heads/master");
command.setBranchesToClone(Collections
.singletonList("refs/heads/master"));
command.setDirectory(directory);
command.setURI("file://"
+ git.getRepository().getWorkTree().getPath());
command.setBare(true);
git2 = command.call();
addRepoToClose(git2.getRepository());
assertNotNull(git2);
assertEquals(git2.getRepository().getFullBranch(),
"refs/heads/master");
assertEquals("refs/heads/master", allRefNames(git2
.branchList().setListMode(ListMode.ALL).call()));
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); fail(e.getMessage());
} }
} }
public static String allRefNames(List<Ref> refs) {
StringBuilder sb = new StringBuilder();
for (Ref f : refs) {
if (sb.length() > 0)
sb.append(", ");
sb.append(f.getName());
}
return sb.toString();
}
public static File createTempDirectory(String name) throws IOException { public static File createTempDirectory(String name) throws IOException {
final File temp; final File temp;
temp = File.createTempFile(name, Long.toString(System.nanoTime())); temp = File.createTempFile(name, Long.toString(System.nanoTime()));

5
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java

@ -72,6 +72,7 @@ public class GitConstructionTest extends RepositoryTestCase {
.setURI(db.getDirectory().toURI().toString()) .setURI(db.getDirectory().toURI().toString())
.setDirectory(createUniqueTestGitDir(true)).call() .setDirectory(createUniqueTestGitDir(true)).call()
.getRepository(); .getRepository();
addRepoToClose(bareRepo);
} }
@Override @Override
@ -88,7 +89,7 @@ public class GitConstructionTest extends RepositoryTestCase {
assertEquals(1, git.branchList().call().size()); assertEquals(1, git.branchList().call().size());
git = Git.wrap(bareRepo); git = Git.wrap(bareRepo);
assertEquals(2, git.branchList().setListMode(ListMode.ALL).call() assertEquals(1, git.branchList().setListMode(ListMode.ALL).call()
.size()); .size());
try { try {
@ -105,7 +106,7 @@ public class GitConstructionTest extends RepositoryTestCase {
assertEquals(1, git.branchList().call().size()); assertEquals(1, git.branchList().call().size());
git = Git.open(bareRepo.getDirectory()); git = Git.open(bareRepo.getDirectory());
assertEquals(2, git.branchList().setListMode(ListMode.ALL).call() assertEquals(1, git.branchList().setListMode(ListMode.ALL).call()
.size()); .size());
git = Git.open(db.getWorkTree()); git = Git.open(db.getWorkTree());

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java

@ -70,6 +70,7 @@ public class InitCommandTest extends RepositoryTestCase {
InitCommand command = new InitCommand(); InitCommand command = new InitCommand();
command.setDirectory(directory); command.setDirectory(directory);
Repository repository = command.call().getRepository(); Repository repository = command.call().getRepository();
addRepoToClose(repository);
assertNotNull(repository); assertNotNull(repository);
} catch (Exception e) { } catch (Exception e) {
fail(e.getMessage()); fail(e.getMessage());
@ -84,6 +85,7 @@ public class InitCommandTest extends RepositoryTestCase {
command.setDirectory(directory); command.setDirectory(directory);
command.setBare(true); command.setBare(true);
Repository repository = command.call().getRepository(); Repository repository = command.call().getRepository();
addRepoToClose(repository);
assertNotNull(repository); assertNotNull(repository);
assertTrue(repository.isBare()); assertTrue(repository.isBare());
} catch (Exception e) { } catch (Exception e) {

4
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java

@ -89,6 +89,8 @@ public class LsRemoteCommandTest extends RepositoryTestCase {
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
command.setCloneAllBranches(true); command.setCloneAllBranches(true);
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
LsRemoteCommand lsRemoteCommand = git2.lsRemote(); LsRemoteCommand lsRemoteCommand = git2.lsRemote();
Collection<Ref> refs = lsRemoteCommand.call(); Collection<Ref> refs = lsRemoteCommand.call();
@ -109,6 +111,7 @@ public class LsRemoteCommandTest extends RepositoryTestCase {
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
command.setCloneAllBranches(true); command.setCloneAllBranches(true);
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
LsRemoteCommand lsRemoteCommand = git2.lsRemote(); LsRemoteCommand lsRemoteCommand = git2.lsRemote();
lsRemoteCommand.setTags(true); lsRemoteCommand.setTags(true);
@ -130,6 +133,7 @@ public class LsRemoteCommandTest extends RepositoryTestCase {
+ git.getRepository().getWorkTree().getPath()); + git.getRepository().getWorkTree().getPath());
command.setCloneAllBranches(true); command.setCloneAllBranches(true);
Git git2 = command.call(); Git git2 = command.call();
addRepoToClose(git2.getRepository());
LsRemoteCommand lsRemoteCommand = git2.lsRemote(); LsRemoteCommand lsRemoteCommand = git2.lsRemote();
lsRemoteCommand.setHeads(true); lsRemoteCommand.setHeads(true);

32
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java

@ -46,7 +46,9 @@
package org.eclipse.jgit.transport; package org.eclipse.jgit.transport;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
@ -54,8 +56,10 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.zip.Deflater; import java.util.zip.Deflater;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
@ -69,6 +73,7 @@ import org.eclipse.jgit.storage.file.ObjectDirectoryPackParser;
import org.eclipse.jgit.storage.file.PackFile; import org.eclipse.jgit.storage.file.PackFile;
import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.TemporaryBuffer;
import org.eclipse.jgit.util.io.UnionInputStream;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
@ -177,6 +182,33 @@ public class PackParserTest extends RepositoryTestCase {
p.parse(NullProgressMonitor.INSTANCE); p.parse(NullProgressMonitor.INSTANCE);
} }
@Test
public void testPackWithTrailingGarbage() throws Exception {
TestRepository d = new TestRepository(db);
RevBlob a = d.blob("a");
TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
packHeader(pack, 1);
pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
a.copyRawTo(pack);
deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
digest(pack);
PackParser p = index(new UnionInputStream(
new ByteArrayInputStream(pack.toByteArray()),
new ByteArrayInputStream(new byte[] { 0x7e })));
p.setAllowThin(true);
p.setCheckEofAfterPackFooter(true);
try {
p.parse(NullProgressMonitor.INSTANCE);
fail("Pack with trailing garbage was accepted");
} catch (IOException err) {
assertEquals(
MessageFormat.format(JGitText.get().expectedEOFReceived, "\\x73"),
err.getMessage());
}
}
private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt) private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt)
throws IOException { throws IOException {
final byte[] hdr = new byte[8]; final byte[] hdr = new byte[8];

20
org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java

@ -98,6 +98,8 @@ public class CloneCommand implements Callable<Git> {
private boolean cloneAllBranches; private boolean cloneAllBranches;
private boolean noCheckout;
private Collection<String> branchesToClone; private Collection<String> branchesToClone;
/** /**
@ -112,7 +114,8 @@ public class CloneCommand implements Callable<Git> {
URIish u = new URIish(uri); URIish u = new URIish(uri);
Repository repository = init(u); Repository repository = init(u);
FetchResult result = fetch(repository, u); FetchResult result = fetch(repository, u);
checkout(repository, result); if (!noCheckout)
checkout(repository, result);
return new Git(repository); return new Git(repository);
} catch (IOException ioe) { } catch (IOException ioe) {
throw new JGitInternalException(ioe.getMessage(), ioe); throw new JGitInternalException(ioe.getMessage(), ioe);
@ -140,7 +143,8 @@ public class CloneCommand implements Callable<Git> {
RemoteConfig config = new RemoteConfig(repo.getConfig(), remote); RemoteConfig config = new RemoteConfig(repo.getConfig(), remote);
config.addURI(u); config.addURI(u);
final String dst = Constants.R_REMOTES + config.getName(); final String dst = bare ? Constants.R_HEADS : Constants.R_REMOTES
+ config.getName();
RefSpec refSpec = new RefSpec(); RefSpec refSpec = new RefSpec();
refSpec = refSpec.setForceUpdate(true); refSpec = refSpec.setForceUpdate(true);
refSpec = refSpec.setSourceDestination(Constants.R_HEADS + "*", dst + "/*"); //$NON-NLS-1$ //$NON-NLS-2$ refSpec = refSpec.setSourceDestination(Constants.R_HEADS + "*", dst + "/*"); //$NON-NLS-1$ //$NON-NLS-2$
@ -368,4 +372,16 @@ public class CloneCommand implements Callable<Git> {
return this; return this;
} }
/**
* @param noCheckout
* if set to <code>true</code> no branch will be checked out
* after the clone. This enhances performance of the clone
* command when there is no need for a checked out branch.
* @return {@code this}
*/
public CloneCommand setNoCheckout(boolean noCheckout) {
this.noCheckout = noCheckout;
return this;
}
} }

56
org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java

@ -43,12 +43,12 @@
package org.eclipse.jgit.diff; package org.eclipse.jgit.diff;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
/** Specialized list of {@link Edit}s in a document. */ /** Specialized list of {@link Edit}s in a document. */
public class EditList extends AbstractList<Edit> { public class EditList extends ArrayList<Edit> {
private static final long serialVersionUID = 1L;
/** /**
* Construct an edit list containing a single edit. * Construct an edit list containing a single edit.
* *
@ -62,11 +62,9 @@ public class EditList extends AbstractList<Edit> {
return res; return res;
} }
private final ArrayList<Edit> container;
/** Create a new, empty edit list. */ /** Create a new, empty edit list. */
public EditList() { public EditList() {
container = new ArrayList<Edit>(); super(16);
} }
/** /**
@ -77,53 +75,11 @@ public class EditList extends AbstractList<Edit> {
* added to the list, it will be grown to support them. * added to the list, it will be grown to support them.
*/ */
public EditList(int capacity) { public EditList(int capacity) {
container = new ArrayList<Edit>(capacity); super(capacity);
}
@Override
public int size() {
return container.size();
}
@Override
public Edit get(final int index) {
return container.get(index);
}
@Override
public Edit set(final int index, final Edit element) {
return container.set(index, element);
}
@Override
public void add(final int index, final Edit element) {
container.add(index, element);
}
@Override
public boolean addAll(Collection<? extends Edit> c) {
return container.addAll(c);
}
@Override
public Edit remove(final int index) {
return container.remove(index);
}
@Override
public int hashCode() {
return container.hashCode();
}
@Override
public boolean equals(final Object o) {
if (o instanceof EditList)
return container.equals(((EditList) o).container);
return false;
} }
@Override @Override
public String toString() { public String toString() {
return "EditList" + container.toString(); return "EditList" + super.toString();
} }
} }

36
org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java

@ -136,6 +136,8 @@ public abstract class PackParser {
private boolean needBaseObjectIds; private boolean needBaseObjectIds;
private boolean checkEofAfterPackFooter;
private long objectCount; private long objectCount;
private PackedObjectInfo[] entries; private PackedObjectInfo[] entries;
@ -282,6 +284,21 @@ public abstract class PackParser {
this.needBaseObjectIds = b; this.needBaseObjectIds = b;
} }
/** @return true if the EOF should be read from the input after the footer. */
public boolean isCheckEofAfterPackFooter() {
return checkEofAfterPackFooter;
}
/**
* Ensure EOF is read from the input stream after the footer.
*
* @param b
* true if the EOF should be read; false if it is not checked.
*/
public void setCheckEofAfterPackFooter(boolean b) {
checkEofAfterPackFooter = b;
}
/** @return the new objects that were sent by the user */ /** @return the new objects that were sent by the user */
public ObjectIdSubclassMap<ObjectId> getNewObjectIds() { public ObjectIdSubclassMap<ObjectId> getNewObjectIds() {
if (newObjectIds != null) if (newObjectIds != null)
@ -782,6 +799,25 @@ public abstract class PackParser {
System.arraycopy(buf, c, srcHash, 0, 20); System.arraycopy(buf, c, srcHash, 0, 20);
use(20); use(20);
// The input stream should be at EOF at this point. We do not support
// yielding back any remaining buffered data after the pack footer, so
// protocols that embed a pack stream are required to either end their
// stream with the pack, or embed the pack with a framing system like
// the SideBandInputStream does.
if (bAvail != 0)
throw new CorruptObjectException(MessageFormat.format(
JGitText.get().expectedEOFReceived,
"\\x" + Integer.toHexString(buf[bOffset] & 0xff)));
if (isCheckEofAfterPackFooter()) {
int eof = in.read();
if (0 <= eof)
throw new CorruptObjectException(MessageFormat.format(
JGitText.get().expectedEOFReceived,
"\\x" + Integer.toHexString(eof)));
}
if (!Arrays.equals(actHash, srcHash)) if (!Arrays.equals(actHash, srcHash))
throw new CorruptObjectException( throw new CorruptObjectException(
JGitText.get().corruptObjectPackfileChecksumIncorrect); JGitText.get().corruptObjectPackfileChecksumIncorrect);

1
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java

@ -825,6 +825,7 @@ public class ReceivePack {
parser.setAllowThin(true); parser.setAllowThin(true);
parser.setNeedNewObjectIds(checkReferencedIsReachable); parser.setNeedNewObjectIds(checkReferencedIsReachable);
parser.setNeedBaseObjectIds(checkReferencedIsReachable); parser.setNeedBaseObjectIds(checkReferencedIsReachable);
parser.setCheckEofAfterPackFooter(!biDirectionalPipe);
parser.setObjectChecking(isCheckReceivedObjects()); parser.setObjectChecking(isCheckReceivedObjects());
parser.setLockMessage(lockMsg); parser.setLockMessage(lockMsg);
packLock = parser.parse(receiving, resolving); packLock = parser.parse(receiving, resolving);

11
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

@ -55,6 +55,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.jgit.JGitText; import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
@ -757,6 +758,16 @@ public class UploadPack {
final boolean sideband = options.contains(OPTION_SIDE_BAND) final boolean sideband = options.contains(OPTION_SIDE_BAND)
|| options.contains(OPTION_SIDE_BAND_64K); || options.contains(OPTION_SIDE_BAND_64K);
if (!biDirectionalPipe) {
// Ensure the request was fully consumed. Any remaining input must
// be a protocol error. If we aren't at EOF the implementation is broken.
int eof = rawIn.read();
if (0 <= eof)
throw new CorruptObjectException(MessageFormat.format(
JGitText.get().expectedEOFReceived,
"\\x" + Integer.toHexString(eof)));
}
ProgressMonitor pm = NullProgressMonitor.INSTANCE; ProgressMonitor pm = NullProgressMonitor.INSTANCE;
OutputStream packOut = rawOut; OutputStream packOut = rawOut;
SideBandOutputStream msgOut = null; SideBandOutputStream msgOut = null;

Loading…
Cancel
Save