View Javadoc
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 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().getRef(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 }