1 /* 2 * Copyright (C) 2009-2010, Google Inc. 3 * Copyright (C) 2009, Robin Rosenberg 4 * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com> 5 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> 6 * and other copyright owners as documented in the project's IP log. 7 * 8 * This program and the accompanying materials are made available 9 * under the terms of the Eclipse Distribution License v1.0 which 10 * accompanies this distribution, is reproduced below, and is 11 * available at http://www.eclipse.org/org/documents/edl-v10.php 12 * 13 * All rights reserved. 14 * 15 * Redistribution and use in source and binary forms, with or 16 * without modification, are permitted provided that the following 17 * conditions are met: 18 * 19 * - Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 22 * - Redistributions in binary form must reproduce the above 23 * copyright notice, this list of conditions and the following 24 * disclaimer in the documentation and/or other materials provided 25 * with the distribution. 26 * 27 * - Neither the name of the Eclipse Foundation, Inc. nor the 28 * names of its contributors may be used to endorse or promote 29 * products derived from this software without specific prior 30 * written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 33 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 34 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 37 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 39 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 40 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 41 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 42 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 44 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 */ 46 47 package org.eclipse.jgit.lib; 48 49 import java.io.IOException; 50 51 import org.eclipse.jgit.lib.RefUpdate.Result; 52 53 /** 54 * A RefUpdate combination for renaming a reference. 55 * <p> 56 * If the source reference is currently pointed to by {@code HEAD}, then the 57 * HEAD symbolic reference is updated to point to the new destination. 58 */ 59 public abstract class RefRename { 60 /** Update operation to read and delete the source reference. */ 61 protected final RefUpdate source; 62 63 /** Update operation to create/overwrite the destination reference. */ 64 protected final RefUpdate destination; 65 66 private Result result = Result.NOT_ATTEMPTED; 67 68 /** 69 * Initialize a new rename operation. 70 * 71 * @param src 72 * operation to read and delete the source. 73 * @param dst 74 * operation to create (or overwrite) the destination. 75 */ 76 protected RefRename(final RefUpdate src, final RefUpdate dst) { 77 source = src; 78 destination = dst; 79 80 String cmd = ""; //$NON-NLS-1$ 81 if (source.getName().startsWith(Constants.R_HEADS) 82 && destination.getName().startsWith(Constants.R_HEADS)) 83 cmd = "Branch: "; //$NON-NLS-1$ 84 setRefLogMessage(cmd + "renamed " //$NON-NLS-1$ 85 + Repository.shortenRefName(source.getName()) + " to " //$NON-NLS-1$ 86 + Repository.shortenRefName(destination.getName())); 87 } 88 89 /** @return identity of the user making the change in the reflog. */ 90 public PersonIdent getRefLogIdent() { 91 return destination.getRefLogIdent(); 92 } 93 94 /** 95 * Set the identity of the user appearing in the reflog. 96 * <p> 97 * The timestamp portion of the identity is ignored. A new identity with the 98 * current timestamp will be created automatically when the rename occurs 99 * and the log record is written. 100 * 101 * @param pi 102 * identity of the user. If null the identity will be 103 * automatically determined based on the repository 104 * configuration. 105 */ 106 public void setRefLogIdent(final PersonIdent pi) { 107 destination.setRefLogIdent(pi); 108 } 109 110 /** 111 * Get the message to include in the reflog. 112 * 113 * @return message the caller wants to include in the reflog; null if the 114 * rename should not be logged. 115 */ 116 public String getRefLogMessage() { 117 return destination.getRefLogMessage(); 118 } 119 120 /** 121 * Set the message to include in the reflog. 122 * 123 * @param msg 124 * the message to describe this change. 125 */ 126 public void setRefLogMessage(final String msg) { 127 if (msg == null) 128 disableRefLog(); 129 else 130 destination.setRefLogMessage(msg, false); 131 } 132 133 /** Don't record this rename in the ref's associated reflog. */ 134 public void disableRefLog() { 135 destination.setRefLogMessage("", false); //$NON-NLS-1$ 136 } 137 138 /** 139 * @return result of rename operation 140 */ 141 public Result getResult() { 142 return result; 143 } 144 145 /** 146 * @return the result of the new ref update 147 * @throws IOException 148 */ 149 public Result rename() throws IOException { 150 try { 151 result = doRename(); 152 return result; 153 } catch (IOException err) { 154 result = Result.IO_FAILURE; 155 throw err; 156 } 157 } 158 159 /** 160 * @return the result of the rename operation. 161 * @throws IOException 162 */ 163 protected abstract Result doRename() throws IOException; 164 165 /** 166 * @return true if the {@code Constants#HEAD} reference needs to be linked 167 * to the new destination name. 168 * @throws IOException 169 * the current value of {@code HEAD} cannot be read. 170 */ 171 protected boolean needToUpdateHEAD() throws IOException { 172 Ref head = source.getRefDatabase().getRef(Constants.HEAD); 173 if (head != null && head.isSymbolic()) { 174 head = head.getTarget(); 175 return head.getName().equals(source.getName()); 176 } 177 return false; 178 } 179 }