Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
        }