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 }