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.

ReadTreeTest.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*
  2. * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
  3. * Copyright (C) 2008-2009, Robin Rosenberg <robin.rosenberg@dewire.com>
  4. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
  5. * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
  6. * and other copyright owners as documented in the project's IP log.
  7. *
  8. * This program and the accompanying materials are made available
  9. * under the terms of the Eclipse Distribution License v1.0 which
  10. * accompanies this distribution, is reproduced below, and is
  11. * available at http://www.eclipse.org/org/documents/edl-v10.php
  12. *
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or
  16. * without modification, are permitted provided that the following
  17. * conditions are met:
  18. *
  19. * - Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. *
  22. * - Redistributions in binary form must reproduce the above
  23. * copyright notice, this list of conditions and the following
  24. * disclaimer in the documentation and/or other materials provided
  25. * with the distribution.
  26. *
  27. * - Neither the name of the Eclipse Foundation, Inc. nor the
  28. * names of its contributors may be used to endorse or promote
  29. * products derived from this software without specific prior
  30. * written permission.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  33. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  34. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  35. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  36. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  37. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  38. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  39. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  41. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  42. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  43. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  44. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45. */
  46. package org.eclipse.jgit.lib;
  47. import java.io.ByteArrayInputStream;
  48. import java.io.File;
  49. import java.io.FileInputStream;
  50. import java.io.IOException;
  51. import java.io.InputStream;
  52. import java.util.ArrayList;
  53. import java.util.Arrays;
  54. import java.util.HashMap;
  55. import org.eclipse.jgit.errors.CheckoutConflictException;
  56. import org.eclipse.jgit.errors.CorruptObjectException;
  57. import org.eclipse.jgit.treewalk.FileTreeIterator;
  58. import org.eclipse.jgit.treewalk.TreeWalk;
  59. public abstract class ReadTreeTest extends RepositoryTestCase {
  60. protected Tree theHead;
  61. protected Tree theMerge;
  62. // Each of these rules are from the read-tree manpage
  63. // go there to see what they mean.
  64. // Rule 0 is left out for obvious reasons :)
  65. public void testRules1thru3_NoIndexEntry() throws IOException {
  66. Tree head = new Tree(db);
  67. FileTreeEntry headFile = head.addFile("foo");
  68. ObjectId objectId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18e9");
  69. headFile.setId(objectId);
  70. Tree merge = new Tree(db);
  71. prescanTwoTrees(head, merge);
  72. assertTrue(getRemoved().contains("foo"));
  73. prescanTwoTrees(merge, head);
  74. assertEquals(objectId, getUpdated().get("foo"));
  75. ObjectId anotherId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18ee");
  76. merge.addFile("foo").setId(anotherId);
  77. prescanTwoTrees(head, merge);
  78. assertEquals(anotherId, getUpdated().get("foo"));
  79. }
  80. void setupCase(HashMap<String, String> headEntries,
  81. HashMap<String, String> mergeEntries,
  82. HashMap<String, String> indexEntries) throws IOException {
  83. theHead = buildTree(headEntries);
  84. theMerge = buildTree(mergeEntries);
  85. buildIndex(indexEntries);
  86. }
  87. private void buildIndex(HashMap<String, String> indexEntries) throws IOException {
  88. GitIndex index = new GitIndex(db);
  89. if (indexEntries != null) {
  90. for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) {
  91. index.add(trash, writeTrashFile(e.getKey(), e.getValue())).forceRecheck();
  92. }
  93. }
  94. index.write();
  95. db.getIndex().read();
  96. }
  97. private Tree buildTree(HashMap<String, String> headEntries) throws IOException {
  98. Tree tree = new Tree(db);
  99. ObjectWriter ow = new ObjectWriter(db);
  100. if (headEntries == null)
  101. return tree;
  102. FileTreeEntry fileEntry;
  103. Tree parent;
  104. for (java.util.Map.Entry<String, String> e : headEntries.entrySet()) {
  105. fileEntry = tree.addFile(e.getKey());
  106. fileEntry.setId(genSha1(e.getValue()));
  107. parent = fileEntry.getParent();
  108. while (parent != null) {
  109. parent.setId(ow.writeTree(parent));
  110. parent = parent.getParent();
  111. }
  112. }
  113. return tree;
  114. }
  115. ObjectId genSha1(String data) {
  116. InputStream is = new ByteArrayInputStream(data.getBytes());
  117. ObjectWriter objectWriter = new ObjectWriter(db);
  118. try {
  119. return objectWriter.writeObject(Constants.OBJ_BLOB, data
  120. .getBytes().length, is, true);
  121. } catch (IOException e) {
  122. fail(e.toString());
  123. }
  124. return null;
  125. }
  126. protected void go() throws IllegalStateException, IOException {
  127. prescanTwoTrees(theHead, theMerge);
  128. }
  129. // for these rules, they all have clean yes/no options
  130. // but it doesn't matter if the entry is clean or not
  131. // so we can just ignore the state in the filesystem entirely
  132. public void testRules4thru13_IndexEntryNotInHead() throws IOException {
  133. // rules 4 and 5
  134. HashMap<String, String> idxMap;
  135. idxMap = new HashMap<String, String>();
  136. idxMap.put("foo", "foo");
  137. setupCase(null, null, idxMap);
  138. go();
  139. assertTrue(getUpdated().isEmpty());
  140. assertTrue(getRemoved().isEmpty());
  141. assertTrue(getConflicts().isEmpty());
  142. // rules 6 and 7
  143. idxMap = new HashMap<String, String>();
  144. idxMap.put("foo", "foo");
  145. setupCase(null, idxMap, idxMap);
  146. go();
  147. assertAllEmpty();
  148. // rules 8 and 9
  149. HashMap<String, String> mergeMap;
  150. mergeMap = new HashMap<String, String>();
  151. mergeMap.put("foo", "merge");
  152. setupCase(null, mergeMap, idxMap);
  153. go();
  154. assertTrue(getUpdated().isEmpty());
  155. assertTrue(getRemoved().isEmpty());
  156. assertTrue(getConflicts().contains("foo"));
  157. // rule 10
  158. HashMap<String, String> headMap = new HashMap<String, String>();
  159. headMap.put("foo", "foo");
  160. setupCase(headMap, null, idxMap);
  161. go();
  162. assertTrue(getRemoved().contains("foo"));
  163. assertTrue(getUpdated().isEmpty());
  164. assertTrue(getConflicts().isEmpty());
  165. // rule 11
  166. setupCase(headMap, null, idxMap);
  167. new File(trash, "foo").delete();
  168. writeTrashFile("foo", "bar");
  169. db.getIndex().getMembers()[0].forceRecheck();
  170. go();
  171. assertTrue(getRemoved().isEmpty());
  172. assertTrue(getUpdated().isEmpty());
  173. assertTrue(getConflicts().contains("foo"));
  174. // rule 12 & 13
  175. headMap.put("foo", "head");
  176. setupCase(headMap, null, idxMap);
  177. go();
  178. assertTrue(getRemoved().isEmpty());
  179. assertTrue(getUpdated().isEmpty());
  180. assertTrue(getConflicts().contains("foo"));
  181. // rules 14 & 15
  182. setupCase(headMap, headMap, idxMap);
  183. go();
  184. assertAllEmpty();
  185. // rules 16 & 17
  186. setupCase(headMap, mergeMap, idxMap); go();
  187. assertTrue(getConflicts().contains("foo"));
  188. // rules 18 & 19
  189. setupCase(headMap, idxMap, idxMap); go();
  190. assertAllEmpty();
  191. // rule 20
  192. setupCase(idxMap, mergeMap, idxMap); go();
  193. assertTrue(getUpdated().containsKey("foo"));
  194. // rules 21
  195. setupCase(idxMap, mergeMap, idxMap);
  196. new File(trash, "foo").delete();
  197. writeTrashFile("foo", "bar");
  198. db.getIndex().getMembers()[0].forceRecheck();
  199. go();
  200. assertTrue(getConflicts().contains("foo"));
  201. }
  202. private void assertAllEmpty() {
  203. assertTrue(getRemoved().isEmpty());
  204. assertTrue(getUpdated().isEmpty());
  205. assertTrue(getConflicts().isEmpty());
  206. }
  207. public void testDirectoryFileSimple() throws IOException {
  208. Tree treeDF = buildTree(mkmap("DF", "DF"));
  209. Tree treeDFDF = buildTree(mkmap("DF/DF", "DF/DF"));
  210. buildIndex(mkmap("DF", "DF"));
  211. prescanTwoTrees(treeDF, treeDFDF);
  212. assertTrue(getRemoved().contains("DF"));
  213. assertTrue(getUpdated().containsKey("DF/DF"));
  214. recursiveDelete(new File(trash, "DF"));
  215. buildIndex(mkmap("DF/DF", "DF/DF"));
  216. prescanTwoTrees(treeDFDF, treeDF);
  217. assertTrue(getRemoved().contains("DF/DF"));
  218. assertTrue(getUpdated().containsKey("DF"));
  219. }
  220. /*
  221. * Directory/File Conflict cases:
  222. * It's entirely possible that in practice a number of these may be equivalent
  223. * to the cases described in git-read-tree.txt. As long as it does the right thing,
  224. * that's all I care about. These are basically reverse-engineered from
  225. * what git currently does. If there are tests for these in git, it's kind of
  226. * hard to track them all down...
  227. *
  228. * H I M Clean H==M H==I I==M Result
  229. * ------------------------------------------------------------------
  230. *1 D D F Y N Y N Update
  231. *2 D D F N N Y N Conflict
  232. *3 D F D Y N N Update
  233. *4 D F D N N N Update
  234. *5 D F F Y N N Y Keep
  235. *6 D F F N N N Y Keep
  236. *7 F D F Y Y N N Update
  237. *8 F D F N Y N N Conflict
  238. *9 F D F Y N N N Update
  239. *10 F D D N N Y Keep
  240. *11 F D D N N N Conflict
  241. *12 F F D Y N Y N Update
  242. *13 F F D N N Y N Conflict
  243. *14 F F D N N N Conflict
  244. *15 0 F D N N N Conflict
  245. *16 0 D F Y N N N Update
  246. *17 0 D F N N N Conflict
  247. *18 F 0 D Update
  248. *19 D 0 F Update
  249. */
  250. public void testDirectoryFileConflicts_1() throws Exception {
  251. // 1
  252. doit(mk("DF/DF"), mk("DF"), mk("DF/DF"));
  253. assertNoConflicts();
  254. assertUpdated("DF");
  255. assertRemoved("DF/DF");
  256. }
  257. public void testDirectoryFileConflicts_2() throws Exception {
  258. // 2
  259. setupCase(mk("DF/DF"), mk("DF"), mk("DF/DF"));
  260. writeTrashFile("DF/DF", "different");
  261. go();
  262. assertConflict("DF/DF");
  263. }
  264. public void testDirectoryFileConflicts_3() throws Exception {
  265. // 3 - the first to break!
  266. doit(mk("DF/DF"), mk("DF/DF"), mk("DF"));
  267. assertUpdated("DF/DF");
  268. assertRemoved("DF");
  269. }
  270. public void testDirectoryFileConflicts_4() throws Exception {
  271. // 4 (basically same as 3, just with H and M different)
  272. doit(mk("DF/DF"), mkmap("DF/DF", "foo"), mk("DF"));
  273. assertUpdated("DF/DF");
  274. assertRemoved("DF");
  275. }
  276. public void testDirectoryFileConflicts_5() throws Exception {
  277. // 5
  278. doit(mk("DF/DF"), mk("DF"), mk("DF"));
  279. assertRemoved("DF/DF");
  280. }
  281. public void testDirectoryFileConflicts_6() throws Exception {
  282. // 6
  283. setupCase(mk("DF/DF"), mk("DF"), mk("DF"));
  284. writeTrashFile("DF", "different");
  285. go();
  286. assertRemoved("DF/DF");
  287. }
  288. public void testDirectoryFileConflicts_7() throws Exception {
  289. // 7
  290. doit(mk("DF"), mk("DF"), mk("DF/DF"));
  291. assertUpdated("DF");
  292. assertRemoved("DF/DF");
  293. cleanUpDF();
  294. setupCase(mk("DF/DF"), mk("DF/DF"), mk("DF/DF/DF/DF/DF"));
  295. go();
  296. assertRemoved("DF/DF/DF/DF/DF");
  297. assertUpdated("DF/DF");
  298. cleanUpDF();
  299. setupCase(mk("DF/DF"), mk("DF/DF"), mk("DF/DF/DF/DF/DF"));
  300. writeTrashFile("DF/DF/DF/DF/DF", "diff");
  301. go();
  302. assertConflict("DF/DF/DF/DF/DF");
  303. assertUpdated("DF/DF");
  304. }
  305. // 8 ?
  306. public void testDirectoryFileConflicts_9() throws Exception {
  307. // 9
  308. doit(mk("DF"), mkmap("DF", "QP"), mk("DF/DF"));
  309. assertRemoved("DF/DF");
  310. assertUpdated("DF");
  311. }
  312. public void testDirectoryFileConflicts_10() throws Exception {
  313. // 10
  314. cleanUpDF();
  315. doit(mk("DF"), mk("DF/DF"), mk("DF/DF"));
  316. assertNoConflicts();
  317. }
  318. public void testDirectoryFileConflicts_11() throws Exception {
  319. // 11
  320. doit(mk("DF"), mk("DF/DF"), mkmap("DF/DF", "asdf"));
  321. assertConflict("DF/DF");
  322. }
  323. public void testDirectoryFileConflicts_12() throws Exception {
  324. // 12
  325. cleanUpDF();
  326. doit(mk("DF"), mk("DF/DF"), mk("DF"));
  327. assertRemoved("DF");
  328. assertUpdated("DF/DF");
  329. }
  330. public void testDirectoryFileConflicts_13() throws Exception {
  331. // 13
  332. cleanUpDF();
  333. setupCase(mk("DF"), mk("DF/DF"), mk("DF"));
  334. writeTrashFile("DF", "asdfsdf");
  335. go();
  336. assertConflict("DF");
  337. assertUpdated("DF/DF");
  338. }
  339. public void testDirectoryFileConflicts_14() throws Exception {
  340. // 14
  341. cleanUpDF();
  342. doit(mk("DF"), mk("DF/DF"), mkmap("DF", "Foo"));
  343. assertConflict("DF");
  344. assertUpdated("DF/DF");
  345. }
  346. public void testDirectoryFileConflicts_15() throws Exception {
  347. // 15
  348. doit(mkmap(), mk("DF/DF"), mk("DF"));
  349. assertRemoved("DF");
  350. assertUpdated("DF/DF");
  351. }
  352. public void testDirectoryFileConflicts_15b() throws Exception {
  353. // 15, take 2, just to check multi-leveled
  354. doit(mkmap(), mk("DF/DF/DF/DF"), mk("DF"));
  355. assertRemoved("DF");
  356. assertUpdated("DF/DF/DF/DF");
  357. }
  358. public void testDirectoryFileConflicts_16() throws Exception {
  359. // 16
  360. cleanUpDF();
  361. doit(mkmap(), mk("DF"), mk("DF/DF/DF"));
  362. assertRemoved("DF/DF/DF");
  363. assertUpdated("DF");
  364. }
  365. public void testDirectoryFileConflicts_17() throws Exception {
  366. // 17
  367. cleanUpDF();
  368. setupCase(mkmap(), mk("DF"), mk("DF/DF/DF"));
  369. writeTrashFile("DF/DF/DF", "asdf");
  370. go();
  371. assertConflict("DF/DF/DF");
  372. assertUpdated("DF");
  373. }
  374. public void testDirectoryFileConflicts_18() throws Exception {
  375. // 18
  376. cleanUpDF();
  377. doit(mk("DF/DF"), mk("DF/DF/DF/DF"), null);
  378. assertRemoved("DF/DF");
  379. assertUpdated("DF/DF/DF/DF");
  380. }
  381. public void testDirectoryFileConflicts_19() throws Exception {
  382. // 19
  383. cleanUpDF();
  384. doit(mk("DF/DF/DF/DF"), mk("DF/DF/DF"), null);
  385. assertRemoved("DF/DF/DF/DF");
  386. assertUpdated("DF/DF/DF");
  387. }
  388. private void cleanUpDF() throws Exception {
  389. tearDown();
  390. setUp();
  391. recursiveDelete(new File(trash, "DF"));
  392. }
  393. private void assertConflict(String s) {
  394. assertTrue(getConflicts().contains(s));
  395. }
  396. private void assertUpdated(String s) {
  397. assertTrue(getUpdated().containsKey(s));
  398. }
  399. private void assertRemoved(String s) {
  400. assertTrue(getRemoved().contains(s));
  401. }
  402. private void assertNoConflicts() {
  403. assertTrue(getConflicts().isEmpty());
  404. }
  405. private void doit(HashMap<String, String> h, HashMap<String, String> m,
  406. HashMap<String, String> i) throws IOException {
  407. setupCase(h, m, i);
  408. go();
  409. }
  410. protected static HashMap<String, String> mk(String a) {
  411. return mkmap(a, a);
  412. }
  413. protected static HashMap<String, String> mkmap(String... args) {
  414. if ((args.length % 2) > 0)
  415. throw new IllegalArgumentException("needs to be pairs");
  416. HashMap<String, String> map = new HashMap<String, String>();
  417. for (int i = 0; i < args.length; i += 2) {
  418. map.put(args[i], args[i+1]);
  419. }
  420. return map;
  421. }
  422. public void testUntrackedConflicts() throws IOException {
  423. setupCase(null, mk("foo"), null);
  424. writeTrashFile("foo", "foo");
  425. go();
  426. assertConflict("foo");
  427. recursiveDelete(new File(trash, "foo"));
  428. setupCase(null, mk("foo"), null);
  429. writeTrashFile("foo/bar/baz", "");
  430. writeTrashFile("foo/blahblah", "");
  431. go();
  432. assertConflict("foo/bar/baz");
  433. assertConflict("foo/blahblah");
  434. recursiveDelete(new File(trash, "foo"));
  435. setupCase(mkmap("foo/bar", "", "foo/baz", ""),
  436. mk("foo"), mkmap("foo/bar", "", "foo/baz", ""));
  437. assertTrue(new File(trash, "foo/bar").exists());
  438. go();
  439. assertNoConflicts();
  440. }
  441. public void testCloseNameConflictsX0() throws IOException {
  442. setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "b.b/b.b","b.b/b.bs"), mkmap("a/a", "a/a-c") );
  443. checkout();
  444. assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
  445. assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
  446. go();
  447. assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
  448. assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
  449. assertNoConflicts();
  450. }
  451. public void testCloseNameConflicts1() throws IOException {
  452. setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "a.a/a.a","a.a/a.a"), mkmap("a/a", "a/a-c") );
  453. checkout();
  454. assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
  455. assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
  456. go();
  457. assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
  458. assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
  459. assertNoConflicts();
  460. }
  461. public void testCheckoutOutChanges() throws IOException {
  462. setupCase(mk("foo"), mk("foo/bar"), mk("foo"));
  463. checkout();
  464. assertIndex(mk("foo/bar"));
  465. assertWorkDir(mk("foo/bar"));
  466. assertFalse(new File(trash, "foo").isFile());
  467. assertTrue(new File(trash, "foo/bar").isFile());
  468. recursiveDelete(new File(trash, "foo"));
  469. assertWorkDir(mkmap());
  470. setupCase(mk("foo/bar"), mk("foo"), mk("foo/bar"));
  471. checkout();
  472. assertIndex(mk("foo"));
  473. assertWorkDir(mk("foo"));
  474. assertFalse(new File(trash, "foo/bar").isFile());
  475. assertTrue(new File(trash, "foo").isFile());
  476. setupCase(mk("foo"), mkmap("foo", "qux"), mkmap("foo", "bar"));
  477. assertIndex(mkmap("foo", "bar"));
  478. assertWorkDir(mkmap("foo", "bar"));
  479. try {
  480. checkout();
  481. fail("did not throw exception");
  482. } catch (CheckoutConflictException e) {
  483. assertIndex(mkmap("foo", "bar"));
  484. assertWorkDir(mkmap("foo", "bar"));
  485. }
  486. }
  487. public void testCheckoutUncachedChanges() throws IOException {
  488. setupCase(mk("foo"), mk("foo"), mk("foo"));
  489. writeTrashFile("foo", "otherData");
  490. checkout();
  491. assertIndex(mk("foo"));
  492. assertWorkDir(mkmap("foo", "otherData"));
  493. assertTrue(new File(trash, "foo").isFile());
  494. }
  495. /**
  496. * The interface these tests need from a class implementing a checkout
  497. */
  498. interface Checkout {
  499. HashMap<String, ObjectId> updated();
  500. ArrayList<String> conflicts();
  501. ArrayList<String> removed();
  502. void prescanTwoTrees() throws IOException;
  503. void checkout() throws IOException;
  504. }
  505. public void assertWorkDir(HashMap<String, String> i)
  506. throws CorruptObjectException, IOException {
  507. TreeWalk walk = new TreeWalk(db);
  508. walk.reset();
  509. walk.setRecursive(true);
  510. walk.addTree(new FileTreeIterator(db));
  511. String expectedValue;
  512. String path;
  513. int nrFiles = 0;
  514. FileTreeIterator ft;
  515. while (walk.next()) {
  516. ft = walk.getTree(0, FileTreeIterator.class);
  517. path = ft.getEntryPathString();
  518. expectedValue = i.get(path);
  519. assertNotNull("found unexpected file for path "
  520. + path + " in workdir", expectedValue);
  521. File file = new File(db.getWorkDir(), path);
  522. assertTrue(file.exists());
  523. if (file.isFile()) {
  524. FileInputStream is = new FileInputStream(file);
  525. byte[] buffer = new byte[(int) file.length()];
  526. int offset = 0;
  527. int numRead = 0;
  528. while (offset < buffer.length
  529. && (numRead = is.read(buffer, offset, buffer.length
  530. - offset)) >= 0) {
  531. offset += numRead;
  532. }
  533. is.close();
  534. assertTrue("unexpected content for path " + path
  535. + " in workDir. Expected: <" + expectedValue + ">",
  536. Arrays.equals(buffer, i.get(path).getBytes()));
  537. nrFiles++;
  538. }
  539. }
  540. assertEquals("WorkDir has not the right size.", i.size(), nrFiles);
  541. }
  542. public void assertIndex(HashMap<String, String> i)
  543. throws CorruptObjectException, IOException {
  544. String expectedValue;
  545. String path;
  546. GitIndex theIndex=db.getIndex();
  547. assertEquals("Index has not the right size.", i.size(),
  548. theIndex.getMembers().length);
  549. for (int j = 0; j < theIndex.getMembers().length; j++) {
  550. path = theIndex.getMembers()[j].getName();
  551. expectedValue = i.get(path);
  552. assertNotNull("found unexpected entry for path " + path
  553. + " in index", expectedValue);
  554. assertTrue("unexpected content for path " + path
  555. + " in index. Expected: <" + expectedValue + ">",
  556. Arrays.equals(
  557. db.openBlob(theIndex.getMembers()[j].getObjectId())
  558. .getBytes(), i.get(path).getBytes()));
  559. }
  560. }
  561. public abstract void prescanTwoTrees(Tree head, Tree merge) throws IllegalStateException, IOException;
  562. public abstract void checkout() throws IOException;
  563. public abstract ArrayList<String> getRemoved();
  564. public abstract HashMap<String, ObjectId> getUpdated();
  565. public abstract ArrayList<String> getConflicts();
  566. }