1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.api;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertNotNull;
15 import static org.junit.Assert.assertThrows;
16 import static org.junit.Assert.assertTrue;
17 import static org.junit.Assert.fail;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.PrintStream;
23 import java.net.URISyntaxException;
24 import java.nio.charset.StandardCharsets;
25 import java.util.Properties;
26
27 import org.eclipse.jgit.api.errors.DetachedHeadException;
28 import org.eclipse.jgit.api.errors.GitAPIException;
29 import org.eclipse.jgit.api.errors.InvalidRefNameException;
30 import org.eclipse.jgit.api.errors.JGitInternalException;
31 import org.eclipse.jgit.api.errors.TransportException;
32 import org.eclipse.jgit.errors.MissingObjectException;
33 import org.eclipse.jgit.errors.NoRemoteRepositoryException;
34 import org.eclipse.jgit.hooks.PrePushHook;
35 import org.eclipse.jgit.junit.JGitTestUtil;
36 import org.eclipse.jgit.junit.RepositoryTestCase;
37 import org.eclipse.jgit.lib.ObjectId;
38 import org.eclipse.jgit.lib.Ref;
39 import org.eclipse.jgit.lib.RefUpdate;
40 import org.eclipse.jgit.lib.Repository;
41 import org.eclipse.jgit.lib.StoredConfig;
42 import org.eclipse.jgit.revwalk.RevCommit;
43 import org.eclipse.jgit.transport.PushConfig.PushDefault;
44 import org.eclipse.jgit.transport.PushResult;
45 import org.eclipse.jgit.transport.RefLeaseSpec;
46 import org.eclipse.jgit.transport.RefSpec;
47 import org.eclipse.jgit.transport.RemoteConfig;
48 import org.eclipse.jgit.transport.RemoteRefUpdate;
49 import org.eclipse.jgit.transport.TrackingRefUpdate;
50 import org.eclipse.jgit.transport.URIish;
51 import org.eclipse.jgit.util.FS;
52 import org.junit.Test;
53
54 public class PushCommandTest extends RepositoryTestCase {
55
56 @Test
57 public void testPush() throws JGitInternalException, IOException,
58 GitAPIException, URISyntaxException {
59
60
61 Repository db2 = createWorkRepository();
62 addRepoToClose(db2);
63 final StoredConfig config2 = db2.getConfig();
64
65
66 config2.setString("fsck", "", "missingEmail", "ignore");
67 config2.save();
68
69
70 final StoredConfig config = db.getConfig();
71 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
72 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
73 remoteConfig.addURI(uri);
74 remoteConfig.update(config);
75 config.save();
76
77 try (Git git1 = new Git(db)) {
78
79 RevCommit commit = git1.commit().setMessage("initial commit").call();
80 Ref tagRef = git1.tag().setName("tag").call();
81
82 try {
83 db2.resolve(commit.getId().getName() + "^{commit}");
84 fail("id shouldn't exist yet");
85 } catch (MissingObjectException e) {
86
87 }
88
89 RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
90 git1.push().setRemote("test").setRefSpecs(spec)
91 .call();
92
93 assertEquals(commit.getId(),
94 db2.resolve(commit.getId().getName() + "^{commit}"));
95 assertEquals(tagRef.getObjectId(),
96 db2.resolve(tagRef.getObjectId().getName()));
97 }
98 }
99
100 @Test
101 public void testPrePushHook() throws JGitInternalException, IOException,
102 GitAPIException, URISyntaxException {
103
104
105 Repository db2 = createWorkRepository();
106
107
108 final StoredConfig config = db.getConfig();
109 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
110 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
111 remoteConfig.addURI(uri);
112 remoteConfig.update(config);
113 config.save();
114
115 File hookOutput = new File(getTemporaryDirectory(), "hookOutput");
116 writeHookFile(PrePushHook.NAME, "#!/bin/sh\necho 1:$1, 2:$2, 3:$3 >\""
117 + hookOutput.toPath() + "\"\ncat - >>\"" + hookOutput.toPath()
118 + "\"\nexit 0");
119
120 try (Git git1 = new Git(db)) {
121
122 RevCommit commit = git1.commit().setMessage("initial commit").call();
123
124 RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
125 git1.push().setRemote("test").setRefSpecs(spec).call();
126 assertEquals("1:test, 2:" + uri + ", 3:\n" + "refs/heads/master "
127 + commit.getName() + " refs/heads/x "
128 + ObjectId.zeroId().name() + "\n", read(hookOutput));
129 }
130 }
131
132 @Test
133 public void testPrePushHookRedirects() throws JGitInternalException,
134 IOException, GitAPIException, URISyntaxException {
135
136
137 Repository db2 = createWorkRepository();
138
139
140 final StoredConfig config = db.getConfig();
141 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
142 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
143 remoteConfig.addURI(uri);
144 remoteConfig.update(config);
145 config.save();
146
147 writeHookFile(PrePushHook.NAME, "#!/bin/sh\n"
148 + "echo \"1:$1, 2:$2, 3:$3\"\n"
149 + "cat - 1>&2\n"
150 + "exit 0\n");
151
152 try (Git git1 = new Git(db)) {
153
154 RevCommit commit = git1.commit().setMessage("initial commit")
155 .call();
156
157 RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
158 try (ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
159 ByteArrayOutputStream errBytes = new ByteArrayOutputStream();
160 PrintStream stdout = new PrintStream(outBytes, true,
161 StandardCharsets.UTF_8);
162 PrintStream stderr = new PrintStream(errBytes, true,
163 StandardCharsets.UTF_8)) {
164 git1.push()
165 .setRemote("test")
166 .setRefSpecs(spec)
167 .setHookOutputStream(stdout)
168 .setHookErrorStream(stderr)
169 .call();
170 String out = outBytes.toString(StandardCharsets.UTF_8);
171 String err = errBytes.toString(StandardCharsets.UTF_8);
172 assertEquals("1:test, 2:" + uri + ", 3:\n", out);
173 assertEquals("refs/heads/master " + commit.getName()
174 + " refs/heads/x " + ObjectId.zeroId().name() + '\n',
175 err);
176 }
177 }
178 }
179
180 private File writeHookFile(String name, String data)
181 throws IOException {
182 File path = new File(db.getWorkTree() + "/.git/hooks/", name);
183 JGitTestUtil.write(path, data);
184 FS.DETECTED.setExecute(path, true);
185 return path;
186 }
187
188
189 @Test
190 public void testTrackingUpdate() throws Exception {
191 Repository db2 = createBareRepository();
192
193 String remote = "origin";
194 String branch = "refs/heads/master";
195 String trackingBranch = "refs/remotes/" + remote + "/master";
196
197 try (Git git = new Git(db)) {
198 RevCommit commit1 = git.commit().setMessage("Initial commit")
199 .call();
200
201 RefUpdate branchRefUpdate = db.updateRef(branch);
202 branchRefUpdate.setNewObjectId(commit1.getId());
203 branchRefUpdate.update();
204
205 RefUpdate trackingBranchRefUpdate = db.updateRef(trackingBranch);
206 trackingBranchRefUpdate.setNewObjectId(commit1.getId());
207 trackingBranchRefUpdate.update();
208
209 final StoredConfig config = db.getConfig();
210 RemoteConfig remoteConfig = new RemoteConfig(config, remote);
211 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
212 remoteConfig.addURI(uri);
213 remoteConfig.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/"
214 + remote + "/*"));
215 remoteConfig.update(config);
216 config.save();
217
218
219 RevCommit commit2 = git.commit().setMessage("Commit to push").call();
220
221 RefSpec spec = new RefSpec(branch + ":" + branch);
222 Iterable<PushResult> resultIterable = git.push().setRemote(remote)
223 .setRefSpecs(spec).call();
224
225 PushResult result = resultIterable.iterator().next();
226 TrackingRefUpdate trackingRefUpdate = result
227 .getTrackingRefUpdate(trackingBranch);
228
229 assertNotNull(trackingRefUpdate);
230 assertEquals(trackingBranch, trackingRefUpdate.getLocalName());
231 assertEquals(branch, trackingRefUpdate.getRemoteName());
232 assertEquals(commit2.getId(), trackingRefUpdate.getNewObjectId());
233 assertEquals(commit2.getId(), db.resolve(trackingBranch));
234 assertEquals(commit2.getId(), db2.resolve(branch));
235 }
236 }
237
238
239
240
241
242
243 @Test
244 public void testPushRefUpdate() throws Exception {
245 try (Git git = new Git(db);
246 Git git2 = new Git(createBareRepository())) {
247 final StoredConfig config = git.getRepository().getConfig();
248 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
249 URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
250 .toURL());
251 remoteConfig.addURI(uri);
252 remoteConfig.addPushRefSpec(new RefSpec("+refs/heads/*:refs/heads/*"));
253 remoteConfig.update(config);
254 config.save();
255
256 writeTrashFile("f", "content of f");
257 git.add().addFilepattern("f").call();
258 RevCommit commit = git.commit().setMessage("adding f").call();
259
260 assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
261 git.push().setRemote("test").call();
262 assertEquals(commit.getId(),
263 git2.getRepository().resolve("refs/heads/master"));
264
265 git.branchCreate().setName("refs/heads/test").call();
266 git.checkout().setName("refs/heads/test").call();
267
268 for (int i = 0; i < 6; i++) {
269 writeTrashFile("f" + i, "content of f" + i);
270 git.add().addFilepattern("f" + i).call();
271 commit = git.commit().setMessage("adding f" + i).call();
272 git.push().setRemote("test").call();
273 git2.getRepository().getRefDatabase().getRefs();
274 assertEquals("failed to update on attempt " + i, commit.getId(),
275 git2.getRepository().resolve("refs/heads/test"));
276 }
277 }
278 }
279
280
281
282
283
284
285 @Test
286 public void testPushWithRefSpecFromConfig() throws Exception {
287 try (Git git = new Git(db);
288 Git git2 = new Git(createBareRepository())) {
289 final StoredConfig config = git.getRepository().getConfig();
290 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
291 URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
292 .toURL());
293 remoteConfig.addURI(uri);
294 remoteConfig.addPushRefSpec(new RefSpec("HEAD:refs/heads/newbranch"));
295 remoteConfig.update(config);
296 config.save();
297
298 writeTrashFile("f", "content of f");
299 git.add().addFilepattern("f").call();
300 RevCommit commit = git.commit().setMessage("adding f").call();
301
302 assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
303 git.push().setRemote("test").call();
304 assertEquals(commit.getId(),
305 git2.getRepository().resolve("refs/heads/newbranch"));
306 }
307 }
308
309
310
311
312
313
314 @Test
315 public void testPushWithoutPushRefSpec() throws Exception {
316 try (Git git = new Git(db);
317 Git git2 = new Git(createBareRepository())) {
318 final StoredConfig config = git.getRepository().getConfig();
319 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
320 URIish uri = new URIish(git2.getRepository().getDirectory().toURI()
321 .toURL());
322 remoteConfig.addURI(uri);
323 remoteConfig.addFetchRefSpec(new RefSpec(
324 "+refs/heads/*:refs/remotes/origin/*"));
325 remoteConfig.update(config);
326 config.save();
327
328 writeTrashFile("f", "content of f");
329 git.add().addFilepattern("f").call();
330 RevCommit commit = git.commit().setMessage("adding f").call();
331
332 git.checkout().setName("not-pushed").setCreateBranch(true).call();
333 git.checkout().setName("branchtopush").setCreateBranch(true).call();
334
335 assertEquals(null,
336 git2.getRepository().resolve("refs/heads/branchtopush"));
337 assertEquals(null, git2.getRepository()
338 .resolve("refs/heads/not-pushed"));
339 assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
340 git.push().setRemote("test").call();
341 assertEquals(commit.getId(),
342 git2.getRepository().resolve("refs/heads/branchtopush"));
343 assertEquals(null, git2.getRepository()
344 .resolve("refs/heads/not-pushed"));
345 assertEquals(null, git2.getRepository().resolve("refs/heads/master"));
346 }
347 }
348
349
350
351
352
353
354
355 @Test
356 public void testPushDefaultDetachedHead() throws Exception {
357 try (Git git = new Git(db);
358 Git git2 = new Git(createBareRepository())) {
359 final StoredConfig config = git.getRepository().getConfig();
360 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
361 URIish uri = new URIish(
362 git2.getRepository().getDirectory().toURI().toURL());
363 remoteConfig.addURI(uri);
364 remoteConfig.addFetchRefSpec(
365 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
366 remoteConfig.update(config);
367 config.save();
368
369 writeTrashFile("f", "content of f");
370 git.add().addFilepattern("f").call();
371 RevCommit commit = git.commit().setMessage("adding f").call();
372
373 git.checkout().setName("not-pushed").setCreateBranch(true).call();
374 git.checkout().setName("branchtopush").setCreateBranch(true).call();
375 git.checkout().setName(commit.getName()).call();
376 String head = git.getRepository().getFullBranch();
377 assertTrue(ObjectId.isId(head));
378 assertEquals(commit.getName(), head);
379 assertThrows(DetachedHeadException.class,
380 () -> git.push().setRemote("test").call());
381 }
382 }
383
384
385
386
387
388
389
390 @Test
391 public void testPushDefaultNothing() throws Exception {
392 try (Git git = new Git(db);
393 Git git2 = new Git(createBareRepository())) {
394 final StoredConfig config = git.getRepository().getConfig();
395 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
396 URIish uri = new URIish(
397 git2.getRepository().getDirectory().toURI().toURL());
398 remoteConfig.addURI(uri);
399 remoteConfig.addFetchRefSpec(
400 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
401 remoteConfig.update(config);
402 config.save();
403
404 writeTrashFile("f", "content of f");
405 git.add().addFilepattern("f").call();
406 git.commit().setMessage("adding f").call();
407
408 git.checkout().setName("not-pushed").setCreateBranch(true).call();
409 git.checkout().setName("branchtopush").setCreateBranch(true).call();
410
411 assertEquals(null,
412 git2.getRepository().resolve("refs/heads/branchtopush"));
413 assertEquals(null,
414 git2.getRepository().resolve("refs/heads/not-pushed"));
415 assertEquals(null,
416 git2.getRepository().resolve("refs/heads/master"));
417 assertThrows(InvalidRefNameException.class,
418 () -> git.push().setRemote("test")
419 .setPushDefault(PushDefault.NOTHING).call());
420 }
421 }
422
423
424
425
426
427
428
429 @Test
430 public void testPushDefaultMatching() throws Exception {
431 try (Git git = new Git(db);
432 Git git2 = new Git(createBareRepository())) {
433 final StoredConfig config = git.getRepository().getConfig();
434 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
435 URIish uri = new URIish(
436 git2.getRepository().getDirectory().toURI().toURL());
437 remoteConfig.addURI(uri);
438 remoteConfig.addFetchRefSpec(
439 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
440 remoteConfig.update(config);
441 config.save();
442
443 writeTrashFile("f", "content of f");
444 git.add().addFilepattern("f").call();
445 RevCommit commit = git.commit().setMessage("adding f").call();
446
447 git.checkout().setName("not-pushed").setCreateBranch(true).call();
448 git.checkout().setName("branchtopush").setCreateBranch(true).call();
449
450 assertEquals(null,
451 git2.getRepository().resolve("refs/heads/branchtopush"));
452 assertEquals(null,
453 git2.getRepository().resolve("refs/heads/not-pushed"));
454 assertEquals(null,
455 git2.getRepository().resolve("refs/heads/master"));
456
457 git.push().setRemote("test").setRefSpecs(
458 new RefSpec("refs/heads/master:refs/heads/master"),
459 new RefSpec(
460 "refs/heads/branchtopush:refs/heads/branchtopush"))
461 .call();
462 assertEquals(commit.getId(),
463 git2.getRepository().resolve("refs/heads/master"));
464 assertEquals(commit.getId(),
465 git2.getRepository().resolve("refs/heads/branchtopush"));
466 assertEquals(null,
467 git2.getRepository().resolve("refs/heads/not-pushed"));
468
469 writeTrashFile("b", "on branchtopush");
470 git.add().addFilepattern("b").call();
471 RevCommit bCommit = git.commit().setMessage("on branchtopush")
472 .call();
473 git.checkout().setName("master").call();
474 writeTrashFile("m", "on master");
475 git.add().addFilepattern("m").call();
476 RevCommit mCommit = git.commit().setMessage("on master").call();
477
478 Iterable<PushResult> result = git.push().setRemote("test")
479 .setPushDefault(PushDefault.MATCHING)
480 .call();
481 int n = 0;
482 for (PushResult r : result) {
483 n++;
484 assertEquals(1, n);
485 assertEquals(2, r.getRemoteUpdates().size());
486 for (RemoteRefUpdate update : r.getRemoteUpdates()) {
487 assertFalse(update.isMatching());
488 assertTrue(update.getSrcRef()
489 .equals("refs/heads/branchtopush")
490 || update.getSrcRef().equals("refs/heads/master"));
491 assertEquals(RemoteRefUpdate.Status.OK, update.getStatus());
492 }
493 }
494 assertEquals(bCommit.getId(),
495 git2.getRepository().resolve("refs/heads/branchtopush"));
496 assertEquals(null,
497 git2.getRepository().resolve("refs/heads/not-pushed"));
498 assertEquals(mCommit.getId(),
499 git2.getRepository().resolve("refs/heads/master"));
500 assertEquals(bCommit.getId(), git.getRepository()
501 .resolve("refs/remotes/origin/branchtopush"));
502 assertEquals(null, git.getRepository()
503 .resolve("refs/remotes/origin/not-pushed"));
504 assertEquals(mCommit.getId(),
505 git.getRepository().resolve("refs/remotes/origin/master"));
506 }
507 }
508
509
510
511
512
513
514
515 @Test
516 public void testPushDefaultUpstream() throws Exception {
517 try (Git git = new Git(db);
518 Git git2 = new Git(createBareRepository())) {
519 StoredConfig config = git.getRepository().getConfig();
520 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
521 URIish uri = new URIish(
522 git2.getRepository().getDirectory().toURI().toURL());
523 remoteConfig.addURI(uri);
524 remoteConfig.addFetchRefSpec(
525 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
526 remoteConfig.update(config);
527 config.save();
528
529 writeTrashFile("f", "content of f");
530 git.add().addFilepattern("f").call();
531 RevCommit commit = git.commit().setMessage("adding f").call();
532
533 git.checkout().setName("not-pushed").setCreateBranch(true).call();
534 git.checkout().setName("branchtopush").setCreateBranch(true).call();
535
536 config = git.getRepository().getConfig();
537 config.setString("branch", "branchtopush", "remote", "test");
538 config.setString("branch", "branchtopush", "merge",
539 "refs/heads/upstreambranch");
540 config.save();
541
542 assertEquals(null,
543 git2.getRepository().resolve("refs/heads/branchtopush"));
544 assertEquals(null,
545 git2.getRepository().resolve("refs/heads/upstreambranch"));
546 assertEquals(null,
547 git2.getRepository().resolve("refs/heads/not-pushed"));
548 assertEquals(null,
549 git2.getRepository().resolve("refs/heads/master"));
550 git.push().setRemote("test").setPushDefault(PushDefault.UPSTREAM)
551 .call();
552 assertEquals(null,
553 git2.getRepository().resolve("refs/heads/branchtopush"));
554 assertEquals(commit.getId(),
555 git2.getRepository().resolve("refs/heads/upstreambranch"));
556 assertEquals(null,
557 git2.getRepository().resolve("refs/heads/not-pushed"));
558 assertEquals(null,
559 git2.getRepository().resolve("refs/heads/master"));
560 assertEquals(commit.getId(), git.getRepository()
561 .resolve("refs/remotes/origin/upstreambranch"));
562 assertEquals(null, git.getRepository()
563 .resolve("refs/remotes/origin/branchtopush"));
564 }
565 }
566
567
568
569
570
571
572
573 @Test
574 public void testPushDefaultUpstreamNoTracking() throws Exception {
575 try (Git git = new Git(db);
576 Git git2 = new Git(createBareRepository())) {
577 StoredConfig config = git.getRepository().getConfig();
578 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
579 URIish uri = new URIish(
580 git2.getRepository().getDirectory().toURI().toURL());
581 remoteConfig.addURI(uri);
582 remoteConfig.addFetchRefSpec(
583 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
584 remoteConfig.update(config);
585 config.save();
586
587 writeTrashFile("f", "content of f");
588 git.add().addFilepattern("f").call();
589 git.commit().setMessage("adding f").call();
590
591 git.checkout().setName("not-pushed").setCreateBranch(true).call();
592 git.checkout().setName("branchtopush").setCreateBranch(true).call();
593
594 config = git.getRepository().getConfig();
595 config.setString("branch", "branchtopush", "remote", "test");
596 config.save();
597
598 assertThrows(InvalidRefNameException.class,
599 () -> git.push().setRemote("test")
600 .setPushDefault(PushDefault.UPSTREAM).call());
601 }
602 }
603
604
605
606
607
608
609
610
611 @Test
612 public void testPushDefaultUpstreamTriangular() throws Exception {
613 try (Git git = new Git(db);
614 Git git2 = new Git(createBareRepository())) {
615 StoredConfig config = git.getRepository().getConfig();
616 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
617 URIish uri = new URIish(
618 git2.getRepository().getDirectory().toURI().toURL());
619 remoteConfig.addURI(uri);
620 remoteConfig.addFetchRefSpec(
621 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
622 remoteConfig.update(config);
623 config.save();
624
625 writeTrashFile("f", "content of f");
626 git.add().addFilepattern("f").call();
627 git.commit().setMessage("adding f").call();
628
629 git.checkout().setName("not-pushed").setCreateBranch(true).call();
630 git.checkout().setName("branchtopush").setCreateBranch(true).call();
631
632 config = git.getRepository().getConfig();
633
634 config.setString("branch", "branchtopush", "merge",
635 "upstreambranch");
636 config.save();
637
638 assertThrows(InvalidRefNameException.class,
639 () -> git.push().setRemote("test")
640 .setPushDefault(PushDefault.UPSTREAM).call());
641 }
642 }
643
644
645
646
647
648
649
650 @Test
651 public void testPushDefaultSimple() throws Exception {
652 try (Git git = new Git(db);
653 Git git2 = new Git(createBareRepository())) {
654 StoredConfig config = git.getRepository().getConfig();
655 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
656 URIish uri = new URIish(
657 git2.getRepository().getDirectory().toURI().toURL());
658 remoteConfig.addURI(uri);
659 remoteConfig.addFetchRefSpec(
660 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
661 remoteConfig.update(config);
662 config.save();
663
664 writeTrashFile("f", "content of f");
665 git.add().addFilepattern("f").call();
666 RevCommit commit = git.commit().setMessage("adding f").call();
667
668 git.checkout().setName("not-pushed").setCreateBranch(true).call();
669 git.checkout().setName("branchtopush").setCreateBranch(true).call();
670
671 config = git.getRepository().getConfig();
672 config.setString("branch", "branchtopush", "remote", "test");
673 config.setString("branch", "branchtopush", "merge",
674 "refs/heads/branchtopush");
675 config.save();
676
677 assertEquals(null,
678 git2.getRepository().resolve("refs/heads/branchtopush"));
679 assertEquals(null,
680 git2.getRepository().resolve("refs/heads/not-pushed"));
681 assertEquals(null,
682 git2.getRepository().resolve("refs/heads/master"));
683 git.push().setRemote("test").setPushDefault(PushDefault.SIMPLE)
684 .call();
685 assertEquals(commit.getId(),
686 git2.getRepository().resolve("refs/heads/branchtopush"));
687 assertEquals(null,
688 git2.getRepository().resolve("refs/heads/not-pushed"));
689 assertEquals(null,
690 git2.getRepository().resolve("refs/heads/master"));
691 assertEquals(commit.getId(), git.getRepository()
692 .resolve("refs/remotes/origin/branchtopush"));
693 }
694 }
695
696
697
698
699
700
701
702 @Test
703 public void testPushDefaultSimpleTriangular() throws Exception {
704 try (Git git = new Git(db);
705 Git git2 = new Git(createBareRepository())) {
706 StoredConfig config = git.getRepository().getConfig();
707 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
708 URIish uri = new URIish(
709 git2.getRepository().getDirectory().toURI().toURL());
710 remoteConfig.addURI(uri);
711 remoteConfig.addFetchRefSpec(
712 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
713 remoteConfig.update(config);
714 config.save();
715
716 writeTrashFile("f", "content of f");
717 git.add().addFilepattern("f").call();
718 RevCommit commit = git.commit().setMessage("adding f").call();
719
720 git.checkout().setName("not-pushed").setCreateBranch(true).call();
721 git.checkout().setName("branchtopush").setCreateBranch(true).call();
722
723 config = git.getRepository().getConfig();
724
725
726 config.setString("branch", "branchtopush", "merge",
727 "refs/heads/upstreambranch");
728 config.save();
729
730 assertEquals(null,
731 git2.getRepository().resolve("refs/heads/branchtopush"));
732 assertEquals(null,
733 git2.getRepository().resolve("refs/heads/upstreambranch"));
734 assertEquals(null,
735 git2.getRepository().resolve("refs/heads/not-pushed"));
736 assertEquals(null,
737 git2.getRepository().resolve("refs/heads/master"));
738 git.push().setRemote("test").setPushDefault(PushDefault.SIMPLE)
739 .call();
740 assertEquals(commit.getId(),
741 git2.getRepository().resolve("refs/heads/branchtopush"));
742 assertEquals(null,
743 git2.getRepository().resolve("refs/heads/upstreambranch"));
744 assertEquals(null,
745 git2.getRepository().resolve("refs/heads/not-pushed"));
746 assertEquals(null,
747 git2.getRepository().resolve("refs/heads/master"));
748 assertEquals(commit.getId(), git.getRepository()
749 .resolve("refs/remotes/origin/branchtopush"));
750 }
751 }
752
753
754
755
756
757
758
759 @Test
760 public void testPushDefaultSimpleNoTracking() throws Exception {
761 try (Git git = new Git(db);
762 Git git2 = new Git(createBareRepository())) {
763 StoredConfig config = git.getRepository().getConfig();
764 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
765 URIish uri = new URIish(
766 git2.getRepository().getDirectory().toURI().toURL());
767 remoteConfig.addURI(uri);
768 remoteConfig.addFetchRefSpec(
769 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
770 remoteConfig.update(config);
771 config.save();
772
773 writeTrashFile("f", "content of f");
774 git.add().addFilepattern("f").call();
775 git.commit().setMessage("adding f").call();
776
777 git.checkout().setName("not-pushed").setCreateBranch(true).call();
778 git.checkout().setName("branchtopush").setCreateBranch(true).call();
779
780 config = git.getRepository().getConfig();
781 config.setString("branch", "branchtopush", "remote", "test");
782 config.save();
783
784 assertThrows(InvalidRefNameException.class,
785 () -> git.push().setRemote("test")
786 .setPushDefault(PushDefault.SIMPLE).call());
787 }
788 }
789
790
791
792
793
794
795
796
797 @Test
798 public void testPushDefaultSimpleDifferentTracking() throws Exception {
799 try (Git git = new Git(db);
800 Git git2 = new Git(createBareRepository())) {
801 StoredConfig config = git.getRepository().getConfig();
802 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
803 URIish uri = new URIish(
804 git2.getRepository().getDirectory().toURI().toURL());
805 remoteConfig.addURI(uri);
806 remoteConfig.addFetchRefSpec(
807 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
808 remoteConfig.update(config);
809 config.save();
810
811 writeTrashFile("f", "content of f");
812 git.add().addFilepattern("f").call();
813 git.commit().setMessage("adding f").call();
814
815 git.checkout().setName("not-pushed").setCreateBranch(true).call();
816 git.checkout().setName("branchtopush").setCreateBranch(true).call();
817
818 config = git.getRepository().getConfig();
819 config.setString("branch", "branchtopush", "remote", "test");
820 config.setString("branch", "branchtopush", "merge",
821 "refs/heads/upstreambranch");
822 config.save();
823
824 assertThrows(InvalidRefNameException.class,
825 () -> git.push().setRemote("test")
826 .setPushDefault(PushDefault.SIMPLE).call());
827 }
828 }
829
830
831
832
833
834
835
836 @Test
837 public void testPushDefaultFromConfig() throws Exception {
838 try (Git git = new Git(db);
839 Git git2 = new Git(createBareRepository())) {
840 StoredConfig config = git.getRepository().getConfig();
841 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
842 URIish uri = new URIish(
843 git2.getRepository().getDirectory().toURI().toURL());
844 remoteConfig.addURI(uri);
845 remoteConfig.addFetchRefSpec(
846 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
847 remoteConfig.update(config);
848 config.setString("push", null, "default", "upstream");
849 config.save();
850
851 writeTrashFile("f", "content of f");
852 git.add().addFilepattern("f").call();
853 RevCommit commit = git.commit().setMessage("adding f").call();
854
855 git.checkout().setName("not-pushed").setCreateBranch(true).call();
856 git.checkout().setName("branchtopush").setCreateBranch(true).call();
857
858 config = git.getRepository().getConfig();
859 config.setString("branch", "branchtopush", "remote", "test");
860 config.setString("branch", "branchtopush", "merge",
861 "refs/heads/upstreambranch");
862 config.save();
863
864 assertEquals(null,
865 git2.getRepository().resolve("refs/heads/branchtopush"));
866 assertEquals(null,
867 git2.getRepository().resolve("refs/heads/upstreambranch"));
868 assertEquals(null,
869 git2.getRepository().resolve("refs/heads/not-pushed"));
870 assertEquals(null,
871 git2.getRepository().resolve("refs/heads/master"));
872 PushCommand cmd = git.push();
873 cmd.setRemote("test").setPushDefault(null).call();
874 assertEquals(PushDefault.UPSTREAM, cmd.getPushDefault());
875 assertEquals(null,
876 git2.getRepository().resolve("refs/heads/branchtopush"));
877 assertEquals(commit.getId(),
878 git2.getRepository().resolve("refs/heads/upstreambranch"));
879 assertEquals(null,
880 git2.getRepository().resolve("refs/heads/not-pushed"));
881 assertEquals(null,
882 git2.getRepository().resolve("refs/heads/master"));
883 assertEquals(commit.getId(), git.getRepository()
884 .resolve("refs/remotes/origin/upstreambranch"));
885 assertEquals(null, git.getRepository()
886 .resolve("refs/remotes/origin/branchtopush"));
887 }
888 }
889
890
891
892
893
894
895
896 @Test
897 public void testPushDefaultFromConfigDefault() throws Exception {
898 try (Git git = new Git(db);
899 Git git2 = new Git(createBareRepository())) {
900 StoredConfig config = git.getRepository().getConfig();
901 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
902 URIish uri = new URIish(
903 git2.getRepository().getDirectory().toURI().toURL());
904 remoteConfig.addURI(uri);
905 remoteConfig.addFetchRefSpec(
906 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
907 remoteConfig.update(config);
908 config.save();
909
910 writeTrashFile("f", "content of f");
911 git.add().addFilepattern("f").call();
912 RevCommit commit = git.commit().setMessage("adding f").call();
913
914 git.checkout().setName("not-pushed").setCreateBranch(true).call();
915 git.checkout().setName("branchtopush").setCreateBranch(true).call();
916
917 config = git.getRepository().getConfig();
918 config.setString("branch", "branchtopush", "remote", "test");
919 config.setString("branch", "branchtopush", "merge",
920 "refs/heads/branchtopush");
921 config.save();
922
923 assertEquals(null,
924 git2.getRepository().resolve("refs/heads/branchtopush"));
925 assertEquals(null,
926 git2.getRepository().resolve("refs/heads/not-pushed"));
927 assertEquals(null,
928 git2.getRepository().resolve("refs/heads/master"));
929 PushCommand cmd = git.push();
930 cmd.setRemote("test").setPushDefault(null).call();
931 assertEquals(PushDefault.SIMPLE, cmd.getPushDefault());
932 assertEquals(commit.getId(),
933 git2.getRepository().resolve("refs/heads/branchtopush"));
934 assertEquals(null,
935 git2.getRepository().resolve("refs/heads/not-pushed"));
936 assertEquals(null,
937 git2.getRepository().resolve("refs/heads/master"));
938 assertEquals(commit.getId(), git.getRepository()
939 .resolve("refs/remotes/origin/branchtopush"));
940 }
941 }
942
943
944
945
946
947
948 @Test
949 public void testBranchPushRemote() throws Exception {
950 try (Git git = new Git(db);
951 Git git2 = new Git(createBareRepository())) {
952 StoredConfig config = git.getRepository().getConfig();
953 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
954 URIish uri = new URIish(
955 git2.getRepository().getDirectory().toURI().toURL());
956 remoteConfig.addURI(uri);
957 remoteConfig.addFetchRefSpec(
958 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
959 remoteConfig.update(config);
960 config.setString("remote", null, "pushDefault", "test");
961 config.save();
962
963 writeTrashFile("f", "content of f");
964 git.add().addFilepattern("f").call();
965 git.commit().setMessage("adding f").call();
966
967 git.checkout().setName("not-pushed").setCreateBranch(true).call();
968 git.checkout().setName("branchtopush").setCreateBranch(true).call();
969
970 config = git.getRepository().getConfig();
971 config.setString("branch", "branchtopush", "remote", "test");
972 config.setString("branch", "branchtopush", "pushremote", "origin");
973 config.setString("branch", "branchtopush", "merge",
974 "refs/heads/branchtopush");
975 config.save();
976
977 assertThrows(InvalidRefNameException.class, () -> git.push()
978 .setPushDefault(PushDefault.UPSTREAM).call());
979 }
980 }
981
982
983
984
985
986
987 @Test
988 public void testRemotePushDefault() throws Exception {
989 try (Git git = new Git(db);
990 Git git2 = new Git(createBareRepository())) {
991 StoredConfig config = git.getRepository().getConfig();
992 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
993 URIish uri = new URIish(
994 git2.getRepository().getDirectory().toURI().toURL());
995 remoteConfig.addURI(uri);
996 remoteConfig.addFetchRefSpec(
997 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
998 remoteConfig.update(config);
999 config.setString("remote", null, "pushDefault", "origin");
1000 config.save();
1001
1002 writeTrashFile("f", "content of f");
1003 git.add().addFilepattern("f").call();
1004 git.commit().setMessage("adding f").call();
1005
1006 git.checkout().setName("not-pushed").setCreateBranch(true).call();
1007 git.checkout().setName("branchtopush").setCreateBranch(true).call();
1008
1009 config = git.getRepository().getConfig();
1010 config.setString("branch", "branchtopush", "remote", "test");
1011 config.setString("branch", "branchtopush", "merge",
1012 "refs/heads/branchtopush");
1013 config.save();
1014
1015 assertThrows(InvalidRefNameException.class, () -> git.push()
1016 .setPushDefault(PushDefault.UPSTREAM).call());
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025 @Test
1026 public void testDefaultRemote() throws Exception {
1027 try (Git git = new Git(db);
1028 Git git2 = new Git(createBareRepository())) {
1029 StoredConfig config = git.getRepository().getConfig();
1030 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
1031 URIish uri = new URIish(
1032 git2.getRepository().getDirectory().toURI().toURL());
1033 remoteConfig.addURI(uri);
1034 remoteConfig.addFetchRefSpec(
1035 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
1036 remoteConfig.update(config);
1037 config.save();
1038
1039 writeTrashFile("f", "content of f");
1040 git.add().addFilepattern("f").call();
1041 git.commit().setMessage("adding f").call();
1042
1043 git.checkout().setName("not-pushed").setCreateBranch(true).call();
1044 git.checkout().setName("branchtopush").setCreateBranch(true).call();
1045
1046 config = git.getRepository().getConfig();
1047 config.setString("branch", "branchtopush", "merge",
1048 "refs/heads/branchtopush");
1049 config.save();
1050
1051 PushCommand cmd = git.push().setPushDefault(PushDefault.UPSTREAM);
1052 TransportException e = assertThrows(TransportException.class,
1053 () -> cmd.call());
1054 assertEquals(NoRemoteRepositoryException.class,
1055 e.getCause().getClass());
1056 assertEquals("origin", cmd.getRemote());
1057 }
1058 }
1059
1060
1061
1062
1063
1064
1065
1066 @Test
1067 public void testDefaultPush() throws Exception {
1068 try (Git git = new Git(db);
1069 Git git2 = new Git(createBareRepository())) {
1070 StoredConfig config = git.getRepository().getConfig();
1071 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
1072 URIish uri = new URIish(
1073 git2.getRepository().getDirectory().toURI().toURL());
1074 remoteConfig.addURI(uri);
1075 remoteConfig.addFetchRefSpec(
1076 new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
1077 remoteConfig.update(config);
1078 config.save();
1079
1080 writeTrashFile("f", "content of f");
1081 git.add().addFilepattern("f").call();
1082 RevCommit commit = git.commit().setMessage("adding f").call();
1083
1084 git.checkout().setName("not-pushed").setCreateBranch(true).call();
1085 git.checkout().setName("branchtopush").setCreateBranch(true).call();
1086
1087 config = git.getRepository().getConfig();
1088 config.setString("branch", "branchtopush", "remote", "test");
1089 config.save();
1090
1091 assertEquals(null,
1092 git2.getRepository().resolve("refs/heads/branchtopush"));
1093 assertEquals(null,
1094 git2.getRepository().resolve("refs/heads/not-pushed"));
1095 assertEquals(null,
1096 git2.getRepository().resolve("refs/heads/master"));
1097
1098 PushCommand cmd = git.push();
1099 cmd.call();
1100 assertEquals("test", cmd.getRemote());
1101 assertEquals(PushDefault.CURRENT, cmd.getPushDefault());
1102 assertEquals(commit.getId(),
1103 git2.getRepository().resolve("refs/heads/branchtopush"));
1104 assertEquals(null,
1105 git2.getRepository().resolve("refs/heads/not-pushed"));
1106 assertEquals(null,
1107 git2.getRepository().resolve("refs/heads/master"));
1108 assertEquals(commit.getId(), git.getRepository()
1109 .resolve("refs/remotes/origin/branchtopush"));
1110 }
1111 }
1112
1113
1114
1115
1116
1117
1118 @Test
1119 public void testPushAfterGC() throws Exception {
1120
1121 Repository db2 = createWorkRepository();
1122 addRepoToClose(db2);
1123
1124
1125 final StoredConfig config = db.getConfig();
1126 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
1127 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
1128 remoteConfig.addURI(uri);
1129 remoteConfig.update(config);
1130 config.save();
1131
1132 try (Git git1 = new Git(db);
1133 Git git2 = new Git(db2)) {
1134
1135 git1.commit().setMessage("initial commit").call();
1136
1137 RefSpec spec = new RefSpec("refs/heads/*:refs/heads/*");
1138 git1.push().setRemote("test").setRefSpecs(spec).call();
1139
1140
1141 git2.branchCreate().setName("refs/heads/other").call();
1142 git2.checkout().setName("refs/heads/other").call();
1143
1144 writeTrashFile("a", "content of a");
1145 git2.add().addFilepattern("a").call();
1146 RevCommit commit2 = git2.commit().setMessage("adding a").call();
1147
1148
1149 Properties res = git1.gc().setExpire(null).call();
1150 assertEquals(8, res.size());
1151
1152
1153 writeTrashFile("b", "content of b");
1154 git1.add().addFilepattern("b").call();
1155 RevCommit commit3 = git1.commit().setMessage("adding b").call();
1156
1157 try {
1158
1159 git1.push().setRemote("test").setRefSpecs(spec).call();
1160 } catch (TransportException e) {
1161 assertTrue("should be caused by a MissingObjectException", e
1162 .getCause().getCause() instanceof MissingObjectException);
1163 fail("caught MissingObjectException for a change we don't have");
1164 }
1165
1166
1167 try {
1168 db.resolve(commit2.getId().getName() + "^{commit}");
1169 fail("id shouldn't exist locally");
1170 } catch (MissingObjectException e) {
1171
1172 }
1173 assertEquals(commit2.getId(),
1174 db2.resolve(commit2.getId().getName() + "^{commit}"));
1175 assertEquals(commit3.getId(),
1176 db2.resolve(commit3.getId().getName() + "^{commit}"));
1177 }
1178 }
1179
1180 @Test
1181 public void testPushWithLease() throws JGitInternalException, IOException,
1182 GitAPIException, URISyntaxException {
1183
1184
1185 Repository db2 = createWorkRepository();
1186 addRepoToClose(db2);
1187
1188
1189 final StoredConfig config = db.getConfig();
1190 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
1191 URIish uri = new URIish(db2.getDirectory().toURI().toURL());
1192 remoteConfig.addURI(uri);
1193 remoteConfig.update(config);
1194 config.save();
1195
1196 try (Git git1 = new Git(db)) {
1197
1198 RevCommit commit = git1.commit().setMessage("initial commit").call();
1199 git1.branchCreate().setName("initial").call();
1200
1201 RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x");
1202 git1.push().setRemote("test").setRefSpecs(spec)
1203 .call();
1204
1205 assertEquals(commit.getId(),
1206 db2.resolve(commit.getId().getName() + "^{commit}"));
1207
1208
1209 git1.commit().setMessage("second commit").call();
1210 Iterable<PushResult> results =
1211 git1.push().setRemote("test").setRefSpecs(spec)
1212 .setRefLeaseSpecs(new RefLeaseSpec("refs/heads/x", "initial"))
1213 .call();
1214 for (PushResult result : results) {
1215 RemoteRefUpdate update = result.getRemoteUpdate("refs/heads/x");
1216 assertEquals(update.getStatus(), RemoteRefUpdate.Status.OK);
1217 }
1218
1219 git1.commit().setMessage("third commit").call();
1220
1221
1222 results =
1223 git1.push().setRemote("test").setRefSpecs(spec)
1224 .setRefLeaseSpecs(new RefLeaseSpec("refs/heads/x", "initial"))
1225 .call();
1226 for (PushResult result : results) {
1227 RemoteRefUpdate update = result.getRemoteUpdate("refs/heads/x");
1228 assertEquals(update.getStatus(), RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED);
1229 }
1230 }
1231 }
1232 }