internal virtual void Stored(RefDirectoryUpdate update, FileSnapshot snapshot)
        {
            ObjectId target = update.GetNewObjectId().Copy();
            Ref      leaf   = update.GetRef().GetLeaf();

            PutLooseRef(new RefDirectory.LooseUnpeeled(snapshot, leaf.GetName(), target));
        }
        /// <exception cref="System.IO.IOException"></exception>
        public override RefRename NewRename(string fromName, string toName)
        {
            RefDirectoryUpdate from = ((RefDirectoryUpdate)NewUpdate(fromName, false));
            RefDirectoryUpdate to   = ((RefDirectoryUpdate)NewUpdate(toName, false));

            return(new RefDirectoryRename(from, to));
        }
        /// <exception cref="System.IO.IOException"></exception>
        public override RefUpdate NewUpdate(string name, bool detach)
        {
            bool          detachingSymbolicRef = false;
            RefList <Ref> packed = GetPackedRefs();
            Ref           @ref   = ReadRef(name, packed);

            if (@ref != null)
            {
                @ref = Resolve(@ref, 0, null, null, packed);
            }
            if (@ref == null)
            {
                @ref = new ObjectIdRef.Unpeeled(RefStorage.NEW, name, null);
            }
            else
            {
                detachingSymbolicRef = detach && @ref.IsSymbolic();
                if (detachingSymbolicRef)
                {
                    @ref = new ObjectIdRef.Unpeeled(RefStorage.LOOSE, name, @ref.GetObjectId());
                }
            }
            RefDirectoryUpdate refDirUpdate = new RefDirectoryUpdate(this, @ref);

            if (detachingSymbolicRef)
            {
                refDirUpdate.SetDetachingSymbolicRef();
            }
            return(refDirUpdate);
        }
Example #4
0
        /// <exception cref="System.IO.IOException"></exception>
        private void WriteReflog(Repository db, ObjectId newId, string msg, string refName
                                 )
        {
            RefDirectory       refs   = (RefDirectory)db.RefDatabase;
            RefDirectoryUpdate update = ((RefDirectoryUpdate)refs.NewUpdate(refName, true));

            update.SetNewObjectId(newId);
            refs.Log(update, msg, true);
        }
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual void Delete(RefDirectoryUpdate update)
        {
            Ref    dst  = update.GetRef().GetLeaf();
            string name = dst.GetName();

            // Write the packed-refs file using an atomic update. We might
            // wind up reading it twice, before and after the lock, to ensure
            // we don't miss an edit made externally.
            RefDirectory.PackedRefList packed = GetPackedRefs();
            if (packed.Contains(name))
            {
                LockFile lck = new LockFile(packedRefsFile, update.GetRepository().FileSystem);
                if (!lck.Lock())
                {
                    throw new LockFailedException(packedRefsFile);
                }
                try
                {
                    RefDirectory.PackedRefList cur = ReadPackedRefs();
                    int idx = cur.Find(name);
                    if (0 <= idx)
                    {
                        CommitPackedRefs(lck, cur.Remove(idx), packed);
                    }
                }
                finally
                {
                    lck.Unlock();
                }
            }
            RefList <RefDirectory.LooseRef> curLoose;
            RefList <RefDirectory.LooseRef> newLoose;

            do
            {
                curLoose = looseRefs.Get();
                int idx = curLoose.Find(name);
                if (idx < 0)
                {
                    break;
                }
                newLoose = curLoose.Remove(idx);
            }while (!looseRefs.CompareAndSet(curLoose, newLoose));
            int levels = LevelsIn(name) - 2;

            Delete(logWriter.LogFor(name), levels);
            if (dst.GetStorage().IsLoose())
            {
                update.Unlock();
                Delete(FileFor(name), levels);
            }
            modCnt.IncrementAndGet();
            FireRefsChanged();
        }
 internal RefDirectoryRename(RefDirectoryUpdate src, RefDirectoryUpdate dst) : base
         (src, dst)
 {
     refdb = ((RefDirectory)src.GetRefDatabase());
 }
        /// <exception cref="System.IO.IOException"></exception>
        protected internal override RefUpdate.Result DoRename()
        {
            if (source.GetRef().IsSymbolic())
            {
                return(RefUpdate.Result.IO_FAILURE);
            }
            // not supported
            objId      = source.GetOldObjectId();
            updateHEAD = NeedToUpdateHEAD();
            tmp        = refdb.NewTemporaryUpdate();
            RevWalk rw = new RevWalk(refdb.GetRepository());

            try
            {
                // First backup the source so its never unreachable.
                tmp.SetNewObjectId(objId);
                tmp.SetForceUpdate(true);
                tmp.DisableRefLog();
                switch (tmp.Update(rw))
                {
                case RefUpdate.Result.NEW:
                case RefUpdate.Result.FORCED:
                case RefUpdate.Result.NO_CHANGE:
                {
                    break;
                }

                default:
                {
                    return(tmp.GetResult());

                    break;
                }
                }
                // Save the source's log under the temporary name, we must do
                // this before we delete the source, otherwise we lose the log.
                if (!RenameLog(source, tmp))
                {
                    return(RefUpdate.Result.IO_FAILURE);
                }
                // If HEAD has to be updated, link it now to destination.
                // We have to link before we delete, otherwise the delete
                // fails because its the current branch.
                RefUpdate dst = destination;
                if (updateHEAD)
                {
                    if (!LinkHEAD(destination))
                    {
                        RenameLog(tmp, source);
                        return(RefUpdate.Result.LOCK_FAILURE);
                    }
                    // Replace the update operation so HEAD will log the rename.
                    dst = ((RefDirectoryUpdate)refdb.NewUpdate(Constants.HEAD, false));
                    dst.SetRefLogIdent(destination.GetRefLogIdent());
                    dst.SetRefLogMessage(destination.GetRefLogMessage(), false);
                }
                // Delete the source name so its path is free for replacement.
                source.SetExpectedOldObjectId(objId);
                source.SetForceUpdate(true);
                source.DisableRefLog();
                if (source.Delete(rw) != RefUpdate.Result.FORCED)
                {
                    RenameLog(tmp, source);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(source.GetResult());
                }
                // Move the log to the destination.
                if (!RenameLog(tmp, destination))
                {
                    RenameLog(tmp, source);
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(RefUpdate.Result.IO_FAILURE);
                }
                // Create the destination, logging the rename during the creation.
                dst.SetExpectedOldObjectId(ObjectId.ZeroId);
                dst.SetNewObjectId(objId);
                if (dst.Update(rw) != RefUpdate.Result.NEW)
                {
                    // If we didn't create the destination we have to undo
                    // our work. Put the log back and restore source.
                    if (RenameLog(destination, tmp))
                    {
                        RenameLog(tmp, source);
                    }
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(dst.GetResult());
                }
                return(RefUpdate.Result.RENAMED);
            }
            finally
            {
                // Always try to free the temporary name.
                try
                {
                    refdb.Delete(tmp);
                }
                catch (IOException)
                {
                    FileUtils.Delete(refdb.FileFor(tmp.GetName()));
                }
                rw.Release();
            }
        }
