1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.api;
11
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.URISyntaxException;
15 import java.text.MessageFormat;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.eclipse.jgit.api.errors.GitAPIException;
25 import org.eclipse.jgit.api.errors.InvalidRemoteException;
26 import org.eclipse.jgit.api.errors.JGitInternalException;
27 import org.eclipse.jgit.errors.NotSupportedException;
28 import org.eclipse.jgit.errors.TooLargeObjectInPackException;
29 import org.eclipse.jgit.errors.TooLargePackException;
30 import org.eclipse.jgit.errors.TransportException;
31 import org.eclipse.jgit.internal.JGitText;
32 import org.eclipse.jgit.lib.Constants;
33 import org.eclipse.jgit.lib.NullProgressMonitor;
34 import org.eclipse.jgit.lib.ProgressMonitor;
35 import org.eclipse.jgit.lib.Ref;
36 import org.eclipse.jgit.lib.Repository;
37 import org.eclipse.jgit.transport.PushResult;
38 import org.eclipse.jgit.transport.RefLeaseSpec;
39 import org.eclipse.jgit.transport.RefSpec;
40 import org.eclipse.jgit.transport.RemoteConfig;
41 import org.eclipse.jgit.transport.RemoteRefUpdate;
42 import org.eclipse.jgit.transport.Transport;
43
44
45
46
47
48
49
50
51
52 public class PushCommand extends
53 TransportCommand<PushCommand, Iterable<PushResult>> {
54
55 private String remote = Constants.DEFAULT_REMOTE_NAME;
56
57 private final List<RefSpec> refSpecs;
58
59 private final Map<String, RefLeaseSpec> refLeaseSpecs;
60
61 private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
62
63 private String receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK;
64
65 private boolean dryRun;
66 private boolean atomic;
67 private boolean force;
68 private boolean thin = Transport.DEFAULT_PUSH_THIN;
69
70 private OutputStream out;
71
72 private List<String> pushOptions;
73
74
75
76
77
78
79
80
81
82 protected PushCommand(Repository repo) {
83 super(repo);
84 refSpecs = new ArrayList<>(3);
85 refLeaseSpecs = new HashMap<>();
86 }
87
88
89
90
91
92
93
94
95
96 @Override
97 public Iterable<PushResult> call() throws GitAPIException,
98 InvalidRemoteException,
99 org.eclipse.jgit.api.errors.TransportException {
100 checkCallable();
101
102 ArrayList<PushResult> pushResults = new ArrayList<>(3);
103
104 try {
105 if (refSpecs.isEmpty()) {
106 RemoteConfig config = new RemoteConfig(repo.getConfig(),
107 getRemote());
108 refSpecs.addAll(config.getPushRefSpecs());
109 }
110 if (refSpecs.isEmpty()) {
111 Ref head = repo.exactRef(Constants.HEAD);
112 if (head != null && head.isSymbolic())
113 refSpecs.add(new RefSpec(head.getLeaf().getName()));
114 }
115
116 if (force) {
117 for (int i = 0; i < refSpecs.size(); i++)
118 refSpecs.set(i, refSpecs.get(i).setForceUpdate(true));
119 }
120
121 final List<Transport> transports;
122 transports = Transport.openAll(repo, remote, Transport.Operation.PUSH);
123 for (@SuppressWarnings("resource")
124 final Transport transport : transports) {
125 transport.setPushThin(thin);
126 transport.setPushAtomic(atomic);
127 if (receivePack != null)
128 transport.setOptionReceivePack(receivePack);
129 transport.setDryRun(dryRun);
130 transport.setPushOptions(pushOptions);
131 configure(transport);
132
133 final Collection<RemoteRefUpdate> toPush = transport
134 .findRemoteRefUpdatesFor(refSpecs, refLeaseSpecs);
135
136 try {
137 PushResult result = transport.push(monitor, toPush, out);
138 pushResults.add(result);
139
140 } catch (TooLargePackException e) {
141 throw new org.eclipse.jgit.api.errors.TooLargePackException(
142 e.getMessage(), e);
143 } catch (TooLargeObjectInPackException e) {
144 throw new org.eclipse.jgit.api.errors.TooLargeObjectInPackException(
145 e.getMessage(), e);
146 } catch (TransportException e) {
147 throw new org.eclipse.jgit.api.errors.TransportException(
148 e.getMessage(), e);
149 } finally {
150 transport.close();
151 }
152 }
153
154 } catch (URISyntaxException e) {
155 throw new InvalidRemoteException(
156 MessageFormat.format(JGitText.get().invalidRemote, remote),
157 e);
158 } catch (TransportException e) {
159 throw new org.eclipse.jgit.api.errors.TransportException(
160 e.getMessage(), e);
161 } catch (NotSupportedException e) {
162 throw new JGitInternalException(
163 JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
164 e);
165 } catch (IOException e) {
166 throw new JGitInternalException(
167 JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
168 e);
169 }
170
171 return pushResults;
172 }
173
174
175
176
177
178
179
180
181
182
183
184 public PushCommand setRemote(String remote) {
185 checkCallable();
186 this.remote = remote;
187 return this;
188 }
189
190
191
192
193
194
195 public String getRemote() {
196 return remote;
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210 public PushCommand setReceivePack(String receivePack) {
211 checkCallable();
212 this.receivePack = receivePack;
213 return this;
214 }
215
216
217
218
219
220
221 public String getReceivePack() {
222 return receivePack;
223 }
224
225
226
227
228
229
230 public int getTimeout() {
231 return timeout;
232 }
233
234
235
236
237
238
239 public ProgressMonitor getProgressMonitor() {
240 return monitor;
241 }
242
243
244
245
246
247
248
249
250
251
252 public PushCommand setProgressMonitor(ProgressMonitor monitor) {
253 checkCallable();
254 if (monitor == null) {
255 monitor = NullProgressMonitor.INSTANCE;
256 }
257 this.monitor = monitor;
258 return this;
259 }
260
261
262
263
264
265
266
267 public List<RefLeaseSpec> getRefLeaseSpecs() {
268 return new ArrayList<>(refLeaseSpecs.values());
269 }
270
271
272
273
274
275
276
277
278
279
280 public PushCommand setRefLeaseSpecs(RefLeaseSpec... specs) {
281 return setRefLeaseSpecs(Arrays.asList(specs));
282 }
283
284
285
286
287
288
289
290
291
292
293 public PushCommand setRefLeaseSpecs(List<RefLeaseSpec> specs) {
294 checkCallable();
295 this.refLeaseSpecs.clear();
296 for (RefLeaseSpec spec : specs) {
297 refLeaseSpecs.put(spec.getRef(), spec);
298 }
299 return this;
300 }
301
302
303
304
305
306
307 public List<RefSpec> getRefSpecs() {
308 return refSpecs;
309 }
310
311
312
313
314
315
316
317 public PushCommand setRefSpecs(RefSpec... specs) {
318 checkCallable();
319 this.refSpecs.clear();
320 Collections.addAll(refSpecs, specs);
321 return this;
322 }
323
324
325
326
327
328
329
330
331 public PushCommand setRefSpecs(List<RefSpec> specs) {
332 checkCallable();
333 this.refSpecs.clear();
334 this.refSpecs.addAll(specs);
335 return this;
336 }
337
338
339
340
341
342
343 public PushCommand setPushAll() {
344 refSpecs.add(Transport.REFSPEC_PUSH_ALL);
345 return this;
346 }
347
348
349
350
351
352
353 public PushCommand setPushTags() {
354 refSpecs.add(Transport.REFSPEC_TAGS);
355 return this;
356 }
357
358
359
360
361
362
363
364
365 public PushCommand add(Ref ref) {
366 refSpecs.add(new RefSpec(ref.getLeaf().getName()));
367 return this;
368 }
369
370
371
372
373
374
375
376
377
378
379 public PushCommand add(String nameOrSpec) {
380 if (0 <= nameOrSpec.indexOf(':')) {
381 refSpecs.add(new RefSpec(nameOrSpec));
382 } else {
383 Ref src;
384 try {
385 src = repo.findRef(nameOrSpec);
386 } catch (IOException e) {
387 throw new JGitInternalException(
388 JGitText.get().exceptionCaughtDuringExecutionOfPushCommand,
389 e);
390 }
391 if (src != null)
392 add(src);
393 }
394 return this;
395 }
396
397
398
399
400
401
402 public boolean isDryRun() {
403 return dryRun;
404 }
405
406
407
408
409
410
411
412 public PushCommand setDryRun(boolean dryRun) {
413 checkCallable();
414 this.dryRun = dryRun;
415 return this;
416 }
417
418
419
420
421
422
423 public boolean isThin() {
424 return thin;
425 }
426
427
428
429
430
431
432
433
434
435
436 public PushCommand setThin(boolean thin) {
437 checkCallable();
438 this.thin = thin;
439 return this;
440 }
441
442
443
444
445
446
447
448
449 public boolean isAtomic() {
450 return atomic;
451 }
452
453
454
455
456
457
458
459
460
461
462
463 public PushCommand setAtomic(boolean atomic) {
464 checkCallable();
465 this.atomic = atomic;
466 return this;
467 }
468
469
470
471
472
473
474 public boolean isForce() {
475 return force;
476 }
477
478
479
480
481
482
483
484
485 public PushCommand setForce(boolean force) {
486 checkCallable();
487 this.force = force;
488 return this;
489 }
490
491
492
493
494
495
496
497
498
499 public PushCommand setOutputStream(OutputStream out) {
500 this.out = out;
501 return this;
502 }
503
504
505
506
507
508
509
510 public List<String> getPushOptions() {
511 return pushOptions;
512 }
513
514
515
516
517
518
519
520
521
522 public PushCommand setPushOptions(List<String> pushOptions) {
523 this.pushOptions = pushOptions;
524 return this;
525 }
526 }