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 static org.eclipse.jgit.lib.Constants.MASTER;
47 import static org.eclipse.jgit.lib.Constants.R_HEADS;
48 import static org.hamcrest.CoreMatchers.is;
49 import static org.hamcrest.MatcherAssert.assertThat;
50 import static org.junit.Assert.assertEquals;
51 import static org.junit.Assert.assertFalse;
52 import static org.junit.Assert.assertNotNull;
53 import static org.junit.Assert.assertNull;
54 import static org.junit.Assert.assertSame;
55 import static org.junit.Assert.assertTrue;
56 import static org.junit.Assert.fail;
57
58 import java.io.File;
59 import java.io.FileInputStream;
60 import java.io.IOException;
61 import java.net.MalformedURLException;
62 import java.net.URISyntaxException;
63
64 import org.eclipse.jgit.api.CheckoutResult.Status;
65 import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
66 import org.eclipse.jgit.api.errors.GitAPIException;
67 import org.eclipse.jgit.api.errors.InvalidRefNameException;
68 import org.eclipse.jgit.api.errors.InvalidRemoteException;
69 import org.eclipse.jgit.api.errors.JGitInternalException;
70 import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
71 import org.eclipse.jgit.api.errors.RefNotFoundException;
72 import org.eclipse.jgit.api.errors.TransportException;
73 import org.eclipse.jgit.dircache.DirCache;
74 import org.eclipse.jgit.dircache.DirCacheEntry;
75 import org.eclipse.jgit.junit.JGitTestUtil;
76 import org.eclipse.jgit.junit.RepositoryTestCase;
77 import org.eclipse.jgit.lib.ConfigConstants;
78 import org.eclipse.jgit.lib.Constants;
79 import org.eclipse.jgit.lib.Ref;
80 import org.eclipse.jgit.lib.RefUpdate;
81 import org.eclipse.jgit.lib.Repository;
82 import org.eclipse.jgit.lib.Sets;
83 import org.eclipse.jgit.lib.StoredConfig;
84 import org.eclipse.jgit.revwalk.RevCommit;
85 import org.eclipse.jgit.storage.file.FileBasedConfig;
86 import org.eclipse.jgit.transport.RefSpec;
87 import org.eclipse.jgit.transport.RemoteConfig;
88 import org.eclipse.jgit.transport.URIish;
89 import org.eclipse.jgit.util.FileUtils;
90 import org.junit.Before;
91 import org.junit.Test;
92
93 public class CheckoutCommandTest extends RepositoryTestCase {
94 private Git git;
95
96 RevCommit initialCommit;
97
98 RevCommit secondCommit;
99
100 @Override
101 @Before
102 public void setUp() throws Exception {
103 super.setUp();
104 git = new Git(db);
105
106 writeTrashFile("Test.txt", "Hello world");
107 git.add().addFilepattern("Test.txt").call();
108 initialCommit = git.commit().setMessage("Initial commit").call();
109
110
111 git.branchCreate().setName("test").call();
112 RefUpdate rup = db.updateRef(Constants.HEAD);
113 rup.link("refs/heads/test");
114
115
116 writeTrashFile("Test.txt", "Some change");
117 git.add().addFilepattern("Test.txt").call();
118 secondCommit = git.commit().setMessage("Second commit").call();
119 }
120
121 @Test
122 public void testSimpleCheckout() throws Exception {
123 git.checkout().setName("test").call();
124 }
125
126 @Test
127 public void testCheckout() throws Exception {
128 git.checkout().setName("test").call();
129 assertEquals("[Test.txt, mode:100644, content:Some change]",
130 indexState(CONTENT));
131 Ref result = git.checkout().setName("master").call();
132 assertEquals("[Test.txt, mode:100644, content:Hello world]",
133 indexState(CONTENT));
134 assertEquals("refs/heads/master", result.getName());
135 assertEquals("refs/heads/master", git.getRepository().getFullBranch());
136 }
137
138 @Test
139 public void testCreateBranchOnCheckout() throws Exception {
140 git.checkout().setCreateBranch(true).setName("test2").call();
141 assertNotNull(db.exactRef("refs/heads/test2"));
142 }
143
144 @Test
145 public void testCheckoutToNonExistingBranch() throws GitAPIException {
146 try {
147 git.checkout().setName("badbranch").call();
148 fail("Should have failed");
149 } catch (RefNotFoundException e) {
150
151 }
152 }
153
154 @Test
155 public void testCheckoutWithConflict() {
156 CheckoutCommand co = git.checkout();
157 try {
158 writeTrashFile("Test.txt", "Another change");
159 assertEquals(Status.NOT_TRIED, co.getResult().getStatus());
160 co.setName("master").call();
161 fail("Should have failed");
162 } catch (Exception e) {
163 assertEquals(Status.CONFLICTS, co.getResult().getStatus());
164 assertTrue(co.getResult().getConflictList().contains("Test.txt"));
165 }
166 }
167
168 @Test
169 public void testCheckoutWithNonDeletedFiles() throws Exception {
170 File testFile = writeTrashFile("temp", "");
171 FileInputStream fis = new FileInputStream(testFile);
172 try {
173 FileUtils.delete(testFile);
174 return;
175 } catch (IOException e) {
176
177
178 } finally {
179 fis.close();
180 }
181 FileUtils.delete(testFile);
182 CheckoutCommand co = git.checkout();
183
184 testFile = new File(db.getWorkTree(), "Test.txt");
185 assertTrue(testFile.exists());
186 FileUtils.delete(testFile);
187 assertFalse(testFile.exists());
188 git.add().addFilepattern("Test.txt");
189 git.commit().setMessage("Delete Test.txt").setAll(true).call();
190 git.checkout().setName("master").call();
191 assertTrue(testFile.exists());
192
193 fis = new FileInputStream(testFile);
194 try {
195 assertEquals(Status.NOT_TRIED, co.getResult().getStatus());
196 co.setName("test").call();
197 assertTrue(testFile.exists());
198 assertEquals(Status.NONDELETED, co.getResult().getStatus());
199 assertTrue(co.getResult().getUndeletedList().contains("Test.txt"));
200 } finally {
201 fis.close();
202 }
203 }
204
205 @Test
206 public void testCheckoutCommit() throws Exception {
207 Ref result = git.checkout().setName(initialCommit.name()).call();
208 assertEquals("[Test.txt, mode:100644, content:Hello world]",
209 indexState(CONTENT));
210 assertNull(result);
211 assertEquals(initialCommit.name(), git.getRepository().getFullBranch());
212 }
213
214 @Test
215 public void testCheckoutLightweightTag() throws Exception {
216 git.tag().setAnnotated(false).setName("test-tag")
217 .setObjectId(initialCommit).call();
218 Ref result = git.checkout().setName("test-tag").call();
219
220 assertNull(result);
221 assertEquals(initialCommit.getId(), db.resolve(Constants.HEAD));
222 assertHeadDetached();
223 }
224
225 @Test
226 public void testCheckoutAnnotatedTag() throws Exception {
227 git.tag().setAnnotated(true).setName("test-tag")
228 .setObjectId(initialCommit).call();
229 Ref result = git.checkout().setName("test-tag").call();
230
231 assertNull(result);
232 assertEquals(initialCommit.getId(), db.resolve(Constants.HEAD));
233 assertHeadDetached();
234 }
235
236 @Test
237 public void testCheckoutRemoteTrackingWithUpstream() throws Exception {
238 Repository db2 = createRepositoryWithRemote();
239
240 Git.wrap(db2).checkout().setCreateBranch(true).setName("test")
241 .setStartPoint("origin/test")
242 .setUpstreamMode(SetupUpstreamMode.TRACK).call();
243
244 assertEquals("refs/heads/test",
245 db2.exactRef(Constants.HEAD).getTarget().getName());
246 StoredConfig config = db2.getConfig();
247 assertEquals("origin", config.getString(
248 ConfigConstants.CONFIG_BRANCH_SECTION, "test",
249 ConfigConstants.CONFIG_KEY_REMOTE));
250 assertEquals("refs/heads/test", config.getString(
251 ConfigConstants.CONFIG_BRANCH_SECTION, "test",
252 ConfigConstants.CONFIG_KEY_MERGE));
253 }
254
255 @Test
256 public void testCheckoutRemoteTrackingWithoutLocalBranch() throws Exception {
257 Repository db2 = createRepositoryWithRemote();
258
259
260
261 Git.wrap(db2).checkout().setName("remotes/origin/test").call();
262 assertEquals("[Test.txt, mode:100644, content:Some change]",
263 indexState(db2, CONTENT));
264 }
265
266
267
268 @Test
269 public void testCheckoutOfFileWithInexistentParentDir() throws Exception {
270 File a = writeTrashFile("dir/a.txt", "A");
271 writeTrashFile("dir/b.txt", "A");
272 git.add().addFilepattern("dir/a.txt").addFilepattern("dir/b.txt")
273 .call();
274 git.commit().setMessage("Added dir").call();
275
276 File dir = new File(db.getWorkTree(), "dir");
277 FileUtils.delete(dir, FileUtils.RECURSIVE);
278
279 git.checkout().addPath("dir/a.txt").call();
280 assertTrue(a.exists());
281 }
282
283 @Test
284 public void testCheckoutOfDirectoryShouldBeRecursive() throws Exception {
285 File a = writeTrashFile("dir/a.txt", "A");
286 File b = writeTrashFile("dir/sub/b.txt", "B");
287 git.add().addFilepattern("dir").call();
288 git.commit().setMessage("Added dir").call();
289
290 write(a, "modified");
291 write(b, "modified");
292 git.checkout().addPath("dir").call();
293
294 assertThat(read(a), is("A"));
295 assertThat(read(b), is("B"));
296 }
297
298 @Test
299 public void testCheckoutAllPaths() throws Exception {
300 File a = writeTrashFile("dir/a.txt", "A");
301 File b = writeTrashFile("dir/sub/b.txt", "B");
302 git.add().addFilepattern("dir").call();
303 git.commit().setMessage("Added dir").call();
304
305 write(a, "modified");
306 write(b, "modified");
307 git.checkout().setAllPaths(true).call();
308
309 assertThat(read(a), is("A"));
310 assertThat(read(b), is("B"));
311 }
312
313 @Test
314 public void testCheckoutWithStartPoint() throws Exception {
315 File a = writeTrashFile("a.txt", "A");
316 git.add().addFilepattern("a.txt").call();
317 RevCommit first = git.commit().setMessage("Added a").call();
318
319 write(a, "other");
320 git.commit().setAll(true).setMessage("Other").call();
321
322 git.checkout().setCreateBranch(true).setName("a")
323 .setStartPoint(first.getId().getName()).call();
324
325 assertThat(read(a), is("A"));
326 }
327
328 @Test
329 public void testCheckoutWithStartPointOnlyCertainFiles() throws Exception {
330 File a = writeTrashFile("a.txt", "A");
331 File b = writeTrashFile("b.txt", "B");
332 git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
333 RevCommit first = git.commit().setMessage("First").call();
334
335 write(a, "other");
336 write(b, "other");
337 git.commit().setAll(true).setMessage("Other").call();
338
339 git.checkout().setCreateBranch(true).setName("a")
340 .setStartPoint(first.getId().getName()).addPath("a.txt").call();
341
342 assertThat(read(a), is("A"));
343 assertThat(read(b), is("other"));
344 }
345
346 @Test
347 public void testDetachedHeadOnCheckout() throws JGitInternalException,
348 IOException, GitAPIException {
349 CheckoutCommand co = git.checkout();
350 co.setName("master").call();
351
352 String commitId = db.exactRef(R_HEADS + MASTER).getObjectId().name();
353 co = git.checkout();
354 co.setName(commitId).call();
355
356 assertHeadDetached();
357 }
358
359 @Test
360 public void testUpdateSmudgedEntries() throws Exception {
361 git.branchCreate().setName("test2").call();
362 RefUpdate rup = db.updateRef(Constants.HEAD);
363 rup.link("refs/heads/test2");
364
365 File file = new File(db.getWorkTree(), "Test.txt");
366 long size = file.length();
367 long mTime = file.lastModified() - 5000L;
368 assertTrue(file.setLastModified(mTime));
369
370 DirCache cache = DirCache.lock(db.getIndexFile(), db.getFS());
371 DirCacheEntry entry = cache.getEntry("Test.txt");
372 assertNotNull(entry);
373 entry.setLength(0);
374 entry.setLastModified(0);
375 cache.write();
376 assertTrue(cache.commit());
377
378 cache = DirCache.read(db.getIndexFile(), db.getFS());
379 entry = cache.getEntry("Test.txt");
380 assertNotNull(entry);
381 assertEquals(0, entry.getLength());
382 assertEquals(0, entry.getLastModified());
383
384 db.getIndexFile().setLastModified(
385 db.getIndexFile().lastModified() - 5000);
386
387 assertNotNull(git.checkout().setName("test").call());
388
389 cache = DirCache.read(db.getIndexFile(), db.getFS());
390 entry = cache.getEntry("Test.txt");
391 assertNotNull(entry);
392 assertEquals(size, entry.getLength());
393 assertEquals(mTime, entry.getLastModified());
394 }
395
396 @Test
397 public void testCheckoutOrphanBranch() throws Exception {
398 CheckoutCommand co = newOrphanBranchCommand();
399 assertCheckoutRef(co.call());
400
401 File HEAD = new File(trash, ".git/HEAD");
402 String headRef = read(HEAD);
403 assertEquals("ref: refs/heads/orphanbranch\n", headRef);
404 assertEquals(2, trash.list().length);
405
406 File heads = new File(trash, ".git/refs/heads");
407 assertEquals(2, heads.listFiles().length);
408
409 this.assertNoHead();
410 this.assertRepositoryCondition(1);
411 assertEquals(CheckoutResult.NOT_TRIED_RESULT, co.getResult());
412 }
413
414 private Repository createRepositoryWithRemote() throws IOException,
415 URISyntaxException, MalformedURLException, GitAPIException,
416 InvalidRemoteException, TransportException {
417
418 Repository db2 = createWorkRepository();
419 try (Git git2 = new Git(db2)) {
420
421 final StoredConfig config = db2.getConfig();
422 RemoteConfig remoteConfig = new RemoteConfig(config, "origin");
423 URIish uri = new URIish(db.getDirectory().toURI().toURL());
424 remoteConfig.addURI(uri);
425 remoteConfig.update(config);
426 config.save();
427
428
429 RefSpec spec = new RefSpec("+refs/heads/*:refs/remotes/origin/*");
430 git2.fetch().setRemote("origin").setRefSpecs(spec).call();
431 return db2;
432 }
433 }
434
435 private CheckoutCommand newOrphanBranchCommand() {
436 return git.checkout().setOrphan(true)
437 .setName("orphanbranch");
438 }
439
440 private static void assertCheckoutRef(Ref ref) {
441 assertNotNull(ref);
442 assertEquals("refs/heads/orphanbranch", ref.getTarget().getName());
443 }
444
445 private void assertNoHead() throws IOException {
446 assertNull(db.resolve("HEAD"));
447 }
448
449 private void assertHeadDetached() throws IOException {
450 Ref head = db.exactRef(Constants.HEAD);
451 assertFalse(head.isSymbolic());
452 assertSame(head, head.getTarget());
453 }
454
455 private void assertRepositoryCondition(int files) throws GitAPIException {
456 org.eclipse.jgit.api.Status status = this.git.status().call();
457 assertFalse(status.isClean());
458 assertEquals(files, status.getAdded().size());
459 }
460
461 @Test
462 public void testCreateOrphanBranchWithStartCommit() throws Exception {
463 CheckoutCommand co = newOrphanBranchCommand();
464 Ref ref = co.setStartPoint(initialCommit).call();
465 assertCheckoutRef(ref);
466 assertEquals(2, trash.list().length);
467 this.assertNoHead();
468 this.assertRepositoryCondition(1);
469 }
470
471 @Test
472 public void testCreateOrphanBranchWithStartPoint() throws Exception {
473 CheckoutCommand co = newOrphanBranchCommand();
474 Ref ref = co.setStartPoint("HEAD^").call();
475 assertCheckoutRef(ref);
476
477 assertEquals(2, trash.list().length);
478 this.assertNoHead();
479 this.assertRepositoryCondition(1);
480 }
481
482 @Test
483 public void testInvalidRefName() throws Exception {
484 try {
485 git.checkout().setOrphan(true).setName("../invalidname").call();
486 fail("Should have failed");
487 } catch (InvalidRefNameException e) {
488
489 }
490 }
491
492 @Test
493 public void testNullRefName() throws Exception {
494 try {
495 git.checkout().setOrphan(true).setName(null).call();
496 fail("Should have failed");
497 } catch (InvalidRefNameException e) {
498
499 }
500 }
501
502 @Test
503 public void testAlreadyExists() throws Exception {
504 this.git.checkout().setCreateBranch(true).setName("orphanbranch")
505 .call();
506 this.git.checkout().setName("master").call();
507
508 try {
509 newOrphanBranchCommand().call();
510 fail("Should have failed");
511 } catch (RefAlreadyExistsException e) {
512
513 }
514 }
515
516
517
518 @Test
519 public void testCheckoutAutoCrlfTrue() throws Exception {
520 int nrOfAutoCrlfTestFiles = 200;
521
522 FileBasedConfig c = db.getConfig();
523 c.setString("core", null, "autocrlf", "true");
524 c.save();
525
526 AddCommand add = git.add();
527 for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
528 writeTrashFile("Test_" + i + ".txt", "Hello " + i
529 + " world\nX\nYU\nJK\n");
530 add.addFilepattern("Test_" + i + ".txt");
531 }
532 fsTick(null);
533 add.call();
534 RevCommit c1 = git.commit().setMessage("add some lines").call();
535
536 add = git.add();
537 for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
538 writeTrashFile("Test_" + i + ".txt", "Hello " + i
539 + " world\nX\nY\n");
540 add.addFilepattern("Test_" + i + ".txt");
541 }
542 fsTick(null);
543 add.call();
544 git.commit().setMessage("add more").call();
545
546 git.checkout().setName(c1.getName()).call();
547
548 boolean foundUnsmudged = false;
549 DirCache dc = db.readDirCache();
550 for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
551 DirCacheEntry entry = dc.getEntry(
552 "Test_" + i + ".txt");
553 if (!entry.isSmudged()) {
554 foundUnsmudged = true;
555 assertEquals("unexpected file length in git index", 28,
556 entry.getLength());
557 }
558 }
559 org.junit.Assume.assumeTrue(foundUnsmudged);
560 }
561
562 @Test
563 public void testSmudgeFilter_modifyExisting() throws IOException, GitAPIException {
564 File script = writeTempFile("sed s/o/e/g");
565 StoredConfig config = git.getRepository().getConfig();
566 config.setString("filter", "tstFilter", "smudge",
567 "sh " + slashify(script.getPath()));
568 config.save();
569
570 writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
571 git.add().addFilepattern(".gitattributes").call();
572 git.commit().setMessage("add filter").call();
573
574 writeTrashFile("src/a.tmp", "x");
575
576
577 writeTrashFile("src/a.txt", "x\n");
578 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
579 .call();
580 RevCommit content1 = git.commit().setMessage("add content").call();
581
582 writeTrashFile("src/a.tmp", "foo");
583 writeTrashFile("src/a.txt", "foo\n");
584 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
585 .call();
586 RevCommit content2 = git.commit().setMessage("changed content").call();
587
588 git.checkout().setName(content1.getName()).call();
589 git.checkout().setName(content2.getName()).call();
590
591 assertEquals(
592 "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
593 indexState(CONTENT));
594 assertEquals(Sets.of("src/a.txt"), git.status().call().getModified());
595 assertEquals("foo", read("src/a.tmp"));
596 assertEquals("fee\n", read("src/a.txt"));
597 }
598
599 @Test
600 public void testSmudgeFilter_createNew()
601 throws IOException, GitAPIException {
602 File script = writeTempFile("sed s/o/e/g");
603 StoredConfig config = git.getRepository().getConfig();
604 config.setString("filter", "tstFilter", "smudge",
605 "sh " + slashify(script.getPath()));
606 config.save();
607
608 writeTrashFile("foo", "foo");
609 git.add().addFilepattern("foo").call();
610 RevCommit initial = git.commit().setMessage("initial").call();
611
612 writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
613 git.add().addFilepattern(".gitattributes").call();
614 git.commit().setMessage("add filter").call();
615
616 writeTrashFile("src/a.tmp", "foo");
617
618
619 writeTrashFile("src/a.txt", "foo\n");
620 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
621 .call();
622 RevCommit content = git.commit().setMessage("added content").call();
623
624 git.checkout().setName(initial.getName()).call();
625 git.checkout().setName(content.getName()).call();
626
627 assertEquals(
628 "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
629 indexState(CONTENT));
630 assertEquals("foo", read("src/a.tmp"));
631 assertEquals("fee\n", read("src/a.txt"));
632 }
633
634 @Test
635 public void testSmudgeFilter_deleteFileAndRestoreFromCommit()
636 throws IOException, GitAPIException {
637 File script = writeTempFile("sed s/o/e/g");
638 StoredConfig config = git.getRepository().getConfig();
639 config.setString("filter", "tstFilter", "smudge",
640 "sh " + slashify(script.getPath()));
641 config.save();
642
643 writeTrashFile("foo", "foo");
644 git.add().addFilepattern("foo").call();
645 git.commit().setMessage("initial").call();
646
647 writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
648 git.add().addFilepattern(".gitattributes").call();
649 git.commit().setMessage("add filter").call();
650
651 writeTrashFile("src/a.tmp", "foo");
652
653
654 writeTrashFile("src/a.txt", "foo\n");
655 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
656 .call();
657 RevCommit content = git.commit().setMessage("added content").call();
658
659 deleteTrashFile("src/a.txt");
660 git.checkout().setStartPoint(content.getName()).addPath("src/a.txt")
661 .call();
662
663 assertEquals(
664 "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
665 indexState(CONTENT));
666 assertEquals("foo", read("src/a.tmp"));
667 assertEquals("fee\n", read("src/a.txt"));
668 }
669
670 @Test
671 public void testSmudgeFilter_deleteFileAndRestoreFromIndex()
672 throws IOException, GitAPIException {
673 File script = writeTempFile("sed s/o/e/g");
674 StoredConfig config = git.getRepository().getConfig();
675 config.setString("filter", "tstFilter", "smudge",
676 "sh " + slashify(script.getPath()));
677 config.save();
678
679 writeTrashFile("foo", "foo");
680 git.add().addFilepattern("foo").call();
681 git.commit().setMessage("initial").call();
682
683 writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
684 git.add().addFilepattern(".gitattributes").call();
685 git.commit().setMessage("add filter").call();
686
687 writeTrashFile("src/a.tmp", "foo");
688
689
690 writeTrashFile("src/a.txt", "foo\n");
691 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
692 .call();
693 git.commit().setMessage("added content").call();
694
695 deleteTrashFile("src/a.txt");
696 git.checkout().addPath("src/a.txt").call();
697
698 assertEquals(
699 "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
700 indexState(CONTENT));
701 assertEquals("foo", read("src/a.tmp"));
702 assertEquals("fee\n", read("src/a.txt"));
703 }
704
705 @Test
706 public void testSmudgeFilter_deleteFileAndCreateBranchAndRestoreFromCommit()
707 throws IOException, GitAPIException {
708 File script = writeTempFile("sed s/o/e/g");
709 StoredConfig config = git.getRepository().getConfig();
710 config.setString("filter", "tstFilter", "smudge",
711 "sh " + slashify(script.getPath()));
712 config.save();
713
714 writeTrashFile("foo", "foo");
715 git.add().addFilepattern("foo").call();
716 git.commit().setMessage("initial").call();
717
718 writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
719 git.add().addFilepattern(".gitattributes").call();
720 git.commit().setMessage("add filter").call();
721
722 writeTrashFile("src/a.tmp", "foo");
723
724
725 writeTrashFile("src/a.txt", "foo\n");
726 git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
727 .call();
728 RevCommit content = git.commit().setMessage("added content").call();
729
730 deleteTrashFile("src/a.txt");
731 git.checkout().setName("newBranch").setCreateBranch(true)
732 .setStartPoint(content).addPath("src/a.txt").call();
733
734 assertEquals(
735 "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
736 indexState(CONTENT));
737 assertEquals("foo", read("src/a.tmp"));
738 assertEquals("fee\n", read("src/a.txt"));
739 }
740
741 @Test
742 public void testSmudgeAndClean() throws Exception {
743 File clean_filter = writeTempFile("sed s/V1/@version/g");
744 File smudge_filter = writeTempFile("sed s/@version/V1/g");
745
746 try (Git git2 = new Git(db)) {
747 StoredConfig config = git.getRepository().getConfig();
748 config.setString("filter", "tstFilter", "smudge",
749 "sh " + slashify(smudge_filter.getPath()));
750 config.setString("filter", "tstFilter", "clean",
751 "sh " + slashify(clean_filter.getPath()));
752 config.save();
753 writeTrashFile(".gitattributes", "filterTest.txt filter=tstFilter");
754 git2.add().addFilepattern(".gitattributes").call();
755 git2.commit().setMessage("add attributes").call();
756
757 fsTick(writeTrashFile("filterTest.txt", "hello world, V1\n"));
758 git2.add().addFilepattern("filterTest.txt").call();
759 RevCommit one = git2.commit().setMessage("add filterText.txt").call();
760 assertEquals(
761 "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]",
762 indexState(CONTENT));
763
764 fsTick(writeTrashFile("filterTest.txt", "bon giorno world, V1\n"));
765 git2.add().addFilepattern("filterTest.txt").call();
766 RevCommit two = git2.commit().setMessage("modified filterTest.txt").call();
767
768 assertTrue(git2.status().call().isClean());
769 assertEquals(
770 "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]",
771 indexState(CONTENT));
772
773 git2.checkout().setName(one.getName()).call();
774 assertTrue(git2.status().call().isClean());
775 assertEquals(
776 "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]",
777 indexState(CONTENT));
778 assertEquals("hello world, V1\n", read("filterTest.txt"));
779
780 git2.checkout().setName(two.getName()).call();
781 assertTrue(git2.status().call().isClean());
782 assertEquals(
783 "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]",
784 indexState(CONTENT));
785 assertEquals("bon giorno world, V1\n", read("filterTest.txt"));
786 }
787 }
788
789 private File writeTempFile(String body) throws IOException {
790 File f = File.createTempFile("AddCommandTest_", "");
791 JGitTestUtil.write(f, body);
792 return f;
793 }
794 }