You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CheckoutTest.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. * Copyright (C) 2012, IBM Corporation
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.pgm;
  44. import static org.junit.Assert.assertArrayEquals;
  45. import static org.junit.Assert.assertEquals;
  46. import static org.junit.Assert.assertFalse;
  47. import static org.junit.Assert.assertNotNull;
  48. import static org.junit.Assert.assertTrue;
  49. import java.io.File;
  50. import java.nio.file.Files;
  51. import java.nio.file.Path;
  52. import java.util.Arrays;
  53. import java.util.List;
  54. import org.eclipse.jgit.api.Git;
  55. import org.eclipse.jgit.api.errors.CheckoutConflictException;
  56. import org.eclipse.jgit.diff.DiffEntry;
  57. import org.eclipse.jgit.lib.CLIRepositoryTestCase;
  58. import org.eclipse.jgit.lib.FileMode;
  59. import org.eclipse.jgit.lib.Ref;
  60. import org.eclipse.jgit.revwalk.RevCommit;
  61. import org.eclipse.jgit.treewalk.FileTreeIterator;
  62. import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
  63. import org.eclipse.jgit.treewalk.TreeWalk;
  64. import org.eclipse.jgit.util.FS;
  65. import org.eclipse.jgit.util.FileUtils;
  66. import org.junit.Assume;
  67. import org.junit.Test;
  68. public class CheckoutTest extends CLIRepositoryTestCase {
  69. @Test
  70. public void testCheckoutSelf() throws Exception {
  71. new Git(db).commit().setMessage("initial commit").call();
  72. assertStringArrayEquals("Already on 'master'",
  73. execute("git checkout master"));
  74. }
  75. @Test
  76. public void testCheckoutBranch() throws Exception {
  77. new Git(db).commit().setMessage("initial commit").call();
  78. new Git(db).branchCreate().setName("side").call();
  79. assertStringArrayEquals("Switched to branch 'side'",
  80. execute("git checkout side"));
  81. }
  82. @Test
  83. public void testCheckoutNewBranch() throws Exception {
  84. new Git(db).commit().setMessage("initial commit").call();
  85. assertStringArrayEquals("Switched to a new branch 'side'",
  86. execute("git checkout -b side"));
  87. }
  88. @Test
  89. public void testCheckoutNonExistingBranch() throws Exception {
  90. assertStringArrayEquals(
  91. "error: pathspec 'side' did not match any file(s) known to git.",
  92. execute("git checkout side"));
  93. }
  94. @Test
  95. public void testCheckoutNewBranchThatAlreadyExists() throws Exception {
  96. new Git(db).commit().setMessage("initial commit").call();
  97. assertStringArrayEquals(
  98. "fatal: A branch named 'master' already exists.",
  99. executeUnchecked("git checkout -b master"));
  100. }
  101. @Test
  102. public void testCheckoutNewBranchOnBranchToBeBorn() throws Exception {
  103. assertStringArrayEquals("fatal: You are on a branch yet to be born",
  104. executeUnchecked("git checkout -b side"));
  105. }
  106. @Test
  107. public void testCheckoutUnresolvedHead() throws Exception {
  108. assertStringArrayEquals(
  109. "error: pathspec 'HEAD' did not match any file(s) known to git.",
  110. execute("git checkout HEAD"));
  111. }
  112. @Test
  113. public void testCheckoutHead() throws Exception {
  114. new Git(db).commit().setMessage("initial commit").call();
  115. assertStringArrayEquals("", execute("git checkout HEAD"));
  116. }
  117. @Test
  118. public void testCheckoutExistingBranchWithConflict() throws Exception {
  119. Git git = new Git(db);
  120. writeTrashFile("a", "Hello world a");
  121. git.add().addFilepattern(".").call();
  122. git.commit().setMessage("commit file a").call();
  123. git.branchCreate().setName("branch_1").call();
  124. git.rm().addFilepattern("a").call();
  125. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  126. writeTrashFile("a/b", "Hello world b");
  127. git.add().addFilepattern("a/b").call();
  128. git.commit().setMessage("commit folder a").call();
  129. git.rm().addFilepattern("a").call();
  130. writeTrashFile("a", "New Hello world a");
  131. git.add().addFilepattern(".").call();
  132. String[] execute = execute("git checkout branch_1");
  133. assertEquals(
  134. "error: Your local changes to the following files would be overwritten by checkout:",
  135. execute[0]);
  136. assertEquals("\ta", execute[1]);
  137. }
  138. /**
  139. * Steps:
  140. * <ol>
  141. * <li>Add file 'a' and 'b'
  142. * <li>Commit
  143. * <li>Create branch '1'
  144. * <li>modify file 'a'
  145. * <li>Commit
  146. * <li>Delete file 'a' in the working tree
  147. * <li>Checkout branch '1'
  148. * </ol>
  149. * <p>
  150. * The working tree should contain 'a' with FileMode.REGULAR_FILE after the
  151. * checkout.
  152. *
  153. * @throws Exception
  154. */
  155. @Test
  156. public void testCheckoutWithMissingWorkingTreeFile() throws Exception {
  157. Git git = new Git(db);
  158. File fileA = writeTrashFile("a", "Hello world a");
  159. writeTrashFile("b", "Hello world b");
  160. git.add().addFilepattern(".").call();
  161. git.commit().setMessage("add files a & b").call();
  162. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  163. writeTrashFile("a", "b");
  164. git.add().addFilepattern("a").call();
  165. git.commit().setMessage("modify file a").call();
  166. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  167. db.getWorkTree(), "a"), db.getFS());
  168. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  169. FileUtils.delete(fileA);
  170. git.checkout().setName(branch_1.getName()).call();
  171. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  172. db.getFS());
  173. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  174. assertEquals("Hello world a", read(fileA));
  175. }
  176. @Test
  177. public void testCheckoutOrphan() throws Exception {
  178. Git git = new Git(db);
  179. git.commit().setMessage("initial commit").call();
  180. assertStringArrayEquals("Switched to a new branch 'new_branch'",
  181. execute("git checkout --orphan new_branch"));
  182. assertEquals("refs/heads/new_branch",
  183. db.exactRef("HEAD").getTarget().getName());
  184. RevCommit commit = git.commit().setMessage("orphan commit").call();
  185. assertEquals(0, commit.getParentCount());
  186. }
  187. /**
  188. * Steps:
  189. * <ol>
  190. * <li>Add file 'b'
  191. * <li>Commit
  192. * <li>Create branch '1'
  193. * <li>Add folder 'a'
  194. * <li>Commit
  195. * <li>Replace folder 'a' by file 'a' in the working tree
  196. * <li>Checkout branch '1'
  197. * </ol>
  198. * <p>
  199. * The working tree should contain 'a' with FileMode.REGULAR_FILE after the
  200. * checkout.
  201. *
  202. * @throws Exception
  203. */
  204. @Test
  205. public void fileModeTestMissingThenFolderWithFileInWorkingTree()
  206. throws Exception {
  207. Git git = new Git(db);
  208. writeTrashFile("b", "Hello world b");
  209. git.add().addFilepattern(".").call();
  210. git.commit().setMessage("add file b").call();
  211. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  212. File folderA = new File(db.getWorkTree(), "a");
  213. FileUtils.mkdirs(folderA);
  214. writeTrashFile("a/c", "Hello world c");
  215. git.add().addFilepattern(".").call();
  216. git.commit().setMessage("add folder a").call();
  217. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  218. db.getWorkTree(), "a"), db.getFS());
  219. assertEquals(FileMode.TREE, entry.getMode());
  220. FileUtils.delete(folderA, FileUtils.RECURSIVE);
  221. writeTrashFile("a", "b");
  222. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  223. db.getFS());
  224. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  225. git.checkout().setName(branch_1.getName()).call();
  226. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  227. db.getFS());
  228. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  229. }
  230. /**
  231. * Steps:
  232. * <ol>
  233. * <li>Add file 'a'
  234. * <li>Commit
  235. * <li>Create branch '1'
  236. * <li>Replace file 'a' by folder 'a'
  237. * <li>Commit
  238. * <li>Delete folder 'a' in the working tree
  239. * <li>Checkout branch '1'
  240. * </ol>
  241. * <p>
  242. * The working tree should contain 'a' with FileMode.REGULAR_FILE after the
  243. * checkout.
  244. *
  245. * @throws Exception
  246. */
  247. @Test
  248. public void fileModeTestFolderWithMissingInWorkingTree() throws Exception {
  249. Git git = new Git(db);
  250. writeTrashFile("b", "Hello world b");
  251. writeTrashFile("a", "b");
  252. git.add().addFilepattern(".").call();
  253. git.commit().setMessage("add file b & file a").call();
  254. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  255. git.rm().addFilepattern("a").call();
  256. File folderA = new File(db.getWorkTree(), "a");
  257. FileUtils.mkdirs(folderA);
  258. writeTrashFile("a/c", "Hello world c");
  259. git.add().addFilepattern(".").call();
  260. git.commit().setMessage("add folder a").call();
  261. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  262. db.getWorkTree(), "a"), db.getFS());
  263. assertEquals(FileMode.TREE, entry.getMode());
  264. FileUtils.delete(folderA, FileUtils.RECURSIVE);
  265. git.checkout().setName(branch_1.getName()).call();
  266. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  267. db.getFS());
  268. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  269. }
  270. /**
  271. * Steps:
  272. * <ol>
  273. * <li>Add file 'a'
  274. * <li>Commit
  275. * <li>Create branch '1'
  276. * <li>Delete file 'a'
  277. * <li>Commit
  278. * <li>Add folder 'a' in the working tree
  279. * <li>Checkout branch '1'
  280. * </ol>
  281. * <p>
  282. * The checkout command should raise an error. The conflicting paths are 'a'
  283. * and 'a/c'.
  284. *
  285. * @throws Exception
  286. */
  287. @Test
  288. public void fileModeTestMissingWithFolderInWorkingTree() throws Exception {
  289. Git git = new Git(db);
  290. writeTrashFile("b", "Hello world b");
  291. writeTrashFile("a", "b");
  292. git.add().addFilepattern(".").call();
  293. git.commit().setMessage("add file b & file a").call();
  294. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  295. git.rm().addFilepattern("a").call();
  296. git.commit().setMessage("delete file a").call();
  297. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  298. writeTrashFile("a/c", "Hello world c");
  299. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  300. db.getWorkTree(), "a"), db.getFS());
  301. assertEquals(FileMode.TREE, entry.getMode());
  302. CheckoutConflictException exception = null;
  303. try {
  304. git.checkout().setName(branch_1.getName()).call();
  305. } catch (CheckoutConflictException e) {
  306. exception = e;
  307. }
  308. assertNotNull(exception);
  309. assertEquals(2, exception.getConflictingPaths().size());
  310. assertEquals("a", exception.getConflictingPaths().get(0));
  311. assertEquals("a/c", exception.getConflictingPaths().get(1));
  312. }
  313. /**
  314. * Steps:
  315. * <ol>
  316. * <li>Add folder 'a'
  317. * <li>Commit
  318. * <li>Create branch '1'
  319. * <li>Delete folder 'a'
  320. * <li>Commit
  321. * <li>Add file 'a' in the working tree
  322. * <li>Checkout branch '1'
  323. * </ol>
  324. * <p>
  325. * The checkout command should raise an error. The conflicting path is 'a'.
  326. *
  327. * @throws Exception
  328. */
  329. @Test
  330. public void fileModeTestFolderThenMissingWithFileInWorkingTree()
  331. throws Exception {
  332. Git git = new Git(db);
  333. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  334. writeTrashFile("a/c", "Hello world c");
  335. writeTrashFile("b", "Hello world b");
  336. git.add().addFilepattern(".").call();
  337. RevCommit commit1 = git.commit().setMessage("add folder a & file b")
  338. .call();
  339. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  340. git.rm().addFilepattern("a").call();
  341. RevCommit commit2 = git.commit().setMessage("delete folder a").call();
  342. TreeWalk tw = new TreeWalk(db);
  343. tw.addTree(commit1.getTree());
  344. tw.addTree(commit2.getTree());
  345. List<DiffEntry> scan = DiffEntry.scan(tw);
  346. assertEquals(1, scan.size());
  347. assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
  348. assertEquals(FileMode.TREE, scan.get(0).getOldMode());
  349. writeTrashFile("a", "b");
  350. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  351. db.getWorkTree(), "a"), db.getFS());
  352. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  353. CheckoutConflictException exception = null;
  354. try {
  355. git.checkout().setName(branch_1.getName()).call();
  356. } catch (CheckoutConflictException e) {
  357. exception = e;
  358. }
  359. assertNotNull(exception);
  360. assertEquals(1, exception.getConflictingPaths().size());
  361. assertEquals("a", exception.getConflictingPaths().get(0));
  362. }
  363. /**
  364. * Steps:
  365. * <ol>
  366. * <li>Add folder 'a'
  367. * <li>Commit
  368. * <li>Create branch '1'
  369. * <li>Replace folder 'a'by file 'a'
  370. * <li>Commit
  371. * <li>Delete file 'a' in the working tree
  372. * <li>Checkout branch '1'
  373. * </ol>
  374. * <p>
  375. * The working tree should contain 'a' with FileMode.TREE after the
  376. * checkout.
  377. *
  378. * @throws Exception
  379. */
  380. @Test
  381. public void fileModeTestFolderThenFileWithMissingInWorkingTree()
  382. throws Exception {
  383. Git git = new Git(db);
  384. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  385. writeTrashFile("a/c", "Hello world c");
  386. writeTrashFile("b", "Hello world b");
  387. git.add().addFilepattern(".").call();
  388. git.commit().setMessage("add folder a & file b").call();
  389. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  390. git.rm().addFilepattern("a").call();
  391. File fileA = new File(db.getWorkTree(), "a");
  392. writeTrashFile("a", "b");
  393. git.add().addFilepattern("a").call();
  394. git.commit().setMessage("add file a").call();
  395. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  396. db.getWorkTree(), "a"), db.getFS());
  397. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  398. FileUtils.delete(fileA);
  399. git.checkout().setName(branch_1.getName()).call();
  400. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  401. db.getFS());
  402. assertEquals(FileMode.TREE, entry.getMode());
  403. }
  404. /**
  405. * Steps:
  406. * <ol>
  407. * <li>Add file 'a'
  408. * <li>Commit
  409. * <li>Create branch '1'
  410. * <li>Modify file 'a'
  411. * <li>Commit
  412. * <li>Delete file 'a' & replace by folder 'a' in the working tree & index
  413. * <li>Checkout branch '1'
  414. * </ol>
  415. * <p>
  416. * The checkout command should raise an error. The conflicting path is 'a'.
  417. *
  418. * @throws Exception
  419. */
  420. @Test
  421. public void fileModeTestFileThenFileWithFolderInIndex() throws Exception {
  422. Git git = new Git(db);
  423. writeTrashFile("a", "Hello world a");
  424. writeTrashFile("b", "Hello world b");
  425. git.add().addFilepattern(".").call();
  426. git.commit().setMessage("add files a & b").call();
  427. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  428. writeTrashFile("a", "b");
  429. git.add().addFilepattern("a").call();
  430. git.commit().setMessage("add file a").call();
  431. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  432. db.getWorkTree(), "a"), db.getFS());
  433. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  434. git.rm().addFilepattern("a").call();
  435. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  436. writeTrashFile("a/c", "Hello world c");
  437. git.add().addFilepattern(".").call();
  438. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  439. db.getFS());
  440. assertEquals(FileMode.TREE, entry.getMode());
  441. CheckoutConflictException exception = null;
  442. try {
  443. git.checkout().setName(branch_1.getName()).call();
  444. } catch (CheckoutConflictException e) {
  445. exception = e;
  446. }
  447. assertNotNull(exception);
  448. assertEquals(1, exception.getConflictingPaths().size());
  449. assertEquals("a", exception.getConflictingPaths().get(0));
  450. }
  451. /**
  452. * Steps:
  453. * <ol>
  454. * <li>Add file 'a'
  455. * <li>Commit
  456. * <li>Create branch '1'
  457. * <li>Modify file 'a'
  458. * <li>Commit
  459. * <li>Delete file 'a' & replace by folder 'a' in the working tree & index
  460. * <li>Checkout branch '1'
  461. * </ol>
  462. * <p>
  463. * The checkout command should raise an error. The conflicting paths are 'a'
  464. * and 'a/c'.
  465. *
  466. * @throws Exception
  467. */
  468. @Test
  469. public void fileModeTestFileWithFolderInIndex() throws Exception {
  470. Git git = new Git(db);
  471. writeTrashFile("b", "Hello world b");
  472. writeTrashFile("a", "b");
  473. git.add().addFilepattern(".").call();
  474. git.commit().setMessage("add file b & file a").call();
  475. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  476. git.rm().addFilepattern("a").call();
  477. writeTrashFile("a", "Hello world a");
  478. git.add().addFilepattern("a").call();
  479. git.commit().setMessage("add file a").call();
  480. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  481. db.getWorkTree(), "a"), db.getFS());
  482. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  483. git.rm().addFilepattern("a").call();
  484. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  485. writeTrashFile("a/c", "Hello world c");
  486. git.add().addFilepattern(".").call();
  487. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  488. db.getFS());
  489. assertEquals(FileMode.TREE, entry.getMode());
  490. CheckoutConflictException exception = null;
  491. try {
  492. git.checkout().setName(branch_1.getName()).call();
  493. } catch (CheckoutConflictException e) {
  494. exception = e;
  495. }
  496. assertNotNull(exception);
  497. assertEquals(1, exception.getConflictingPaths().size());
  498. assertEquals("a", exception.getConflictingPaths().get(0));
  499. // TODO: ideally we'd like to get two paths from this exception
  500. // assertEquals(2, exception.getConflictingPaths().size());
  501. // assertEquals("a", exception.getConflictingPaths().get(0));
  502. // assertEquals("a/c", exception.getConflictingPaths().get(1));
  503. }
  504. @Test
  505. public void testCheckoutPath() throws Exception {
  506. Git git = new Git(db);
  507. writeTrashFile("a", "Hello world a");
  508. git.add().addFilepattern(".").call();
  509. git.commit().setMessage("commit file a").call();
  510. git.branchCreate().setName("branch_1").call();
  511. git.checkout().setName("branch_1").call();
  512. File b = writeTrashFile("b", "Hello world b");
  513. git.add().addFilepattern("b").call();
  514. git.commit().setMessage("commit file b").call();
  515. File a = writeTrashFile("a", "New Hello world a");
  516. git.add().addFilepattern(".").call();
  517. git.commit().setMessage("modified a").call();
  518. assertArrayEquals(new String[] { "" },
  519. execute("git checkout HEAD~2 -- a"));
  520. assertEquals("Hello world a", read(a));
  521. assertArrayEquals(new String[] { "* branch_1", " master", "" },
  522. execute("git branch"));
  523. assertEquals("Hello world b", read(b));
  524. }
  525. @Test
  526. public void testCheckouSingleFile() throws Exception {
  527. try (Git git = new Git(db)) {
  528. File a = writeTrashFile("a", "file a");
  529. git.add().addFilepattern(".").call();
  530. git.commit().setMessage("commit file a").call();
  531. writeTrashFile("a", "b");
  532. assertEquals("b", read(a));
  533. assertEquals("[]", Arrays.toString(execute("git checkout -- a")));
  534. assertEquals("file a", read(a));
  535. }
  536. }
  537. @Test
  538. public void testCheckoutLink() throws Exception {
  539. Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
  540. try (Git git = new Git(db)) {
  541. Path path = writeLink("a", "link_a");
  542. assertTrue(Files.isSymbolicLink(path));
  543. git.add().addFilepattern(".").call();
  544. git.commit().setMessage("commit link a").call();
  545. deleteTrashFile("a");
  546. writeTrashFile("a", "Hello world a");
  547. assertFalse(Files.isSymbolicLink(path));
  548. assertEquals("[]", Arrays.toString(execute("git checkout -- a")));
  549. assertEquals("link_a", FileUtils.readSymLink(path.toFile()));
  550. assertTrue(Files.isSymbolicLink(path));
  551. }
  552. }
  553. }