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