|
|
@@ -48,7 +48,6 @@ import java.io.File; |
|
|
|
import java.io.FileNotFoundException; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.security.MessageDigest; |
|
|
|
import java.text.MessageFormat; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
@@ -63,7 +62,6 @@ import org.eclipse.jgit.JGitText; |
|
|
|
import org.eclipse.jgit.errors.CompoundException; |
|
|
|
import org.eclipse.jgit.errors.CorruptObjectException; |
|
|
|
import org.eclipse.jgit.errors.MissingObjectException; |
|
|
|
import org.eclipse.jgit.errors.ObjectWritingException; |
|
|
|
import org.eclipse.jgit.errors.TransportException; |
|
|
|
import org.eclipse.jgit.lib.AnyObjectId; |
|
|
|
import org.eclipse.jgit.lib.Constants; |
|
|
@@ -72,6 +70,7 @@ import org.eclipse.jgit.lib.MutableObjectId; |
|
|
|
import org.eclipse.jgit.lib.ObjectChecker; |
|
|
|
import org.eclipse.jgit.lib.ObjectDirectory; |
|
|
|
import org.eclipse.jgit.lib.ObjectId; |
|
|
|
import org.eclipse.jgit.lib.ObjectInserter; |
|
|
|
import org.eclipse.jgit.lib.PackIndex; |
|
|
|
import org.eclipse.jgit.lib.PackLock; |
|
|
|
import org.eclipse.jgit.lib.ProgressMonitor; |
|
|
@@ -166,8 +165,6 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
|
|
|
|
private final MutableObjectId idBuffer = new MutableObjectId(); |
|
|
|
|
|
|
|
private final MessageDigest objectDigest = Constants.newMessageDigest(); |
|
|
|
|
|
|
|
/** |
|
|
|
* Errors received while trying to obtain an object. |
|
|
|
* <p> |
|
|
@@ -181,10 +178,14 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
|
|
|
|
private final List<PackLock> packLocks; |
|
|
|
|
|
|
|
/** Inserter to write objects onto {@link #local}. */ |
|
|
|
private final ObjectInserter inserter; |
|
|
|
|
|
|
|
WalkFetchConnection(final WalkTransport t, final WalkRemoteObjectDatabase w) { |
|
|
|
Transport wt = (Transport)t; |
|
|
|
local = wt.local; |
|
|
|
objCheck = wt.isCheckFetchedObjects() ? new ObjectChecker() : null; |
|
|
|
inserter = local.newObjectInserter(); |
|
|
|
|
|
|
|
remotes = new ArrayList<WalkRemoteObjectDatabase>(); |
|
|
|
remotes.add(w); |
|
|
@@ -241,6 +242,7 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
|
|
|
|
@Override |
|
|
|
public void close() { |
|
|
|
inserter.release(); |
|
|
|
for (final RemotePack p : unfetchedPacks) { |
|
|
|
if (p.tmpIdx != null) |
|
|
|
p.tmpIdx.delete(); |
|
|
@@ -559,8 +561,7 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
throws TransportException { |
|
|
|
try { |
|
|
|
final byte[] compressed = remote.open(looseName).toArray(); |
|
|
|
verifyLooseObject(id, compressed); |
|
|
|
saveLooseObject(id, compressed); |
|
|
|
verifyAndInsertLooseObject(id, compressed); |
|
|
|
return true; |
|
|
|
} catch (FileNotFoundException e) { |
|
|
|
// Not available in a loose format from this alternate? |
|
|
@@ -573,8 +574,8 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void verifyLooseObject(final AnyObjectId id, final byte[] compressed) |
|
|
|
throws IOException { |
|
|
|
private void verifyAndInsertLooseObject(final AnyObjectId id, |
|
|
|
final byte[] compressed) throws IOException { |
|
|
|
final UnpackedObjectLoader uol; |
|
|
|
try { |
|
|
|
uol = new UnpackedObjectLoader(compressed); |
|
|
@@ -596,62 +597,23 @@ class WalkFetchConnection extends BaseFetchConnection { |
|
|
|
throw e; |
|
|
|
} |
|
|
|
|
|
|
|
objectDigest.reset(); |
|
|
|
objectDigest.update(Constants.encodedTypeString(uol.getType())); |
|
|
|
objectDigest.update((byte) ' '); |
|
|
|
objectDigest.update(Constants.encodeASCII(uol.getSize())); |
|
|
|
objectDigest.update((byte) 0); |
|
|
|
objectDigest.update(uol.getCachedBytes()); |
|
|
|
idBuffer.fromRaw(objectDigest.digest(), 0); |
|
|
|
|
|
|
|
if (!AnyObjectId.equals(id, idBuffer)) { |
|
|
|
throw new TransportException(MessageFormat.format(JGitText.get().incorrectHashFor |
|
|
|
, id.name(), idBuffer.name(), Constants.typeString(uol.getType()), compressed.length)); |
|
|
|
} |
|
|
|
final int type = uol.getType(); |
|
|
|
final byte[] raw = uol.getCachedBytes(); |
|
|
|
if (objCheck != null) { |
|
|
|
try { |
|
|
|
objCheck.check(uol.getType(), uol.getCachedBytes()); |
|
|
|
objCheck.check(type, raw); |
|
|
|
} catch (CorruptObjectException e) { |
|
|
|
throw new TransportException(MessageFormat.format(JGitText.get().transportExceptionInvalid |
|
|
|
, Constants.typeString(uol.getType()), id.name(), e.getMessage())); |
|
|
|
, Constants.typeString(type), id.name(), e.getMessage())); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void saveLooseObject(final AnyObjectId id, final byte[] compressed) |
|
|
|
throws IOException, ObjectWritingException { |
|
|
|
final File tmp; |
|
|
|
|
|
|
|
tmp = File.createTempFile("noz", null, local.getObjectsDirectory()); |
|
|
|
try { |
|
|
|
final FileOutputStream out = new FileOutputStream(tmp); |
|
|
|
try { |
|
|
|
out.write(compressed); |
|
|
|
} finally { |
|
|
|
out.close(); |
|
|
|
} |
|
|
|
tmp.setReadOnly(); |
|
|
|
} catch (IOException e) { |
|
|
|
tmp.delete(); |
|
|
|
throw e; |
|
|
|
ObjectId act = inserter.insert(type, raw); |
|
|
|
if (!AnyObjectId.equals(id, act)) { |
|
|
|
throw new TransportException(MessageFormat.format(JGitText.get().incorrectHashFor |
|
|
|
, id.name(), act.name(), Constants.typeString(type), compressed.length)); |
|
|
|
} |
|
|
|
|
|
|
|
final File o = local.toFile(id); |
|
|
|
if (tmp.renameTo(o)) |
|
|
|
return; |
|
|
|
|
|
|
|
// Maybe the directory doesn't exist yet as the object |
|
|
|
// directories are always lazily created. Note that we |
|
|
|
// try the rename first as the directory likely does exist. |
|
|
|
// |
|
|
|
o.getParentFile().mkdir(); |
|
|
|
if (tmp.renameTo(o)) |
|
|
|
return; |
|
|
|
|
|
|
|
tmp.delete(); |
|
|
|
if (local.hasObject(id)) |
|
|
|
return; |
|
|
|
throw new ObjectWritingException(MessageFormat.format(JGitText.get().unableToStore, id.name())); |
|
|
|
inserter.flush(); |
|
|
|
} |
|
|
|
|
|
|
|
private Collection<WalkRemoteObjectDatabase> expandOneAlternate( |