1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.reftree;
12
13 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
14 import static org.eclipse.jgit.lib.Constants.encode;
15 import static org.eclipse.jgit.lib.FileMode.TYPE_GITLINK;
16 import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK;
17 import static org.eclipse.jgit.lib.Ref.Storage.NETWORK;
18 import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
19 import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
20
21 import java.io.IOException;
22
23 import org.eclipse.jgit.annotations.Nullable;
24 import org.eclipse.jgit.dircache.DirCacheEntry;
25 import org.eclipse.jgit.errors.MissingObjectException;
26 import org.eclipse.jgit.internal.JGitText;
27 import org.eclipse.jgit.lib.ObjectId;
28 import org.eclipse.jgit.lib.ObjectIdRef;
29 import org.eclipse.jgit.lib.ObjectInserter;
30 import org.eclipse.jgit.lib.Ref;
31 import org.eclipse.jgit.lib.SymbolicRef;
32 import org.eclipse.jgit.revwalk.RevObject;
33 import org.eclipse.jgit.revwalk.RevTag;
34 import org.eclipse.jgit.revwalk.RevWalk;
35 import org.eclipse.jgit.transport.ReceiveCommand;
36 import org.eclipse.jgit.transport.ReceiveCommand.Result;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class Command {
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public static void abort(Iterable<Command> commands, @Nullable String why) {
71 if (why == null || why.isEmpty()) {
72 why = JGitText.get().transactionAborted;
73 }
74 for (Command c : commands) {
75 if (c.getResult() == NOT_ATTEMPTED) {
76 c.setResult(REJECTED_OTHER_REASON, why);
77 why = JGitText.get().transactionAborted;
78 }
79 }
80 }
81
82 private final Ref oldRef;
83 private final Ref newRef;
84 private final ReceiveCommand cmd;
85 private Result result;
86
87
88
89
90
91
92
93
94
95
96
97
98 public Command(@Nullable Ref/../../../../org/eclipse/jgit/lib/Ref.html#Ref">Ref oldRef, @Nullable Ref newRef) {
99 this.oldRef = oldRef;
100 this.newRef = newRef;
101 this.cmd = null;
102 this.result = NOT_ATTEMPTED;
103
104 if (oldRef == null && newRef == null) {
105 throw new IllegalArgumentException();
106 }
107 if (newRef != null && !newRef.isPeeled() && !newRef.isSymbolic()) {
108 throw new IllegalArgumentException();
109 }
110 if (oldRef != null && newRef != null
111 && !oldRef.getName().equals(newRef.getName())) {
112 throw new IllegalArgumentException();
113 }
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public Command(RevWalk rw, ReceiveCommand cmd)
129 throws MissingObjectException, IOException {
130 this.oldRef = toRef(rw, cmd.getOldId(), cmd.getOldSymref(),
131 cmd.getRefName(), false);
132 this.newRef = toRef(rw, cmd.getNewId(), cmd.getNewSymref(),
133 cmd.getRefName(), true);
134 this.cmd = cmd;
135 }
136
137 static Ref toRef(RevWalk rw, ObjectId id, @Nullable String target,
138 String name, boolean mustExist)
139 throws MissingObjectException, IOException {
140 if (target != null) {
141 return new SymbolicRef(name,
142 new ObjectIdRef.Unpeeled(NETWORK, target, id));
143 } else if (ObjectId.zeroId().equals(id)) {
144 return null;
145 }
146
147 try {
148 RevObject o = rw.parseAny(id);
149 if (o instanceof RevTag) {
150 RevObject p = rw.peel(o);
151 return new ObjectIdRef.PeeledTag(NETWORK, name, id, p.copy());
152 }
153 return new ObjectIdRef.PeeledNonTag(NETWORK, name, id);
154 } catch (MissingObjectException e) {
155 if (mustExist) {
156 throw e;
157 }
158 return new ObjectIdRef.Unpeeled(NETWORK, name, id);
159 }
160 }
161
162
163
164
165
166
167 public String getRefName() {
168 if (cmd != null) {
169 return cmd.getRefName();
170 } else if (newRef != null) {
171 return newRef.getName();
172 }
173 return oldRef.getName();
174 }
175
176
177
178
179
180
181
182 public void setResult(Result result) {
183 setResult(result, null);
184 }
185
186
187
188
189
190
191
192
193
194 public void setResult(Result result, @Nullable String why) {
195 if (cmd != null) {
196 cmd.setResult(result, why);
197 } else {
198 this.result = result;
199 }
200 }
201
202
203
204
205
206
207 public Result getResult() {
208 return cmd != null ? cmd.getResult() : result;
209 }
210
211
212
213
214
215
216 @Nullable
217 public String getMessage() {
218 return cmd != null ? cmd.getMessage() : null;
219 }
220
221
222
223
224
225
226 @Nullable
227 public Ref getOldRef() {
228 return oldRef;
229 }
230
231
232
233
234
235
236 @Nullable
237 public Ref getNewRef() {
238 return newRef;
239 }
240
241
242 @Override
243 public String toString() {
244 StringBuilder s = new StringBuilder();
245 append(s, oldRef, "CREATE");
246 s.append(' ');
247 append(s, newRef, "DELETE");
248 s.append(' ').append(getRefName());
249 s.append(' ').append(getResult());
250 if (getMessage() != null) {
251 s.append(' ').append(getMessage());
252 }
253 return s.toString();
254 }
255
256 private static void append(StringBuilder s, Ref r, String nullName) {
257 if (r == null) {
258 s.append(nullName);
259 } else if (r.isSymbolic()) {
260 s.append(r.getTarget().getName());
261 } else {
262 ObjectId id = r.getObjectId();
263 if (id != null) {
264 s.append(id.name());
265 }
266 }
267 }
268
269
270
271
272
273
274
275
276
277 boolean checkRef(@Nullable DirCacheEntry entry) {
278 if (entry != null && entry.getRawMode() == 0) {
279 entry = null;
280 }
281 return check(entry, oldRef) || check(entry, newRef);
282 }
283
284 private static boolean check(@Nullable DirCacheEntry cur,
285 @Nullable Ref exp) {
286 if (cur == null) {
287
288 return exp == null;
289 } else if (exp == null) {
290
291 return false;
292 }
293
294 if (exp.isSymbolic()) {
295 String dst = exp.getTarget().getName();
296 return cur.getRawMode() == TYPE_SYMLINK
297 && cur.getObjectId().equals(symref(dst));
298 }
299
300 return cur.getRawMode() == TYPE_GITLINK
301 && cur.getObjectId().equals(exp.getObjectId());
302 }
303
304 static ObjectId symref(String s) {
305 @SuppressWarnings("resource")
306 ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
307 return fmt.idFor(OBJ_BLOB, encode(s));
308 }
309 }