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> and others 6 * 7 * This program and the accompanying materials are made available under the 8 * terms of the Eclipse Distribution License v. 1.0 which is available at 9 * https://www.eclipse.org/org/documents/edl-v10.php. 10 * 11 * SPDX-License-Identifier: BSD-3-Clause 12 */ 13 14 package org.eclipse.jgit.lib; 15 16 import java.io.IOException; 17 18 import org.eclipse.jgit.lib.RefUpdate.Result; 19 20 /** 21 * A RefUpdate combination for renaming a reference. 22 * <p> 23 * If the source reference is currently pointed to by {@code HEAD}, then the 24 * HEAD symbolic reference is updated to point to the new destination. 25 */ 26 public abstract class RefRename { 27 /** Update operation to read and delete the source reference. */ 28 protected final RefUpdate source; 29 30 /** Update operation to create/overwrite the destination reference. */ 31 protected final RefUpdate destination; 32 33 private Result result = Result.NOT_ATTEMPTED; 34 35 /** 36 * Initialize a new rename operation. 37 * 38 * @param src 39 * operation to read and delete the source. 40 * @param dst 41 * operation to create (or overwrite) the destination. 42 */ 43 protected RefRename(RefUpdate src, RefUpdate dst) { 44 source = src; 45 destination = dst; 46 47 String cmd = ""; //$NON-NLS-1$ 48 if (source.getName().startsWith(Constants.R_HEADS) 49 && destination.getName().startsWith(Constants.R_HEADS)) 50 cmd = "Branch: "; //$NON-NLS-1$ 51 setRefLogMessage(cmd + "renamed " //$NON-NLS-1$ 52 + Repository.shortenRefName(source.getName()) + " to " //$NON-NLS-1$ 53 + Repository.shortenRefName(destination.getName())); 54 } 55 56 /** 57 * Get identity of the user making the change in the reflog. 58 * 59 * @return identity of the user making the change in the reflog. 60 */ 61 public PersonIdent getRefLogIdent() { 62 return destination.getRefLogIdent(); 63 } 64 65 /** 66 * Set the identity of the user appearing in the reflog. 67 * <p> 68 * The timestamp portion of the identity is ignored. A new identity with the 69 * current timestamp will be created automatically when the rename occurs 70 * and the log record is written. 71 * 72 * @param pi 73 * identity of the user. If null the identity will be 74 * automatically determined based on the repository 75 * configuration. 76 */ 77 public void setRefLogIdent(PersonIdent pi) { 78 destination.setRefLogIdent(pi); 79 } 80 81 /** 82 * Get the message to include in the reflog. 83 * 84 * @return message the caller wants to include in the reflog; null if the 85 * rename should not be logged. 86 */ 87 public String getRefLogMessage() { 88 return destination.getRefLogMessage(); 89 } 90 91 /** 92 * Set the message to include in the reflog. 93 * 94 * @param msg 95 * the message to describe this change. 96 */ 97 public void setRefLogMessage(String msg) { 98 if (msg == null) 99 disableRefLog(); 100 else 101 destination.setRefLogMessage(msg, false); 102 } 103 104 /** 105 * Don't record this rename in the ref's associated reflog. 106 */ 107 public void disableRefLog() { 108 destination.setRefLogMessage("", false); //$NON-NLS-1$ 109 } 110 111 /** 112 * Get result of rename operation 113 * 114 * @return result of rename operation 115 */ 116 public Result getResult() { 117 return result; 118 } 119 120 /** 121 * Rename 122 * 123 * @return the result of the new ref update 124 * @throws java.io.IOException 125 */ 126 public Result rename() throws IOException { 127 try { 128 result = doRename(); 129 return result; 130 } catch (IOException err) { 131 result = Result.IO_FAILURE; 132 throw err; 133 } 134 } 135 136 /** 137 * Do the actual rename 138 * 139 * @return the result of the rename operation. 140 * @throws java.io.IOException 141 */ 142 protected abstract Result doRename() throws IOException; 143 144 /** 145 * Whether the {@code Constants#HEAD} reference needs to be linked to the 146 * new destination name. 147 * 148 * @return true if the {@code Constants#HEAD} reference needs to be linked 149 * to the new destination name. 150 * @throws java.io.IOException 151 * the current value of {@code HEAD} cannot be read. 152 */ 153 protected boolean needToUpdateHEAD() throws IOException { 154 Ref head = source.getRefDatabase().exactRef(Constants.HEAD); 155 if (head != null && head.isSymbolic()) { 156 head = head.getTarget(); 157 return head.getName().equals(source.getName()); 158 } 159 return false; 160 } 161 }