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(RefUpdate="../../../../org/eclipse/jgit/lib/RefUpdate.html#RefUpdate">RefUpdate src, 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 /** 90 * Get identity of the user making the change in the reflog. 91 * 92 * @return identity of the user making the change in the reflog. 93 */ 94 public PersonIdent getRefLogIdent() { 95 return destination.getRefLogIdent(); 96 } 97 98 /** 99 * Set the identity of the user appearing in the reflog. 100 * <p> 101 * The timestamp portion of the identity is ignored. A new identity with the 102 * current timestamp will be created automatically when the rename occurs 103 * and the log record is written. 104 * 105 * @param pi 106 * identity of the user. If null the identity will be 107 * automatically determined based on the repository 108 * configuration. 109 */ 110 public void setRefLogIdent(PersonIdent pi) { 111 destination.setRefLogIdent(pi); 112 } 113 114 /** 115 * Get the message to include in the reflog. 116 * 117 * @return message the caller wants to include in the reflog; null if the 118 * rename should not be logged. 119 */ 120 public String getRefLogMessage() { 121 return destination.getRefLogMessage(); 122 } 123 124 /** 125 * Set the message to include in the reflog. 126 * 127 * @param msg 128 * the message to describe this change. 129 */ 130 public void setRefLogMessage(String msg) { 131 if (msg == null) 132 disableRefLog(); 133 else 134 destination.setRefLogMessage(msg, false); 135 } 136 137 /** 138 * Don't record this rename in the ref's associated reflog. 139 */ 140 public void disableRefLog() { 141 destination.setRefLogMessage("", false); //$NON-NLS-1$ 142 } 143 144 /** 145 * Get result of rename operation 146 * 147 * @return result of rename operation 148 */ 149 public Result getResult() { 150 return result; 151 } 152 153 /** 154 * Rename 155 * 156 * @return the result of the new ref update 157 * @throws java.io.IOException 158 */ 159 public Result rename() throws IOException { 160 try { 161 result = doRename(); 162 return result; 163 } catch (IOException err) { 164 result = Result.IO_FAILURE; 165 throw err; 166 } 167 } 168 169 /** 170 * Do the actual rename 171 * 172 * @return the result of the rename operation. 173 * @throws java.io.IOException 174 */ 175 protected abstract Result doRename() throws IOException; 176 177 /** 178 * Whether the {@code Constants#HEAD} reference needs to be linked to the 179 * new destination name. 180 * 181 * @return true if the {@code Constants#HEAD} reference needs to be linked 182 * to the new destination name. 183 * @throws java.io.IOException 184 * the current value of {@code HEAD} cannot be read. 185 */ 186 protected boolean needToUpdateHEAD() throws IOException { 187 Ref head = source.getRefDatabase().exactRef(Constants.HEAD); 188 if (head != null && head.isSymbolic()) { 189 head = head.getTarget(); 190 return head.getName().equals(source.getName()); 191 } 192 return false; 193 } 194 }