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 package org.eclipse.jgit.pgm;
44
45 import static org.junit.Assert.assertArrayEquals;
46 import static org.junit.Assert.assertNotNull;
47
48 import java.io.File;
49 import java.util.List;
50
51 import org.eclipse.jgit.api.Git;
52 import org.eclipse.jgit.api.errors.CheckoutConflictException;
53 import org.eclipse.jgit.diff.DiffEntry;
54 import org.eclipse.jgit.lib.CLIRepositoryTestCase;
55 import org.eclipse.jgit.lib.FileMode;
56 import org.eclipse.jgit.lib.Ref;
57 import org.eclipse.jgit.revwalk.RevCommit;
58 import org.eclipse.jgit.treewalk.FileTreeIterator;
59 import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
60 import org.eclipse.jgit.treewalk.TreeWalk;
61 import org.eclipse.jgit.util.FileUtils;
62 import org.junit.Assert;
63 import org.junit.Test;
64
65 public class CheckoutTest extends CLIRepositoryTestCase {
66
67 @Test
68 public void testCheckoutSelf() throws Exception {
69 new Git(db).commit().setMessage("initial commit").call();
70
71 assertEquals("Already on 'master'", execute("git checkout master"));
72 }
73
74 @Test
75 public void testCheckoutBranch() throws Exception {
76 new Git(db).commit().setMessage("initial commit").call();
77 new Git(db).branchCreate().setName("side").call();
78
79 assertEquals("Switched to branch 'side'", execute("git checkout side"));
80 }
81
82 @Test
83 public void testCheckoutNewBranch() throws Exception {
84 new Git(db).commit().setMessage("initial commit").call();
85
86 assertEquals("Switched to a new branch 'side'",
87 execute("git checkout -b side"));
88 }
89
90 @Test
91 public void testCheckoutNonExistingBranch() throws Exception {
92 assertEquals(
93 "error: pathspec 'side' did not match any file(s) known to git.",
94 execute("git checkout side"));
95 }
96
97 @Test
98 public void testCheckoutNewBranchThatAlreadyExists() throws Exception {
99 new Git(db).commit().setMessage("initial commit").call();
100
101 assertEquals("fatal: A branch named 'master' already exists.",
102 execute("git checkout -b master"));
103 }
104
105 @Test
106 public void testCheckoutNewBranchOnBranchToBeBorn() throws Exception {
107 assertEquals("fatal: You are on a branch yet to be born",
108 execute("git checkout -b side"));
109 }
110
111 @Test
112 public void testCheckoutUnresolvedHead() throws Exception {
113 assertEquals(
114 "error: pathspec 'HEAD' did not match any file(s) known to git.",
115 execute("git checkout HEAD"));
116 }
117
118 @Test
119 public void testCheckoutHead() throws Exception {
120 new Git(db).commit().setMessage("initial commit").call();
121
122 assertEquals("", execute("git checkout HEAD"));
123 }
124
125 @Test
126 public void testCheckoutExistingBranchWithConflict() throws Exception {
127 Git git = new Git(db);
128 writeTrashFile("a", "Hello world a");
129 git.add().addFilepattern(".").call();
130 git.commit().setMessage("commit file a").call();
131 git.branchCreate().setName("branch_1").call();
132 git.rm().addFilepattern("a").call();
133 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
134 writeTrashFile("a/b", "Hello world b");
135 git.add().addFilepattern("a/b").call();
136 git.commit().setMessage("commit folder a").call();
137 git.rm().addFilepattern("a").call();
138 writeTrashFile("a", "New Hello world a");
139 git.add().addFilepattern(".").call();
140
141 String[] execute = execute("git checkout branch_1");
142 Assert.assertEquals(
143 "error: Your local changes to the following files would be overwritten by checkout:",
144 execute[0]);
145 Assert.assertEquals("\ta", execute[1]);
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 @Test
166 public void testCheckoutWithMissingWorkingTreeFile() throws Exception {
167 Git git = new Git(db);
168 File fileA = writeTrashFile("a", "Hello world a");
169 writeTrashFile("b", "Hello world b");
170 git.add().addFilepattern(".").call();
171 git.commit().setMessage("add files a & b").call();
172 Ref branch_1 = git.branchCreate().setName("branch_1").call();
173 writeTrashFile("a", "b");
174 git.add().addFilepattern("a").call();
175 git.commit().setMessage("modify file a").call();
176
177 FileEntry entry = new FileTreeIterator.FileEntry(new File(
178 db.getWorkTree(), "a"), db.getFS());
179 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
180
181 FileUtils.delete(fileA);
182
183 git.checkout().setName(branch_1.getName()).call();
184
185 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
186 db.getFS());
187 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
188 assertEquals("Hello world a", read(fileA));
189 }
190
191 @Test
192 public void testCheckoutOrphan() throws Exception {
193 Git git = new Git(db);
194 git.commit().setMessage("initial commit").call();
195
196 assertEquals("Switched to a new branch 'new_branch'",
197 execute("git checkout --orphan new_branch"));
198 assertEquals("refs/heads/new_branch", db.getRef("HEAD").getTarget().getName());
199 RevCommit commit = git.commit().setMessage("orphan commit").call();
200 assertEquals(0, commit.getParentCount());
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 @Test
221 public void fileModeTestMissingThenFolderWithFileInWorkingTree()
222 throws Exception {
223 Git git = new Git(db);
224 writeTrashFile("b", "Hello world b");
225 git.add().addFilepattern(".").call();
226 git.commit().setMessage("add file b").call();
227 Ref branch_1 = git.branchCreate().setName("branch_1").call();
228 File folderA = new File(db.getWorkTree(), "a");
229 FileUtils.mkdirs(folderA);
230 writeTrashFile("a/c", "Hello world c");
231 git.add().addFilepattern(".").call();
232 git.commit().setMessage("add folder a").call();
233
234 FileEntry entry = new FileTreeIterator.FileEntry(new File(
235 db.getWorkTree(), "a"), db.getFS());
236 assertEquals(FileMode.TREE, entry.getMode());
237
238 FileUtils.delete(folderA, FileUtils.RECURSIVE);
239 writeTrashFile("a", "b");
240
241 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
242 db.getFS());
243 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
244
245 git.checkout().setName(branch_1.getName()).call();
246
247 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
248 db.getFS());
249 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 @Test
270 public void fileModeTestFolderWithMissingInWorkingTree() throws Exception {
271 Git git = new Git(db);
272 writeTrashFile("b", "Hello world b");
273 writeTrashFile("a", "b");
274 git.add().addFilepattern(".").call();
275 git.commit().setMessage("add file b & file a").call();
276 Ref branch_1 = git.branchCreate().setName("branch_1").call();
277 git.rm().addFilepattern("a").call();
278 File folderA = new File(db.getWorkTree(), "a");
279 FileUtils.mkdirs(folderA);
280 writeTrashFile("a/c", "Hello world c");
281 git.add().addFilepattern(".").call();
282 git.commit().setMessage("add folder a").call();
283
284 FileEntry entry = new FileTreeIterator.FileEntry(new File(
285 db.getWorkTree(), "a"), db.getFS());
286 assertEquals(FileMode.TREE, entry.getMode());
287
288 FileUtils.delete(folderA, FileUtils.RECURSIVE);
289
290 git.checkout().setName(branch_1.getName()).call();
291
292 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
293 db.getFS());
294 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314 @Test
315 public void fileModeTestMissingWithFolderInWorkingTree() throws Exception {
316 Git git = new Git(db);
317 writeTrashFile("b", "Hello world b");
318 writeTrashFile("a", "b");
319 git.add().addFilepattern(".").call();
320 git.commit().setMessage("add file b & file a").call();
321 Ref branch_1 = git.branchCreate().setName("branch_1").call();
322 git.rm().addFilepattern("a").call();
323 git.commit().setMessage("delete file a").call();
324
325 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
326 writeTrashFile("a/c", "Hello world c");
327
328 FileEntry entry = new FileTreeIterator.FileEntry(new File(
329 db.getWorkTree(), "a"), db.getFS());
330 assertEquals(FileMode.TREE, entry.getMode());
331
332 CheckoutConflictException exception = null;
333 try {
334 git.checkout().setName(branch_1.getName()).call();
335 } catch (CheckoutConflictException e) {
336 exception = e;
337 }
338 assertNotNull(exception);
339 assertEquals(2, exception.getConflictingPaths().size());
340 assertEquals("a", exception.getConflictingPaths().get(0));
341 assertEquals("a/c", exception.getConflictingPaths().get(1));
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 @Test
361 public void fileModeTestFolderThenMissingWithFileInWorkingTree()
362 throws Exception {
363 Git git = new Git(db);
364 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
365 writeTrashFile("a/c", "Hello world c");
366 writeTrashFile("b", "Hello world b");
367 git.add().addFilepattern(".").call();
368 RevCommit commit1 = git.commit().setMessage("add folder a & file b")
369 .call();
370 Ref branch_1 = git.branchCreate().setName("branch_1").call();
371 git.rm().addFilepattern("a").call();
372 RevCommit commit2 = git.commit().setMessage("delete folder a").call();
373
374 TreeWalk tw = new TreeWalk(db);
375 tw.addTree(commit1.getTree());
376 tw.addTree(commit2.getTree());
377 List<DiffEntry> scan = DiffEntry.scan(tw);
378 assertEquals(1, scan.size());
379 assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
380 assertEquals(FileMode.TREE, scan.get(0).getOldMode());
381
382 writeTrashFile("a", "b");
383
384 FileEntry entry = new FileTreeIterator.FileEntry(new File(
385 db.getWorkTree(), "a"), db.getFS());
386 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
387
388 CheckoutConflictException exception = null;
389 try {
390 git.checkout().setName(branch_1.getName()).call();
391 } catch (CheckoutConflictException e) {
392 exception = e;
393 }
394 assertNotNull(exception);
395 assertEquals(1, exception.getConflictingPaths().size());
396 assertEquals("a", exception.getConflictingPaths().get(0));
397 }
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416 @Test
417 public void fileModeTestFolderThenFileWithMissingInWorkingTree()
418 throws Exception {
419 Git git = new Git(db);
420 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
421 writeTrashFile("a/c", "Hello world c");
422 writeTrashFile("b", "Hello world b");
423 git.add().addFilepattern(".").call();
424 git.commit().setMessage("add folder a & file b").call();
425 Ref branch_1 = git.branchCreate().setName("branch_1").call();
426 git.rm().addFilepattern("a").call();
427 File fileA = new File(db.getWorkTree(), "a");
428 writeTrashFile("a", "b");
429 git.add().addFilepattern("a").call();
430 git.commit().setMessage("add file a").call();
431
432 FileEntry entry = new FileTreeIterator.FileEntry(new File(
433 db.getWorkTree(), "a"), db.getFS());
434 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
435
436 FileUtils.delete(fileA);
437
438 git.checkout().setName(branch_1.getName()).call();
439
440 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
441 db.getFS());
442 assertEquals(FileMode.TREE, entry.getMode());
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 @Test
462 public void fileModeTestFileThenFileWithFolderInIndex() throws Exception {
463 Git git = new Git(db);
464 writeTrashFile("a", "Hello world a");
465 writeTrashFile("b", "Hello world b");
466 git.add().addFilepattern(".").call();
467 git.commit().setMessage("add files a & b").call();
468 Ref branch_1 = git.branchCreate().setName("branch_1").call();
469 writeTrashFile("a", "b");
470 git.add().addFilepattern("a").call();
471 git.commit().setMessage("add file a").call();
472
473 FileEntry entry = new FileTreeIterator.FileEntry(new File(
474 db.getWorkTree(), "a"), db.getFS());
475 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
476
477 git.rm().addFilepattern("a").call();
478 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
479 writeTrashFile("a/c", "Hello world c");
480 git.add().addFilepattern(".").call();
481
482 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
483 db.getFS());
484 assertEquals(FileMode.TREE, entry.getMode());
485
486 CheckoutConflictException exception = null;
487 try {
488 git.checkout().setName(branch_1.getName()).call();
489 } catch (CheckoutConflictException e) {
490 exception = e;
491 }
492 assertNotNull(exception);
493 assertEquals(1, exception.getConflictingPaths().size());
494 assertEquals("a", exception.getConflictingPaths().get(0));
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514 @Test
515 public void fileModeTestFileWithFolderInIndex() throws Exception {
516 Git git = new Git(db);
517 writeTrashFile("b", "Hello world b");
518 writeTrashFile("a", "b");
519 git.add().addFilepattern(".").call();
520 git.commit().setMessage("add file b & file a").call();
521 Ref branch_1 = git.branchCreate().setName("branch_1").call();
522 git.rm().addFilepattern("a").call();
523 writeTrashFile("a", "Hello world a");
524 git.add().addFilepattern("a").call();
525 git.commit().setMessage("add file a").call();
526
527 FileEntry entry = new FileTreeIterator.FileEntry(new File(
528 db.getWorkTree(), "a"), db.getFS());
529 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
530
531 git.rm().addFilepattern("a").call();
532 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
533 writeTrashFile("a/c", "Hello world c");
534 git.add().addFilepattern(".").call();
535
536 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
537 db.getFS());
538 assertEquals(FileMode.TREE, entry.getMode());
539
540 CheckoutConflictException exception = null;
541 try {
542 git.checkout().setName(branch_1.getName()).call();
543 } catch (CheckoutConflictException e) {
544 exception = e;
545 }
546 assertNotNull(exception);
547 assertEquals(1, exception.getConflictingPaths().size());
548 assertEquals("a", exception.getConflictingPaths().get(0));
549
550
551
552
553
554 }
555
556 static private void assertEquals(Object expected, Object actual) {
557 Assert.assertEquals(expected, actual);
558 }
559
560 static private void assertEquals(String expected, String[] actual) {
561
562 Assert.assertEquals(
563 1,
564 actual.length > 1 && actual[actual.length - 1].equals("") ? actual.length - 1
565 : actual.length);
566 Assert.assertEquals(expected, actual[0]);
567 }
568
569 @Test
570 public void testCheckoutPath() throws Exception {
571 Git git = new Git(db);
572 writeTrashFile("a", "Hello world a");
573 git.add().addFilepattern(".").call();
574 git.commit().setMessage("commit file a").call();
575 git.branchCreate().setName("branch_1").call();
576 git.checkout().setName("branch_1").call();
577 File b = writeTrashFile("b", "Hello world b");
578 git.add().addFilepattern("b").call();
579 git.commit().setMessage("commit file b").call();
580 File a = writeTrashFile("a", "New Hello world a");
581 git.add().addFilepattern(".").call();
582 git.commit().setMessage("modified a").call();
583 assertArrayEquals(new String[] { "" },
584 execute("git checkout HEAD~2 -- a"));
585 assertEquals("Hello world a", read(a));
586 assertArrayEquals(new String[] { "* branch_1", " master", "" },
587 execute("git branch"));
588 assertEquals("Hello world b", read(b));
589 }
590 }