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> 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="../../../../org/eclipse/jgit/lib/RefUpdate.html#RefUpdate">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 }