1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.api;
45
46 import java.io.IOException;
47 import java.text.MessageFormat;
48 import java.util.Arrays;
49
50 import org.eclipse.jgit.api.errors.DetachedHeadException;
51 import org.eclipse.jgit.api.errors.GitAPIException;
52 import org.eclipse.jgit.api.errors.InvalidRefNameException;
53 import org.eclipse.jgit.api.errors.JGitInternalException;
54 import org.eclipse.jgit.api.errors.NoHeadException;
55 import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
56 import org.eclipse.jgit.api.errors.RefNotFoundException;
57 import org.eclipse.jgit.internal.JGitText;
58 import org.eclipse.jgit.lib.ConfigConstants;
59 import org.eclipse.jgit.lib.Constants;
60 import org.eclipse.jgit.lib.ObjectId;
61 import org.eclipse.jgit.lib.Ref;
62 import org.eclipse.jgit.lib.RefRename;
63 import org.eclipse.jgit.lib.RefUpdate.Result;
64 import org.eclipse.jgit.lib.Repository;
65 import org.eclipse.jgit.lib.StoredConfig;
66
67
68
69
70
71
72
73
74 public class RenameBranchCommand extends GitCommand<Ref> {
75 private String oldName;
76
77 private String newName;
78
79
80
81
82
83
84
85
86
87 protected RenameBranchCommand(Repository repo) {
88 super(repo);
89 }
90
91
92 @Override
93 public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameException,
94 RefAlreadyExistsException, DetachedHeadException {
95 checkCallable();
96
97 if (newName == null) {
98 throw new InvalidRefNameException(MessageFormat.format(JGitText
99 .get().branchNameInvalid, "<null>"));
100 }
101 try {
102 String fullOldName;
103 String fullNewName;
104 if (oldName != null) {
105
106
107
108
109
110
111
112 Ref ref = repo.exactRef(oldName);
113 if (ref == null) {
114 ref = repo.exactRef(Constants.R_HEADS + oldName);
115 Ref ref2 = repo.exactRef(Constants.R_REMOTES + oldName);
116 if (ref != null && ref2 != null) {
117 throw new RefNotFoundException(MessageFormat.format(
118 JGitText.get().renameBranchFailedAmbiguous,
119 oldName, ref.getName(), ref2.getName()));
120 } else if (ref == null) {
121 if (ref2 != null) {
122 ref = ref2;
123 } else {
124 throw new RefNotFoundException(MessageFormat.format(
125 JGitText.get().refNotResolved, oldName));
126 }
127 }
128 }
129 fullOldName = ref.getName();
130 } else {
131 fullOldName = repo.getFullBranch();
132 if (fullOldName == null) {
133 throw new NoHeadException(
134 JGitText.get().invalidRepositoryStateNoHead);
135 }
136 if (ObjectId.isId(fullOldName))
137 throw new DetachedHeadException();
138 }
139
140 if (fullOldName.startsWith(Constants.R_REMOTES)) {
141 fullNewName = Constants.R_REMOTES + newName;
142 } else if (fullOldName.startsWith(Constants.R_HEADS)) {
143 fullNewName = Constants.R_HEADS + newName;
144 } else {
145 throw new RefNotFoundException(MessageFormat.format(
146 JGitText.get().renameBranchFailedNotABranch,
147 fullOldName));
148 }
149
150 if (!Repository.isValidRefName(fullNewName)) {
151 throw new InvalidRefNameException(MessageFormat.format(JGitText
152 .get().branchNameInvalid, fullNewName));
153 }
154 if (repo.exactRef(fullNewName) != null) {
155 throw new RefAlreadyExistsException(MessageFormat
156 .format(JGitText.get().refAlreadyExists1, fullNewName));
157 }
158 RefRename rename = repo.renameRef(fullOldName, fullNewName);
159 Result renameResult = rename.rename();
160
161 setCallable(false);
162
163 if (Result.RENAMED != renameResult) {
164 throw new JGitInternalException(MessageFormat.format(JGitText
165 .get().renameBranchUnexpectedResult, renameResult
166 .name()));
167 }
168 if (fullNewName.startsWith(Constants.R_HEADS)) {
169 String shortOldName = fullOldName.substring(Constants.R_HEADS
170 .length());
171 final StoredConfig repoConfig = repo.getConfig();
172
173 for (String name : repoConfig.getNames(
174 ConfigConstants.CONFIG_BRANCH_SECTION, shortOldName)) {
175 String[] values = repoConfig.getStringList(
176 ConfigConstants.CONFIG_BRANCH_SECTION,
177 shortOldName, name);
178 if (values.length == 0) {
179 continue;
180 }
181
182
183 String[] existing = repoConfig.getStringList(
184 ConfigConstants.CONFIG_BRANCH_SECTION, newName,
185 name);
186 if (existing.length > 0) {
187 String[] newValues = new String[values.length
188 + existing.length];
189 System.arraycopy(existing, 0, newValues, 0,
190 existing.length);
191 System.arraycopy(values, 0, newValues, existing.length,
192 values.length);
193 values = newValues;
194 }
195
196 repoConfig.setStringList(
197 ConfigConstants.CONFIG_BRANCH_SECTION, newName,
198 name, Arrays.asList(values));
199 }
200 repoConfig.unsetSection(ConfigConstants.CONFIG_BRANCH_SECTION,
201 shortOldName);
202 repoConfig.save();
203 }
204
205 Ref resultRef = repo.exactRef(fullNewName);
206 if (resultRef == null) {
207 throw new JGitInternalException(
208 JGitText.get().renameBranchFailedUnknownReason);
209 }
210 return resultRef;
211 } catch (IOException ioe) {
212 throw new JGitInternalException(ioe.getMessage(), ioe);
213 }
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 public RenameBranchCommand setNewName(String newName) {
230 checkCallable();
231 this.newName = newName;
232 return this;
233 }
234
235
236
237
238
239
240
241
242
243
244
245
246
247 public RenameBranchCommand setOldName(String oldName) {
248 checkCallable();
249 this.oldName = oldName;
250 return this;
251 }
252 }