private void sendpack(final List<RemoteRefUpdate> updates,
final ProgressMonitor monitor) throws TransportException {
String pathPack = null;
String pathIdx = null;
final PackWriter writer = new PackWriter(transport.getPackConfig(),
local.newObjectReader());
try {
final Set<ObjectId> need = new HashSet<ObjectId>();
final Set<ObjectId> have = new HashSet<ObjectId>();
for (final RemoteRefUpdate r : updates)
need.add(r.getNewObjectId());
for (final Ref r : getRefs()) {
have.add(r.getObjectId());
if (r.getPeeledObjectId() != null)
have.add(r.getPeeledObjectId());
}
writer.preparePack(monitor, need, have);
// We don't have to continue further if the pack will
// be an empty pack, as the remote has all objects it
// needs to complete this change.
//
if (writer.getObjectCount() == 0)
return;
packNames = new LinkedHashMap<String, String>();
for (final String n : dest.getPackNames())
packNames.put(n, n);
final String base = "pack-" + writer.computeName().name();
final String packName = base + ".pack";
pathPack = "pack/" + packName;
pathIdx = "pack/" + base + ".idx";
if (packNames.remove(packName) != null) {
// The remote already contains this pack. We should
// remove the index before overwriting to prevent bad
// offsets from appearing to clients.
//
dest.writeInfoPacks(packNames.keySet());
dest.deleteFile(pathIdx);
}
// Write the pack file, then the index, as readers look the
// other direction (index, then pack file).
//
final String wt = "Put " + base.substring(0, 12);
OutputStream os = dest.writeFile(pathPack, monitor, wt + "..pack");
try {
os = new SafeBufferedOutputStream(os);
writer.writePack(monitor, monitor, os);
} finally {
os.close();
}
os = dest.writeFile(pathIdx, monitor, wt + "..idx");
try {
os = new SafeBufferedOutputStream(os);
writer.writeIndex(os);
} finally {
os.close();
}
// Record the pack at the start of the pack info list. This
// way clients are likely to consult the newest pack first,
// and discover the most recent objects there.
//
final ArrayList<String> infoPacks = new ArrayList<String>();
infoPacks.add(packName);
infoPacks.addAll(packNames.keySet());
dest.writeInfoPacks(infoPacks);
} catch (IOException err) {
safeDelete(pathIdx);
safeDelete(pathPack);
throw new TransportException(uri, JGitText.get().cannotStoreObjects, err);
} finally {
writer.release();
}
}