Example #8
0
        /// <exception cref="System.IO.IOException"></exception>
        protected internal override RefUpdate.Result DoRename()
        {
            if (source.GetRef().IsSymbolic())
            {
                return RefUpdate.Result.IO_FAILURE;
            }
            // not supported
            objId = source.GetOldObjectId();
            updateHEAD = NeedToUpdateHEAD();
            tmp = refdb.NewTemporaryUpdate();
            RevWalk rw = new RevWalk(refdb.GetRepository());
            try
            {
                // First backup the source so its never unreachable.
                tmp.SetNewObjectId(objId);
                tmp.SetForceUpdate(true);
                tmp.DisableRefLog();
                switch (tmp.Update(rw))
                {
                    case RefUpdate.Result.NEW:
                    case RefUpdate.Result.FORCED:
                    case RefUpdate.Result.NO_CHANGE:
                    {
                        break;
                    }

                    default:
                    {
                        return tmp.GetResult();
                        break;
                    }
                }
                // Save the source's log under the temporary name, we must do
                // this before we delete the source, otherwise we lose the log.
                if (!RenameLog(source, tmp))
                {
                    return RefUpdate.Result.IO_FAILURE;
                }
                // If HEAD has to be updated, link it now to destination.
                // We have to link before we delete, otherwise the delete
                // fails because its the current branch.
                RefUpdate dst = destination;
                if (updateHEAD)
                {
                    if (!LinkHEAD(destination))
                    {
                        RenameLog(tmp, source);
                        return RefUpdate.Result.LOCK_FAILURE;
                    }
                    // Replace the update operation so HEAD will log the rename.
                    dst = ((RefDirectoryUpdate)refdb.NewUpdate(Constants.HEAD, false));
                    dst.SetRefLogIdent(destination.GetRefLogIdent());
                    dst.SetRefLogMessage(destination.GetRefLogMessage(), false);
                }
                // Delete the source name so its path is free for replacement.
                source.SetExpectedOldObjectId(objId);
                source.SetForceUpdate(true);
                source.DisableRefLog();
                if (source.Delete(rw) != RefUpdate.Result.FORCED)
                {
                    RenameLog(tmp, source);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return source.GetResult();
                }
                // Move the log to the destination.
                if (!RenameLog(tmp, destination))
                {
                    RenameLog(tmp, source);
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return RefUpdate.Result.IO_FAILURE;
                }
                // Create the destination, logging the rename during the creation.
                dst.SetExpectedOldObjectId(ObjectId.ZeroId);
                dst.SetNewObjectId(objId);
                if (dst.Update(rw) != RefUpdate.Result.NEW)
                {
                    // If we didn't create the destination we have to undo
                    // our work. Put the log back and restore source.
                    if (RenameLog(destination, tmp))
                    {
                        RenameLog(tmp, source);
                    }
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return dst.GetResult();
                }
                return RefUpdate.Result.RENAMED;
            }
            finally
            {
                // Always try to free the temporary name.
                try
                {
                    refdb.Delete(tmp);
                }
                catch (IOException)
                {
                    FileUtils.Delete(refdb.FileFor(tmp.GetName()));
                }
                rw.Release();
            }
        }
Example #9
0
 internal RefDirectoryRename(RefDirectoryUpdate src, RefDirectoryUpdate dst)
     : base(src, dst)
 {
     refdb = ((RefDirectory)src.GetRefDatabase());
 }
 internal virtual void StoredSymbolicRef(RefDirectoryUpdate u, FileSnapshot snapshot
                                         , string target)
 {
     PutLooseRef(NewSymbolicRef(snapshot, u.GetRef().GetName(), target));
     FireRefsChanged();
 }