return -1;
return Integer.signum(o1.hashCode() - o2.hashCode());
}
});
PackWriter pw = new PackWriter((pconfig == null) ? new PackConfig(repo) : pconfig, repo.newObjectReader());
try {
// prepare the PackWriter
pw.setDeltaBaseAsOffset(true);
pw.setReuseDeltaCommits(false);
if (tagTargets != null)
pw.setTagTargets(tagTargets);
if (excludeObjects != null)
for (ObjectIdSet idx : excludeObjects)
pw.excludeObjects(idx);
pw.preparePack(pm, want, have);
if (pw.getObjectCount() == 0)
return null;
// create temporary files
String id = pw.computeName().getName();
File packdir = new File(repo.getObjectsDirectory(), "pack"); //$NON-NLS-1$
tmpPack = File.createTempFile("gc_", ".pack_tmp", packdir); //$NON-NLS-1$ //$NON-NLS-2$
final String tmpBase = tmpPack.getName()
.substring(0, tmpPack.getName().lastIndexOf('.'));
File tmpIdx = new File(packdir, tmpBase + ".idx_tmp"); //$NON-NLS-1$
tmpExts.put(INDEX, tmpIdx);
if (!tmpIdx.createNewFile())
throw new IOException(MessageFormat.format(
JGitText.get().cannotCreateIndexfile, tmpIdx.getPath()));
// write the packfile
FileOutputStream fos = new FileOutputStream(tmpPack);
FileChannel channel = fos.getChannel();
OutputStream channelStream = Channels.newOutputStream(channel);
try {
pw.writePack(pm, pm, channelStream);
} finally {
channel.force(true);
channelStream.close();
fos.close();
}
// write the packindex
fos = new FileOutputStream(tmpIdx);
FileChannel idxChannel = fos.getChannel();
OutputStream idxStream = Channels.newOutputStream(idxChannel);
try {
pw.writeIndex(idxStream);
} finally {
idxChannel.force(true);
idxStream.close();
fos.close();
}
if (pw.prepareBitmapIndex(pm)) {
File tmpBitmapIdx = new File(packdir, tmpBase + ".bitmap_tmp"); //$NON-NLS-1$
tmpExts.put(BITMAP_INDEX, tmpBitmapIdx);
if (!tmpBitmapIdx.createNewFile())
throw new IOException(MessageFormat.format(
JGitText.get().cannotCreateIndexfile,
tmpBitmapIdx.getPath()));
fos = new FileOutputStream(tmpBitmapIdx);
idxChannel = fos.getChannel();
idxStream = Channels.newOutputStream(idxChannel);
try {
pw.writeBitmapIndex(idxStream);
} finally {
idxChannel.force(true);
idxStream.close();
fos.close();
}
}
// rename the temporary files to real files
File realPack = nameFor(id, ".pack"); //$NON-NLS-1$
// if the packfile already exists (because we are rewriting a
// packfile for the same set of objects maybe with different
// PackConfig) then make sure we get rid of all handles on the file.
// Windows will not allow for rename otherwise.
if (realPack.exists())
for (PackFile p : repo.getObjectDatabase().getPacks())
if (realPack.getPath().equals(p.getPackFile().getPath())) {
p.close();
break;
}
tmpPack.setReadOnly();
boolean delete = true;
try {
FileUtils.rename(tmpPack, realPack);
delete = false;
for (Map.Entry<PackExt, File> tmpEntry : tmpExts.entrySet()) {
File tmpExt = tmpEntry.getValue();
tmpExt.setReadOnly();
File realExt = nameFor(
id, "." + tmpEntry.getKey().getExtension()); //$NON-NLS-1$
try {
FileUtils.rename(tmpExt, realExt);
} catch (IOException e) {
File newExt = new File(realExt.getParentFile(),
realExt.getName() + ".new"); //$NON-NLS-1$
if (!tmpExt.renameTo(newExt))
newExt = tmpExt;
throw new IOException(MessageFormat.format(
JGitText.get().panicCantRenameIndexFile, newExt,
realExt));
}
}
} finally {
if (delete) {
if (tmpPack.exists())
tmpPack.delete();
for (File tmpExt : tmpExts.values()) {
if (tmpExt.exists())
tmpExt.delete();
}
}
}
return repo.getObjectDatabase().openPack(realPack);
} finally {
pw.release();
if (tmpPack != null && tmpPack.exists())
tmpPack.delete();
for (File tmpExt : tmpExts.values()) {
if (tmpExt.exists())
tmpExt.delete();