/// <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();
            }
        }
Exemple #2
0
 /// <summary>Get the status of this update.</summary>
 /// <remarks>Get the status of this update.</remarks>
 /// <returns>the status of the update.</returns>
 public virtual RefUpdate.Result GetResult()
 {
     return(update.GetResult());
 }