/// <summary> /// Rename the pack to it's final name and location and open it. /// <para/> /// If the call completes successfully the repository this IndexPack instance /// was created with will have the objects in the pack available for reading /// and use, without needing to scan for packs. /// </summary> /// <param name="lockMessage"> /// message to place in the pack-*.keep file. If null, no lock /// will be created, and this method returns null. /// </param> /// <returns>the pack lock object, if lockMessage is not null.</returns> public PackLock renameAndOpenPack(string lockMessage) { if (!_keepEmpty && _entryCount == 0) { CleanupTemporaryFiles(); return(null); } MessageDigest d = Constants.newMessageDigest(); var oeBytes = new byte[Constants.OBJECT_ID_LENGTH]; for (int i = 0; i < _entryCount; i++) { PackedObjectInfo oe = _entries[i]; oe.copyRawTo(oeBytes, 0); d.Update(oeBytes); } string name = ObjectId.FromRaw(d.Digest()).Name; var packDir = PathUtil.CombineDirectoryPath(_repo.ObjectsDirectory, "pack"); var finalPack = PathUtil.CombineFilePath(packDir, "pack-" + GetPackFileName(name)); var finalIdx = PathUtil.CombineFilePath(packDir, "pack-" + GetIndexFileName(name)); var keep = new PackLock(finalPack); if (!packDir.Exists && !packDir.Mkdirs() && !packDir.Exists) { // The objects/pack directory isn't present, and we are unable // to create it. There is no way to move this pack in. // CleanupTemporaryFiles(); throw new IOException("Cannot Create " + packDir); } if (finalPack.Exists) { // If the pack is already present we should never replace it. // CleanupTemporaryFiles(); return(null); } if (lockMessage != null) { // If we have a reason to create a keep file for this pack, do // so, or fail fast and don't put the pack in place. // try { if (!keep.Lock(lockMessage)) { throw new IOException("Cannot lock pack in " + finalPack); } } catch (IOException) { CleanupTemporaryFiles(); throw; } } if (!_dstPack.RenameTo(finalPack.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); throw new IOException("Cannot move pack to " + finalPack); } if (!_dstIdx.RenameTo(finalIdx.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); finalPack.DeleteFile(); //if (finalPack.Exists) // TODO: [caytchen] finalPack.deleteOnExit(); throw new IOException("Cannot move index to " + finalIdx); } try { _repo.OpenPack(finalPack, finalIdx); } catch (IOException) { keep.Unlock(); finalPack.DeleteFile(); finalIdx.DeleteFile(); throw; } return(lockMessage != null ? keep : null); }
public PackLock renameAndOpenPack(string lockMessage) { if (!_keepEmpty && _entryCount == 0) { CleanupTemporaryFiles(); return(null); } MessageDigest d = Constants.newMessageDigest(); var oeBytes = new byte[Constants.OBJECT_ID_LENGTH]; for (int i = 0; i < _entryCount; i++) { PackedObjectInfo oe = _entries[i]; oe.copyRawTo(oeBytes, 0); d.Update(oeBytes); } string name = ObjectId.FromRaw(d.Digest()).Name; var packDir = new DirectoryInfo(Path.Combine(_repo.ObjectsDirectory.ToString(), "pack")); var finalPack = new FileInfo(Path.Combine(packDir.ToString(), "pack-" + GetPackFileName(name))); var finalIdx = new FileInfo(Path.Combine(packDir.ToString(), "pack-" + GetIndexFileName(name))); var keep = new PackLock(finalPack); if (!packDir.Exists && !packDir.Mkdirs() && !packDir.Exists) { CleanupTemporaryFiles(); throw new IOException("Cannot Create " + packDir); } if (finalPack.Exists) { CleanupTemporaryFiles(); return(null); } if (lockMessage != null) { try { if (!keep.Lock(lockMessage)) { throw new IOException("Cannot lock pack in " + finalPack); } } catch (IOException) { CleanupTemporaryFiles(); throw; } } if (!_dstPack.RenameTo(finalPack.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); throw new IOException("Cannot move pack to " + finalPack); } if (!_dstIdx.RenameTo(finalIdx.ToString())) { CleanupTemporaryFiles(); keep.Unlock(); finalPack.Delete(); //if (finalPack.Exists) // TODO: [caytchen] finalPack.deleteOnExit(); throw new IOException("Cannot move index to " + finalIdx); } try { _repo.OpenPack(finalPack, finalIdx); } catch (IOException) { keep.Unlock(); finalPack.Delete(); finalIdx.Delete(); throw; } return(lockMessage != null ? keep : null); }