예제 #1
0
        /// <exception cref="System.IO.IOException"></exception>
        private void UpdateStashRef(ObjectId commitId, PersonIdent refLogIdent, string refLogMessage
                                    )
        {
            Ref       currentRef = repo.GetRef(@ref);
            RefUpdate refUpdate  = repo.UpdateRef(@ref);

            refUpdate.SetNewObjectId(commitId);
            refUpdate.SetRefLogIdent(refLogIdent);
            refUpdate.SetRefLogMessage(refLogMessage, false);
            if (currentRef != null)
            {
                refUpdate.SetExpectedOldObjectId(currentRef.GetObjectId());
            }
            else
            {
                refUpdate.SetExpectedOldObjectId(ObjectId.ZeroId);
            }
            refUpdate.ForceUpdate();
        }
        /// <summary>Execute this command during a receive-pack session.</summary>
        /// <remarks>
        /// Execute this command during a receive-pack session.
        /// <p>
        /// Sets the status of the command as a side effect.
        /// </remarks>
        /// <param name="rp">receive-pack session.</param>
        /// <since>2.0</since>
        public virtual void Execute(BaseReceivePack rp)
        {
            try
            {
                RefUpdate ru = rp.GetRepository().UpdateRef(GetRefName());
                ru.SetRefLogIdent(rp.GetRefLogIdent());
                switch (GetType())
                {
                case ReceiveCommand.Type.DELETE:
                {
                    if (!ObjectId.ZeroId.Equals(GetOldId()))
                    {
                        // We can only do a CAS style delete if the client
                        // didn't bork its delete request by sending the
                        // wrong zero id rather than the advertised one.
                        //
                        ru.SetExpectedOldObjectId(GetOldId());
                    }
                    ru.SetForceUpdate(true);
                    SetResult(ru.Delete(rp.GetRevWalk()));
                    break;
                }

                case ReceiveCommand.Type.CREATE:
                case ReceiveCommand.Type.UPDATE:
                case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
                {
                    ru.SetForceUpdate(rp.IsAllowNonFastForwards());
                    ru.SetExpectedOldObjectId(GetOldId());
                    ru.SetNewObjectId(GetNewId());
                    ru.SetRefLogMessage("push", true);
                    SetResult(ru.Update(rp.GetRevWalk()));
                    break;
                }
                }
            }
            catch (IOException err)
            {
                Reject(err);
            }
        }
        /// <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();
            }
        }