/*
* Copyright (C) 2009, Robin Rosenberg
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Git Development Community nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.spearce.jgit.lib;
import java.io.IOException;
import org.spearce.jgit.lib.RefUpdate.Result;
/**
* A RefUpdate combination for renaming a ref
*/
public class RefRename {
private RefUpdate newToUpdate;
private RefUpdate oldFromDelete;
private Result renameResult = Result.NOT_ATTEMPTED;
RefRename(final RefUpdate toUpdate, final RefUpdate fromUpdate) {
newToUpdate = toUpdate;
oldFromDelete = fromUpdate;
}
/**
* @return result of rename operation
*/
public Result getResult() {
return renameResult;
}
/**
* @return the result of the new ref update
* @throws IOException
*/
public Result rename() throws IOException {
Ref oldRef = oldFromDelete.db.readRef(Constants.HEAD);
boolean renameHEADtoo = oldRef != null
&& oldRef.getName().equals(oldFromDelete.getName());
Repository db = oldFromDelete.getRepository();
try {
RefLogWriter.renameTo(db, oldFromDelete,
newToUpdate);
newToUpdate.setRefLogMessage(null, false);
String tmpRefName = "RENAMED-REF.." + Thread.currentThread().getId();
RefUpdate tmpUpdateRef = db.updateRef(tmpRefName);
if (renameHEADtoo) {
try {
oldFromDelete.db.link(Constants.HEAD, tmpRefName);
} catch (IOException e) {
RefLogWriter.renameTo(db,
newToUpdate, oldFromDelete);
return renameResult = Result.LOCK_FAILURE;
}
}
tmpUpdateRef.setNewObjectId(oldFromDelete.getOldObjectId());
tmpUpdateRef.setForceUpdate(true);
Result update = tmpUpdateRef.update();
if (update != Result.FORCED && update != Result.NEW && update != Result.NO_CHANGE) {
RefLogWriter.renameTo(db,
newToUpdate, oldFromDelete);
if (renameHEADtoo) {
oldFromDelete.db.link(Constants.HEAD, oldFromDelete.getName());
}
return renameResult = update;
}
oldFromDelete.setExpectedOldObjectId(oldFromDelete.getOldObjectId());
oldFromDelete.setForceUpdate(true);
Result delete = oldFromDelete.delete();
if (delete != Result.FORCED) {
if (db.getRef(
oldFromDelete.getName()) != null) {
RefLogWriter.renameTo(db,
newToUpdate, oldFromDelete);
if (renameHEADtoo) {
oldFromDelete.db.link(Constants.HEAD, oldFromDelete
.getName());
}
}
return renameResult = delete;
}
newToUpdate.setNewObjectId(tmpUpdateRef.getNewObjectId());
Result updateResult = newToUpdate.update();
if (updateResult != Result.NEW) {
RefLogWriter.renameTo(db, newToUpdate, oldFromDelete);
if (renameHEADtoo) {
oldFromDelete.db.link(Constants.HEAD, oldFromDelete.getName());
}
oldFromDelete.setExpectedOldObjectId(null);
oldFromDelete.setNewObjectId(oldFromDelete.getOldObjectId());
oldFromDelete.setForceUpdate(true);
oldFromDelete.setRefLogMessage(null, false);
Result undelete = oldFromDelete.update();
if (undelete != Result.NEW && undelete != Result.LOCK_FAILURE)
return renameResult = Result.IO_FAILURE;
return renameResult = Result.LOCK_FAILURE;
}
if (renameHEADtoo) {
oldFromDelete.db.link(Constants.HEAD, newToUpdate.getName());
} else {
db.fireRefsMaybeChanged();
}
RefLogWriter.append(this, newToUpdate.getName(), "Branch: renamed "
+ db.shortenRefName(oldFromDelete.getName()) + " to "
+ db.shortenRefName(newToUpdate.getName()));
if (renameHEADtoo)
RefLogWriter.append(this, Constants.HEAD, "Branch: renamed "
+ db.shortenRefName(oldFromDelete.getName()) + " to "
+ db.shortenRefName(newToUpdate.getName()));
return renameResult = Result.RENAMED;
} catch (RuntimeException e) {
throw e;
}
}
ObjectId getObjectId() {
return oldFromDelete.getOldObjectId();
}
Repository getRepository() {
return oldFromDelete.getRepository();
}
PersonIdent getRefLogIdent() {
return newToUpdate.getRefLogIdent();
}
String getToName() {
return newToUpdate.getName();
}
}