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 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * Copyright (C) 2012, IBM Corporation and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.pgm;
  11. import static org.junit.Assert.assertArrayEquals;
  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.assertTrue;
  16. import static org.junit.Assert.fail;
  17. import java.io.File;
  18. import java.nio.file.Files;
  19. import java.nio.file.Path;
  20. import java.util.Arrays;
  21. import java.util.List;
  22. import org.eclipse.jgit.api.Git;
  23. import org.eclipse.jgit.api.errors.CheckoutConflictException;
  24. import org.eclipse.jgit.diff.DiffEntry;
  25. import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
  26. import org.eclipse.jgit.lib.CLIRepositoryTestCase;
  27. import org.eclipse.jgit.lib.FileMode;
  28. import org.eclipse.jgit.lib.Ref;
  29. import org.eclipse.jgit.revwalk.RevCommit;
  30. import org.eclipse.jgit.treewalk.FileTreeIterator;
  31. import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
  32. import org.eclipse.jgit.treewalk.TreeWalk;
  33. import org.eclipse.jgit.util.FS;
  34. import org.eclipse.jgit.util.FileUtils;
  35. import org.junit.Assume;
  36. import org.junit.Test;
  37. public class CheckoutTest extends CLIRepositoryTestCase {
  38. /**
  39. * Executes specified git command (with arguments), captures exception and
  40. * returns its message as an array of lines. Throws an AssertionError if no
  41. * exception is thrown.
  42. *
  43. * @param command
  44. * a valid git command line, e.g. "git branch -h"
  45. * @return message contained within the exception
  46. */
  47. private String[] executeExpectingException(String command) {
  48. try {
  49. execute(command);
  50. throw new AssertionError("Expected Die");
  51. } catch (Exception e) {
  52. return e.getMessage().split(System.lineSeparator());
  53. }
  54. }
  55. @Test
  56. public void testCheckoutSelf() throws Exception {
  57. try (Git git = new Git(db)) {
  58. git.commit().setMessage("initial commit").call();
  59. assertStringArrayEquals("Already on 'master'",
  60. execute("git checkout master"));
  61. }
  62. }
  63. @Test
  64. public void testCheckoutBranch() throws Exception {
  65. try (Git git = new Git(db)) {
  66. git.commit().setMessage("initial commit").call();
  67. git.branchCreate().setName("side").call();
  68. assertStringArrayEquals("Switched to branch 'side'",
  69. execute("git checkout side"));
  70. }
  71. }
  72. @Test
  73. public void testCheckoutNewBranch() throws Exception {
  74. try (Git git = new Git(db)) {
  75. git.commit().setMessage("initial commit").call();
  76. assertStringArrayEquals("Switched to a new branch 'side'",
  77. execute("git checkout -b side"));
  78. }
  79. }
  80. @Test
  81. public void testCheckoutNonExistingBranch() throws Exception {
  82. assertStringArrayEquals(
  83. "error: pathspec 'side' did not match any file(s) known to git.",
  84. executeExpectingException("git checkout side"));
  85. }
  86. @Test
  87. public void testCheckoutNewBranchThatAlreadyExists() throws Exception {
  88. try (Git git = new Git(db)) {
  89. git.commit().setMessage("initial commit").call();
  90. assertStringArrayEquals(
  91. "fatal: A branch named 'master' already exists.",
  92. executeUnchecked("git checkout -b master"));
  93. }
  94. }
  95. @Test
  96. public void testCheckoutNewBranchOnBranchToBeBorn() throws Exception {
  97. assertStringArrayEquals("fatal: You are on a branch yet to be born",
  98. executeUnchecked("git checkout -b side"));
  99. }
  100. @Test
  101. public void testCheckoutUnresolvedHead() throws Exception {
  102. assertStringArrayEquals(
  103. "error: pathspec 'HEAD' did not match any file(s) known to git.",
  104. executeExpectingException("git checkout HEAD"));
  105. }
  106. @Test
  107. public void testCheckoutHead() throws Exception {
  108. try (Git git = new Git(db)) {
  109. git.commit().setMessage("initial commit").call();
  110. assertStringArrayEquals("", execute("git checkout HEAD"));
  111. }
  112. }
  113. @Test
  114. public void testCheckoutExistingBranchWithConflict() throws Exception {
  115. try (Git git = new Git(db)) {
  116. writeTrashFile("a", "Hello world a");
  117. git.add().addFilepattern(".").call();
  118. git.commit().setMessage("commit file a").call();
  119. git.branchCreate().setName("branch_1").call();
  120. git.rm().addFilepattern("a").call();
  121. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  122. writeTrashFile("a/b", "Hello world b");
  123. git.add().addFilepattern("a/b").call();
  124. git.commit().setMessage("commit folder a").call();
  125. git.rm().addFilepattern("a").call();
  126. writeTrashFile("a", "New Hello world a");
  127. git.add().addFilepattern(".").call();
  128. String[] execute = executeExpectingException(
  129. "git checkout branch_1");
  130. assertEquals(
  131. "error: Your local changes to the following files would be overwritten by checkout:",
  132. execute[0]);
  133. assertEquals("\ta", execute[1]);
  134. }
  135. }
  136. /**
  137. * Steps:
  138. * <ol>
  139. * <li>Add file 'a' and 'b'
  140. * <li>Commit
  141. * <li>Create branch '1'
  142. * <li>modify file 'a'
  143. * <li>Commit
  144. * <li>Delete file 'a' in the working tree
  145. * <li>Checkout branch '1'
  146. * </ol>
  147. * <p>
  148. * The working tree should contain 'a' with FileMode.REGULAR_FILE after the
  149. * checkout.
  150. *
  151. * @throws Exception
  152. */
  153. @Test
  154. public void testCheckoutWithMissingWorkingTreeFile() throws Exception {
  155. try (Git git = new Git(db)) {
  156. File fileA = writeTrashFile("a", "Hello world a");
  157. writeTrashFile("b", "Hello world b");
  158. git.add().addFilepattern(".").call();
  159. git.commit().setMessage("add files a & b").call();
  160. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  161. writeTrashFile("a", "b");
  162. git.add().addFilepattern("a").call();
  163. git.commit().setMessage("modify file a").call();
  164. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  165. db.getWorkTree(), "a"), db.getFS());
  166. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  167. FileUtils.delete(fileA);
  168. git.checkout().setName(branch_1.getName()).call();
  169. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  170. db.getFS());
  171. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  172. assertEquals("Hello world a", read(fileA));
  173. }
  174. }
  175. @Test
  176. public void testCheckoutOrphan() throws Exception {
  177. try (Git git = new Git(db)) {
  178. git.commit().setMessage("initial commit").call();
  179. assertStringArrayEquals("Switched to a new branch 'new_branch'",
  180. execute("git checkout --orphan new_branch"));
  181. assertEquals("refs/heads/new_branch",
  182. db.exactRef("HEAD").getTarget().getName());
  183. RevCommit commit = git.commit().setMessage("orphan commit").call();
  184. assertEquals(0, commit.getParentCount());
  185. }
  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 checkout has to delete folder but the workingtree contains a dirty
  200. * file at this path. The checkout should fail like in native git.
  201. *
  202. * @throws Exception
  203. */
  204. @Test
  205. public void fileModeTestMissingThenFolderWithFileInWorkingTree()
  206. throws Exception {
  207. try (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. try {
  226. git.checkout().setName(branch_1.getName()).call();
  227. fail("Don't get the expected conflict");
  228. } catch (CheckoutConflictException e) {
  229. assertEquals("[a]", e.getConflictingPaths().toString());
  230. entry = new FileTreeIterator.FileEntry(
  231. new File(db.getWorkTree(), "a"), db.getFS());
  232. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  233. }
  234. }
  235. }
  236. /**
  237. * Steps:
  238. * <ol>
  239. * <li>Add file 'a'
  240. * <li>Commit
  241. * <li>Create branch '1'
  242. * <li>Replace file 'a' by folder 'a'
  243. * <li>Commit
  244. * <li>Delete folder 'a' in the working tree
  245. * <li>Checkout branch '1'
  246. * </ol>
  247. * <p>
  248. * The working tree should contain 'a' with FileMode.REGULAR_FILE after the
  249. * checkout.
  250. *
  251. * @throws Exception
  252. */
  253. @Test
  254. public void fileModeTestFolderWithMissingInWorkingTree() throws Exception {
  255. try (Git git = new Git(db)) {
  256. writeTrashFile("b", "Hello world b");
  257. writeTrashFile("a", "b");
  258. git.add().addFilepattern(".").call();
  259. git.commit().setMessage("add file b & file a").call();
  260. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  261. git.rm().addFilepattern("a").call();
  262. File folderA = new File(db.getWorkTree(), "a");
  263. FileUtils.mkdirs(folderA);
  264. writeTrashFile("a/c", "Hello world c");
  265. git.add().addFilepattern(".").call();
  266. git.commit().setMessage("add folder a").call();
  267. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  268. db.getWorkTree(), "a"), db.getFS());
  269. assertEquals(FileMode.TREE, entry.getMode());
  270. FileUtils.delete(folderA, FileUtils.RECURSIVE);
  271. git.checkout().setName(branch_1.getName()).call();
  272. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  273. db.getFS());
  274. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  275. }
  276. }
  277. /**
  278. * Steps:
  279. * <ol>
  280. * <li>Add file 'a'
  281. * <li>Commit
  282. * <li>Create branch '1'
  283. * <li>Delete file 'a'
  284. * <li>Commit
  285. * <li>Add folder 'a' in the working tree
  286. * <li>Checkout branch '1'
  287. * </ol>
  288. * <p>
  289. * The checkout command should raise an error. The conflicting paths are 'a'
  290. * and 'a/c'.
  291. *
  292. * @throws Exception
  293. */
  294. @Test
  295. public void fileModeTestMissingWithFolderInWorkingTree() throws Exception {
  296. try (Git git = new Git(db)) {
  297. writeTrashFile("b", "Hello world b");
  298. writeTrashFile("a", "b");
  299. git.add().addFilepattern(".").call();
  300. git.commit().setMessage("add file b & file a").call();
  301. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  302. git.rm().addFilepattern("a").call();
  303. git.commit().setMessage("delete file a").call();
  304. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  305. writeTrashFile("a/c", "Hello world c");
  306. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  307. db.getWorkTree(), "a"), db.getFS());
  308. assertEquals(FileMode.TREE, entry.getMode());
  309. CheckoutConflictException exception = null;
  310. try {
  311. git.checkout().setName(branch_1.getName()).call();
  312. } catch (CheckoutConflictException e) {
  313. exception = e;
  314. }
  315. assertNotNull(exception);
  316. assertEquals(2, exception.getConflictingPaths().size());
  317. assertEquals("a", exception.getConflictingPaths().get(0));
  318. assertEquals("a/c", exception.getConflictingPaths().get(1));
  319. }
  320. }
  321. /**
  322. * Steps:
  323. * <ol>
  324. * <li>Add folder 'a'
  325. * <li>Commit
  326. * <li>Create branch '1'
  327. * <li>Delete folder 'a'
  328. * <li>Commit
  329. * <li>Add file 'a' in the working tree
  330. * <li>Checkout branch '1'
  331. * </ol>
  332. * <p>
  333. * The checkout command should raise an error. The conflicting path is 'a'.
  334. *
  335. * @throws Exception
  336. */
  337. @Test
  338. public void fileModeTestFolderThenMissingWithFileInWorkingTree()
  339. throws Exception {
  340. try (Git git = new Git(db)) {
  341. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  342. writeTrashFile("a/c", "Hello world c");
  343. writeTrashFile("b", "Hello world b");
  344. git.add().addFilepattern(".").call();
  345. RevCommit commit1 = git.commit().setMessage("add folder a & file b")
  346. .call();
  347. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  348. git.rm().addFilepattern("a").call();
  349. RevCommit commit2 = git.commit().setMessage("delete folder a").call();
  350. TreeWalk tw = new TreeWalk(db);
  351. tw.addTree(commit1.getTree());
  352. tw.addTree(commit2.getTree());
  353. List<DiffEntry> scan = DiffEntry.scan(tw);
  354. assertEquals(1, scan.size());
  355. assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
  356. assertEquals(FileMode.TREE, scan.get(0).getOldMode());
  357. writeTrashFile("a", "b");
  358. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  359. db.getWorkTree(), "a"), db.getFS());
  360. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  361. CheckoutConflictException exception = null;
  362. try {
  363. git.checkout().setName(branch_1.getName()).call();
  364. } catch (CheckoutConflictException e) {
  365. exception = e;
  366. }
  367. assertNotNull(exception);
  368. assertEquals(1, exception.getConflictingPaths().size());
  369. assertEquals("a", exception.getConflictingPaths().get(0));
  370. }
  371. }
  372. /**
  373. * Steps:
  374. * <ol>
  375. * <li>Add folder 'a'
  376. * <li>Commit
  377. * <li>Create branch '1'
  378. * <li>Replace folder 'a'by file 'a'
  379. * <li>Commit
  380. * <li>Delete file 'a' in the working tree
  381. * <li>Checkout branch '1'
  382. * </ol>
  383. * <p>
  384. * The working tree should contain 'a' with FileMode.TREE after the
  385. * checkout.
  386. *
  387. * @throws Exception
  388. */
  389. @Test
  390. public void fileModeTestFolderThenFileWithMissingInWorkingTree()
  391. throws Exception {
  392. try (Git git = new Git(db)) {
  393. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  394. writeTrashFile("a/c", "Hello world c");
  395. writeTrashFile("b", "Hello world b");
  396. git.add().addFilepattern(".").call();
  397. git.commit().setMessage("add folder a & file b").call();
  398. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  399. git.rm().addFilepattern("a").call();
  400. File fileA = new File(db.getWorkTree(), "a");
  401. writeTrashFile("a", "b");
  402. git.add().addFilepattern("a").call();
  403. git.commit().setMessage("add file a").call();
  404. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  405. db.getWorkTree(), "a"), db.getFS());
  406. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  407. FileUtils.delete(fileA);
  408. git.checkout().setName(branch_1.getName()).call();
  409. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  410. db.getFS());
  411. assertEquals(FileMode.TREE, entry.getMode());
  412. }
  413. }
  414. /**
  415. * Steps:
  416. * <ol>
  417. * <li>Add file 'a'
  418. * <li>Commit
  419. * <li>Create branch '1'
  420. * <li>Modify file 'a'
  421. * <li>Commit
  422. * <li>Delete file 'a' and replace by folder 'a' in the working tree and
  423. * index
  424. * <li>Checkout branch '1'
  425. * </ol>
  426. * <p>
  427. * The checkout command should raise an error. The conflicting path is 'a'.
  428. *
  429. * @throws Exception
  430. */
  431. @Test
  432. public void fileModeTestFileThenFileWithFolderInIndex() throws Exception {
  433. try (Git git = new Git(db)) {
  434. writeTrashFile("a", "Hello world a");
  435. writeTrashFile("b", "Hello world b");
  436. git.add().addFilepattern(".").call();
  437. git.commit().setMessage("add files a & b").call();
  438. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  439. writeTrashFile("a", "b");
  440. git.add().addFilepattern("a").call();
  441. git.commit().setMessage("add file a").call();
  442. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  443. db.getWorkTree(), "a"), db.getFS());
  444. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  445. git.rm().addFilepattern("a").call();
  446. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  447. writeTrashFile("a/c", "Hello world c");
  448. git.add().addFilepattern(".").call();
  449. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  450. db.getFS());
  451. assertEquals(FileMode.TREE, entry.getMode());
  452. CheckoutConflictException exception = null;
  453. try {
  454. git.checkout().setName(branch_1.getName()).call();
  455. } catch (CheckoutConflictException e) {
  456. exception = e;
  457. }
  458. assertNotNull(exception);
  459. assertEquals(1, exception.getConflictingPaths().size());
  460. assertEquals("a", exception.getConflictingPaths().get(0));
  461. }
  462. }
  463. /**
  464. * Steps:
  465. * <ol>
  466. * <li>Add file 'a'
  467. * <li>Commit
  468. * <li>Create branch '1'
  469. * <li>Modify file 'a'
  470. * <li>Commit
  471. * <li>Delete file 'a' and replace by folder 'a' in the working tree and
  472. * index
  473. * <li>Checkout branch '1'
  474. * </ol>
  475. * <p>
  476. * The checkout command should raise an error. The conflicting paths are 'a'
  477. * and 'a/c'.
  478. *
  479. * @throws Exception
  480. */
  481. @Test
  482. public void fileModeTestFileWithFolderInIndex() throws Exception {
  483. try (Git git = new Git(db)) {
  484. writeTrashFile("b", "Hello world b");
  485. writeTrashFile("a", "b");
  486. git.add().addFilepattern(".").call();
  487. git.commit().setMessage("add file b & file a").call();
  488. Ref branch_1 = git.branchCreate().setName("branch_1").call();
  489. git.rm().addFilepattern("a").call();
  490. writeTrashFile("a", "Hello world a");
  491. git.add().addFilepattern("a").call();
  492. git.commit().setMessage("add file a").call();
  493. FileEntry entry = new FileTreeIterator.FileEntry(new File(
  494. db.getWorkTree(), "a"), db.getFS());
  495. assertEquals(FileMode.REGULAR_FILE, entry.getMode());
  496. git.rm().addFilepattern("a").call();
  497. FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
  498. writeTrashFile("a/c", "Hello world c");
  499. git.add().addFilepattern(".").call();
  500. entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
  501. db.getFS());
  502. assertEquals(FileMode.TREE, entry.getMode());
  503. CheckoutConflictException exception = null;
  504. try {
  505. git.checkout().setName(branch_1.getName()).call();
  506. } catch (CheckoutConflictException e) {
  507. exception = e;
  508. }
  509. assertNotNull(exception);
  510. assertEquals(1, exception.getConflictingPaths().size());
  511. assertEquals("a", exception.getConflictingPaths().get(0));
  512. // TODO: ideally we'd like to get two paths from this exception
  513. // assertEquals(2, exception.getConflictingPaths().size());
  514. // assertEquals("a", exception.getConflictingPaths().get(0));
  515. // assertEquals("a/c", exception.getConflictingPaths().get(1));
  516. }
  517. }
  518. @Test
  519. public void testCheckoutPath() throws Exception {
  520. try (Git git = new Git(db)) {
  521. writeTrashFile("a", "Hello world a");
  522. git.add().addFilepattern(".").call();
  523. git.commit().setMessage("commit file a").call();
  524. git.branchCreate().setName("branch_1").call();
  525. git.checkout().setName("branch_1").call();
  526. File b = writeTrashFile("b", "Hello world b");
  527. git.add().addFilepattern("b").call();
  528. git.commit().setMessage("commit file b").call();
  529. File a = writeTrashFile("a", "New Hello world a");
  530. git.add().addFilepattern(".").call();
  531. git.commit().setMessage("modified a").call();
  532. assertArrayEquals(new String[] { "" },
  533. execute("git checkout HEAD~2 -- a"));
  534. assertEquals("Hello world a", read(a));
  535. assertArrayEquals(new String[] { "* branch_1", " master", "" },
  536. execute("git branch"));
  537. assertEquals("Hello world b", read(b));
  538. }
  539. }
  540. @Test
  541. public void testCheckoutAllPaths() throws Exception {
  542. try (Git git = new Git(db)) {
  543. writeTrashFile("a", "Hello world a");
  544. git.add().addFilepattern(".").call();
  545. git.commit().setMessage("commit file a").call();
  546. git.branchCreate().setName("branch_1").call();
  547. git.checkout().setName("branch_1").call();
  548. File b = writeTrashFile("b", "Hello world b");
  549. git.add().addFilepattern("b").call();
  550. git.commit().setMessage("commit file b").call();
  551. File a = writeTrashFile("a", "New Hello world a");
  552. git.add().addFilepattern(".").call();
  553. git.commit().setMessage("modified a").call();
  554. assertArrayEquals(new String[] { "" },
  555. execute("git checkout HEAD~2 -- ."));
  556. assertEquals("Hello world a", read(a));
  557. assertArrayEquals(new String[] { "* branch_1", " master", "" },
  558. execute("git branch"));
  559. assertEquals("Hello world b", read(b));
  560. }
  561. }
  562. @Test
  563. public void testCheckoutSingleFile() throws Exception {
  564. try (Git git = new Git(db)) {
  565. File a = writeTrashFile("a", "file a");
  566. git.add().addFilepattern(".").call();
  567. git.commit().setMessage("commit file a").call();
  568. writeTrashFile("a", "b");
  569. assertEquals("b", read(a));
  570. assertEquals("[]", Arrays.toString(execute("git checkout -- a")));
  571. assertEquals("file a", read(a));
  572. }
  573. }
  574. @Test
  575. public void testCheckoutLink() throws Exception {
  576. Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
  577. try (Git git = new Git(db)) {
  578. Path path = writeLink("a", "link_a");
  579. assertTrue(Files.isSymbolicLink(path));
  580. git.add().addFilepattern(".").call();
  581. git.commit().setMessage("commit link a").call();
  582. deleteTrashFile("a");
  583. writeTrashFile("a", "Hello world a");
  584. assertFalse(Files.isSymbolicLink(path));
  585. assertEquals("[]", Arrays.toString(execute("git checkout -- a")));
  586. assertEquals("link_a", FileUtils.readSymLink(path.toFile()));
  587. assertTrue(Files.isSymbolicLink(path));
  588. }
  589. }
  590. @Test
  591. public void testCheckoutForce_Bug530771() throws Exception {
  592. try (Git git = new Git(db)) {
  593. File f = writeTrashFile("a", "Hello world");
  594. git.add().addFilepattern("a").call();
  595. git.commit().setMessage("create a").call();
  596. writeTrashFile("a", "Goodbye world");
  597. assertEquals("[]",
  598. Arrays.toString(execute("git checkout -f HEAD")));
  599. assertEquals("Hello world", read(f));
  600. assertEquals("[a, mode:100644, content:Hello world]",
  601. indexState(db, LocalDiskRepositoryTestCase.CONTENT));
  602. }
  603. }
  604. }