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.

RenameDetectorTest.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*
  2. * Copyright (C) 2010, Google Inc. 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.diff;
  11. import static org.junit.Assert.assertEquals;
  12. import static org.junit.Assert.assertSame;
  13. import static org.junit.Assert.assertTrue;
  14. import static org.junit.Assert.fail;
  15. import java.util.Arrays;
  16. import java.util.List;
  17. import org.eclipse.jgit.diff.DiffEntry.ChangeType;
  18. import org.eclipse.jgit.junit.RepositoryTestCase;
  19. import org.eclipse.jgit.junit.TestRepository;
  20. import org.eclipse.jgit.lib.AbbreviatedObjectId;
  21. import org.eclipse.jgit.lib.FileMode;
  22. import org.eclipse.jgit.lib.ObjectId;
  23. import org.eclipse.jgit.lib.Repository;
  24. import org.junit.Before;
  25. import org.junit.Test;
  26. public class RenameDetectorTest extends RepositoryTestCase {
  27. private static final String PATH_A = "src/A";
  28. private static final String PATH_B = "src/B";
  29. private static final String PATH_H = "src/H";
  30. private static final String PATH_Q = "src/Q";
  31. private RenameDetector rd;
  32. private TestRepository<Repository> testDb;
  33. @Override
  34. @Before
  35. public void setUp() throws Exception {
  36. super.setUp();
  37. testDb = new TestRepository<>(db);
  38. rd = new RenameDetector(db);
  39. }
  40. @Test
  41. public void testExactRename_OneRename() throws Exception {
  42. ObjectId foo = blob("foo");
  43. DiffEntry a = DiffEntry.add(PATH_A, foo);
  44. DiffEntry b = DiffEntry.delete(PATH_Q, foo);
  45. rd.add(a);
  46. rd.add(b);
  47. List<DiffEntry> entries = rd.compute();
  48. assertEquals(1, entries.size());
  49. assertRename(b, a, 100, entries.get(0));
  50. }
  51. @Test
  52. public void testExactRename_DifferentObjects() throws Exception {
  53. ObjectId foo = blob("foo");
  54. ObjectId bar = blob("bar");
  55. DiffEntry a = DiffEntry.add(PATH_A, foo);
  56. DiffEntry h = DiffEntry.add(PATH_H, foo);
  57. DiffEntry q = DiffEntry.delete(PATH_Q, bar);
  58. rd.add(a);
  59. rd.add(h);
  60. rd.add(q);
  61. List<DiffEntry> entries = rd.compute();
  62. assertEquals(3, entries.size());
  63. assertSame(a, entries.get(0));
  64. assertSame(h, entries.get(1));
  65. assertSame(q, entries.get(2));
  66. }
  67. @Test
  68. public void testExactRename_OneRenameOneModify() throws Exception {
  69. ObjectId foo = blob("foo");
  70. ObjectId bar = blob("bar");
  71. DiffEntry a = DiffEntry.add(PATH_A, foo);
  72. DiffEntry b = DiffEntry.delete(PATH_Q, foo);
  73. DiffEntry c = DiffEntry.modify(PATH_H);
  74. c.newId = c.oldId = AbbreviatedObjectId.fromObjectId(bar);
  75. rd.add(a);
  76. rd.add(b);
  77. rd.add(c);
  78. List<DiffEntry> entries = rd.compute();
  79. assertEquals(2, entries.size());
  80. assertRename(b, a, 100, entries.get(0));
  81. assertSame(c, entries.get(1));
  82. }
  83. @Test
  84. public void testExactRename_ManyRenames() throws Exception {
  85. ObjectId foo = blob("foo");
  86. ObjectId bar = blob("bar");
  87. DiffEntry a = DiffEntry.add(PATH_A, foo);
  88. DiffEntry b = DiffEntry.delete(PATH_Q, foo);
  89. DiffEntry c = DiffEntry.add(PATH_H, bar);
  90. DiffEntry d = DiffEntry.delete(PATH_B, bar);
  91. rd.add(a);
  92. rd.add(b);
  93. rd.add(c);
  94. rd.add(d);
  95. List<DiffEntry> entries = rd.compute();
  96. assertEquals(2, entries.size());
  97. assertRename(b, a, 100, entries.get(0));
  98. assertRename(d, c, 100, entries.get(1));
  99. }
  100. @Test
  101. public void testExactRename_MultipleIdenticalDeletes() throws Exception {
  102. ObjectId foo = blob("foo");
  103. DiffEntry a = DiffEntry.delete(PATH_A, foo);
  104. DiffEntry b = DiffEntry.delete(PATH_B, foo);
  105. DiffEntry c = DiffEntry.delete(PATH_H, foo);
  106. DiffEntry d = DiffEntry.add(PATH_Q, foo);
  107. rd.add(a);
  108. rd.add(b);
  109. rd.add(c);
  110. rd.add(d);
  111. // Pairs the add with the first delete added
  112. List<DiffEntry> entries = rd.compute();
  113. assertEquals(3, entries.size());
  114. assertEquals(b, entries.get(0));
  115. assertEquals(c, entries.get(1));
  116. assertRename(a, d, 100, entries.get(2));
  117. }
  118. @Test
  119. public void testExactRename_PathBreaksTie() throws Exception {
  120. ObjectId foo = blob("foo");
  121. DiffEntry a = DiffEntry.add("src/com/foo/a.java", foo);
  122. DiffEntry b = DiffEntry.delete("src/com/foo/b.java", foo);
  123. DiffEntry c = DiffEntry.add("c.txt", foo);
  124. DiffEntry d = DiffEntry.delete("d.txt", foo);
  125. DiffEntry e = DiffEntry.add("the_e_file.txt", foo);
  126. // Add out of order to avoid first-match succeeding
  127. rd.add(a);
  128. rd.add(d);
  129. rd.add(e);
  130. rd.add(b);
  131. rd.add(c);
  132. List<DiffEntry> entries = rd.compute();
  133. assertEquals(3, entries.size());
  134. assertRename(d, c, 100, entries.get(0));
  135. assertRename(b, a, 100, entries.get(1));
  136. assertCopy(d, e, 100, entries.get(2));
  137. }
  138. @Test
  139. public void testExactRename_OneDeleteManyAdds() throws Exception {
  140. ObjectId foo = blob("foo");
  141. DiffEntry a = DiffEntry.add("src/com/foo/a.java", foo);
  142. DiffEntry b = DiffEntry.add("src/com/foo/b.java", foo);
  143. DiffEntry c = DiffEntry.add("c.txt", foo);
  144. DiffEntry d = DiffEntry.delete("d.txt", foo);
  145. rd.add(a);
  146. rd.add(b);
  147. rd.add(c);
  148. rd.add(d);
  149. List<DiffEntry> entries = rd.compute();
  150. assertEquals(3, entries.size());
  151. assertRename(d, c, 100, entries.get(0));
  152. assertCopy(d, a, 100, entries.get(1));
  153. assertCopy(d, b, 100, entries.get(2));
  154. }
  155. @Test
  156. public void testExactRename_UnstagedFile() throws Exception {
  157. ObjectId aId = blob("foo");
  158. DiffEntry a = DiffEntry.delete(PATH_A, aId);
  159. DiffEntry b = DiffEntry.add(PATH_B, aId);
  160. rd.addAll(Arrays.asList(a, b));
  161. List<DiffEntry> entries = rd.compute();
  162. assertEquals(1, entries.size());
  163. assertRename(a, b, 100, entries.get(0));
  164. }
  165. @Test
  166. public void testInexactRename_OnePair() throws Exception {
  167. ObjectId aId = blob("foo\nbar\nbaz\nblarg\n");
  168. ObjectId bId = blob("foo\nbar\nbaz\nblah\n");
  169. DiffEntry a = DiffEntry.add(PATH_A, aId);
  170. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  171. rd.add(a);
  172. rd.add(b);
  173. List<DiffEntry> entries = rd.compute();
  174. assertEquals(1, entries.size());
  175. assertRename(b, a, 66, entries.get(0));
  176. }
  177. @Test
  178. public void testInexactRename_OneRenameTwoUnrelatedFiles() throws Exception {
  179. ObjectId aId = blob("foo\nbar\nbaz\nblarg\n");
  180. ObjectId bId = blob("foo\nbar\nbaz\nblah\n");
  181. DiffEntry a = DiffEntry.add(PATH_A, aId);
  182. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  183. ObjectId cId = blob("some\nsort\nof\ntext\n");
  184. ObjectId dId = blob("completely\nunrelated\ntext\n");
  185. DiffEntry c = DiffEntry.add(PATH_B, cId);
  186. DiffEntry d = DiffEntry.delete(PATH_H, dId);
  187. rd.add(a);
  188. rd.add(b);
  189. rd.add(c);
  190. rd.add(d);
  191. List<DiffEntry> entries = rd.compute();
  192. assertEquals(3, entries.size());
  193. assertRename(b, a, 66, entries.get(0));
  194. assertSame(c, entries.get(1));
  195. assertSame(d, entries.get(2));
  196. }
  197. @Test
  198. public void testInexactRename_LastByteDifferent() throws Exception {
  199. ObjectId aId = blob("foo\nbar\na");
  200. ObjectId bId = blob("foo\nbar\nb");
  201. DiffEntry a = DiffEntry.add(PATH_A, aId);
  202. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  203. rd.add(a);
  204. rd.add(b);
  205. List<DiffEntry> entries = rd.compute();
  206. assertEquals(1, entries.size());
  207. assertRename(b, a, 88, entries.get(0));
  208. }
  209. @Test
  210. public void testInexactRename_NewlinesOnly() throws Exception {
  211. ObjectId aId = blob("\n\n\n");
  212. ObjectId bId = blob("\n\n\n\n");
  213. DiffEntry a = DiffEntry.add(PATH_A, aId);
  214. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  215. rd.add(a);
  216. rd.add(b);
  217. List<DiffEntry> entries = rd.compute();
  218. assertEquals(1, entries.size());
  219. assertRename(b, a, 74, entries.get(0));
  220. }
  221. @Test
  222. public void testInexactRename_SameContentMultipleTimes() throws Exception {
  223. ObjectId aId = blob("a\na\na\na\n");
  224. ObjectId bId = blob("a\na\na\n");
  225. DiffEntry a = DiffEntry.add(PATH_A, aId);
  226. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  227. rd.add(a);
  228. rd.add(b);
  229. List<DiffEntry> entries = rd.compute();
  230. assertEquals(1, entries.size());
  231. assertRename(b, a, 74, entries.get(0));
  232. }
  233. @Test
  234. public void testInexactRenames_OnePair2() throws Exception {
  235. ObjectId aId = blob("ab\nab\nab\nac\nad\nae\n");
  236. ObjectId bId = blob("ac\nab\nab\nab\naa\na0\na1\n");
  237. DiffEntry a = DiffEntry.add(PATH_A, aId);
  238. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  239. rd.add(a);
  240. rd.add(b);
  241. rd.setRenameScore(50);
  242. List<DiffEntry> entries = rd.compute();
  243. assertEquals(1, entries.size());
  244. assertRename(b, a, 57, entries.get(0));
  245. }
  246. @Test
  247. public void testNoRenames_SingleByteFiles() throws Exception {
  248. ObjectId aId = blob("a");
  249. ObjectId bId = blob("b");
  250. DiffEntry a = DiffEntry.add(PATH_A, aId);
  251. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  252. rd.add(a);
  253. rd.add(b);
  254. List<DiffEntry> entries = rd.compute();
  255. assertEquals(2, entries.size());
  256. assertSame(a, entries.get(0));
  257. assertSame(b, entries.get(1));
  258. }
  259. @Test
  260. public void testNoRenames_EmptyFile1() throws Exception {
  261. ObjectId aId = blob("");
  262. DiffEntry a = DiffEntry.add(PATH_A, aId);
  263. rd.add(a);
  264. List<DiffEntry> entries = rd.compute();
  265. assertEquals(1, entries.size());
  266. assertSame(a, entries.get(0));
  267. }
  268. @Test
  269. public void testNoRenames_EmptyFile2() throws Exception {
  270. ObjectId aId = blob("");
  271. ObjectId bId = blob("blah");
  272. DiffEntry a = DiffEntry.add(PATH_A, aId);
  273. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  274. rd.add(a);
  275. rd.add(b);
  276. List<DiffEntry> entries = rd.compute();
  277. assertEquals(2, entries.size());
  278. assertSame(a, entries.get(0));
  279. assertSame(b, entries.get(1));
  280. }
  281. @Test
  282. public void testNoRenames_SymlinkAndFile() throws Exception {
  283. ObjectId aId = blob("src/dest");
  284. DiffEntry a = DiffEntry.add(PATH_A, aId);
  285. DiffEntry b = DiffEntry.delete(PATH_Q, aId);
  286. b.oldMode = FileMode.SYMLINK;
  287. rd.add(a);
  288. rd.add(b);
  289. List<DiffEntry> entries = rd.compute();
  290. assertEquals(2, entries.size());
  291. assertSame(a, entries.get(0));
  292. assertSame(b, entries.get(1));
  293. }
  294. @Test
  295. public void testNoRenames_GitlinkAndFile() throws Exception {
  296. ObjectId aId = blob("src/dest");
  297. DiffEntry a = DiffEntry.add(PATH_A, aId);
  298. DiffEntry b = DiffEntry.delete(PATH_Q, aId);
  299. b.oldMode = FileMode.GITLINK;
  300. rd.add(a);
  301. rd.add(b);
  302. List<DiffEntry> entries = rd.compute();
  303. assertEquals(2, entries.size());
  304. assertSame(a, entries.get(0));
  305. assertSame(b, entries.get(1));
  306. }
  307. @Test
  308. public void testNoRenames_SymlinkAndFileSamePath() throws Exception {
  309. ObjectId aId = blob("src/dest");
  310. DiffEntry a = DiffEntry.delete(PATH_A, aId);
  311. DiffEntry b = DiffEntry.add(PATH_A, aId);
  312. a.oldMode = FileMode.SYMLINK;
  313. rd.add(a);
  314. rd.add(b);
  315. // Deletes should be first
  316. List<DiffEntry> entries = rd.compute();
  317. assertEquals(2, entries.size());
  318. assertSame(a, entries.get(0));
  319. assertSame(b, entries.get(1));
  320. }
  321. @Test
  322. public void testNoRenames_UntrackedFile() throws Exception {
  323. ObjectId aId = blob("foo");
  324. ObjectId bId = ObjectId
  325. .fromString("3049eb6eee7e1318f4e78e799bf33f1e54af9cbf");
  326. DiffEntry a = DiffEntry.delete(PATH_A, aId);
  327. DiffEntry b = DiffEntry.add(PATH_B, bId);
  328. rd.addAll(Arrays.asList(a, b));
  329. List<DiffEntry> entries = rd.compute();
  330. assertEquals(2, entries.size());
  331. assertSame(a, entries.get(0));
  332. assertSame(b, entries.get(1));
  333. }
  334. @Test
  335. public void testBreakModify_BreakAll() throws Exception {
  336. ObjectId aId = blob("foo");
  337. ObjectId bId = blob("bar");
  338. DiffEntry m = DiffEntry.modify(PATH_A);
  339. m.oldId = AbbreviatedObjectId.fromObjectId(aId);
  340. m.newId = AbbreviatedObjectId.fromObjectId(bId);
  341. DiffEntry a = DiffEntry.add(PATH_B, aId);
  342. rd.add(a);
  343. rd.add(m);
  344. rd.setBreakScore(101);
  345. List<DiffEntry> entries = rd.compute();
  346. assertEquals(2, entries.size());
  347. assertAdd(PATH_A, bId, FileMode.REGULAR_FILE, entries.get(0));
  348. assertRename(DiffEntry.breakModify(m).get(0), a, 100, entries.get(1));
  349. }
  350. @Test
  351. public void testBreakModify_BreakNone() throws Exception {
  352. ObjectId aId = blob("foo");
  353. ObjectId bId = blob("bar");
  354. DiffEntry m = DiffEntry.modify(PATH_A);
  355. m.oldId = AbbreviatedObjectId.fromObjectId(aId);
  356. m.newId = AbbreviatedObjectId.fromObjectId(bId);
  357. DiffEntry a = DiffEntry.add(PATH_B, aId);
  358. rd.add(a);
  359. rd.add(m);
  360. rd.setBreakScore(-1);
  361. List<DiffEntry> entries = rd.compute();
  362. assertEquals(2, entries.size());
  363. assertSame(m, entries.get(0));
  364. assertSame(a, entries.get(1));
  365. }
  366. @Test
  367. public void testBreakModify_BreakBelowScore() throws Exception {
  368. ObjectId aId = blob("foo");
  369. ObjectId bId = blob("bar");
  370. DiffEntry m = DiffEntry.modify(PATH_A);
  371. m.oldId = AbbreviatedObjectId.fromObjectId(aId);
  372. m.newId = AbbreviatedObjectId.fromObjectId(bId);
  373. DiffEntry a = DiffEntry.add(PATH_B, aId);
  374. rd.add(a);
  375. rd.add(m);
  376. rd.setBreakScore(20); // Should break the modify
  377. List<DiffEntry> entries = rd.compute();
  378. assertEquals(2, entries.size());
  379. assertAdd(PATH_A, bId, FileMode.REGULAR_FILE, entries.get(0));
  380. assertRename(DiffEntry.breakModify(m).get(0), a, 100, entries.get(1));
  381. }
  382. @Test
  383. public void testBreakModify_DontBreakAboveScore() throws Exception {
  384. ObjectId aId = blob("blah\nblah\nfoo");
  385. ObjectId bId = blob("blah\nblah\nbar");
  386. DiffEntry m = DiffEntry.modify(PATH_A);
  387. m.oldId = AbbreviatedObjectId.fromObjectId(aId);
  388. m.newId = AbbreviatedObjectId.fromObjectId(bId);
  389. DiffEntry a = DiffEntry.add(PATH_B, aId);
  390. rd.add(a);
  391. rd.add(m);
  392. rd.setBreakScore(20); // Should not break the modify
  393. List<DiffEntry> entries = rd.compute();
  394. assertEquals(2, entries.size());
  395. assertSame(m, entries.get(0));
  396. assertSame(a, entries.get(1));
  397. }
  398. @Test
  399. public void testBreakModify_RejoinIfUnpaired() throws Exception {
  400. ObjectId aId = blob("foo");
  401. ObjectId bId = blob("bar");
  402. DiffEntry m = DiffEntry.modify(PATH_A);
  403. m.oldId = AbbreviatedObjectId.fromObjectId(aId);
  404. m.newId = AbbreviatedObjectId.fromObjectId(bId);
  405. rd.add(m);
  406. rd.setBreakScore(101); // Ensure m is broken apart
  407. List<DiffEntry> entries = rd.compute();
  408. assertEquals(1, entries.size());
  409. DiffEntry modify = entries.get(0);
  410. assertEquals(m.oldPath, modify.oldPath);
  411. assertEquals(m.oldId, modify.oldId);
  412. assertEquals(m.oldMode, modify.oldMode);
  413. assertEquals(m.newPath, modify.newPath);
  414. assertEquals(m.newId, modify.newId);
  415. assertEquals(m.newMode, modify.newMode);
  416. assertEquals(m.changeType, modify.changeType);
  417. assertEquals(0, modify.score);
  418. }
  419. @Test
  420. public void testExactRename_LargeFile() throws Exception {
  421. ObjectId aId = blob("blah\nblah\nfoo"); // size = 14
  422. DiffEntry a = DiffEntry.add(PATH_A, aId);
  423. DiffEntry b = DiffEntry.delete(PATH_Q, aId);
  424. rd.add(a);
  425. rd.add(b);
  426. // Exact renames are identified for large files
  427. rd.setBigFileThreshold(10);
  428. List<DiffEntry> entries = rd.compute();
  429. assertEquals(1, entries.size());
  430. assertRename(b, a, 100, entries.get(0));
  431. }
  432. @Test
  433. public void testInexactRename_LargeFile() throws Exception {
  434. ObjectId aId = blob("blah\nblah\nfoo"); // size = 14
  435. ObjectId bId = blob("bla\nblah\nfoo"); // size = 13
  436. DiffEntry a = DiffEntry.add(PATH_A, aId);
  437. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  438. rd.add(a);
  439. rd.add(b);
  440. rd.setBigFileThreshold(10);
  441. // Inexact renames are not detected for large files
  442. List<DiffEntry> entries = rd.compute();
  443. assertEquals(2, entries.size());
  444. assertAdd(PATH_A, aId, FileMode.REGULAR_FILE, entries.get(0));
  445. assertDelete(PATH_Q, bId, FileMode.REGULAR_FILE, entries.get(1));
  446. }
  447. @Test
  448. public void testExactRenameForBinaryFile_isIdentified() throws Exception {
  449. ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
  450. DiffEntry a = DiffEntry.add(PATH_A, aId);
  451. DiffEntry b = DiffEntry.delete(PATH_Q, aId);
  452. rd.add(a);
  453. rd.add(b);
  454. List<DiffEntry> entries = rd.compute();
  455. assertEquals(1, entries.size());
  456. assertRename(b, a, 100, entries.get(0));
  457. }
  458. @Test
  459. public void testInexactRenameForBinaryFile_identifiedByDefault() throws Exception {
  460. ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
  461. ObjectId bId = blob("a\nb\nc\n\0\0\0d\n");
  462. DiffEntry a = DiffEntry.add(PATH_A, aId);
  463. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  464. rd.add(a);
  465. rd.add(b);
  466. rd.setRenameScore(40);
  467. List<DiffEntry> entries = rd.compute();
  468. assertEquals(1, entries.size());
  469. assertRename(b, a, 50, entries.get(0));
  470. }
  471. @Test
  472. public void testInexactRenameForBinaryFile_notIdentifiedIfSkipParameterSet() throws Exception {
  473. ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
  474. ObjectId bId = blob("a\nb\nc\n\0\0\0d\n");
  475. DiffEntry a = DiffEntry.add(PATH_A, aId);
  476. DiffEntry b = DiffEntry.delete(PATH_Q, bId);
  477. rd.add(a);
  478. rd.add(b);
  479. rd.setRenameScore(40);
  480. rd.setSkipContentRenamesForBinaryFiles(true);
  481. List<DiffEntry> entries = rd.compute();
  482. assertEquals(2, entries.size());
  483. assertAdd(PATH_A, aId, FileMode.REGULAR_FILE, entries.get(0));
  484. assertDelete(PATH_Q, bId, FileMode.REGULAR_FILE, entries.get(1));
  485. }
  486. @Test
  487. public void testSetRenameScore_IllegalArgs() throws Exception {
  488. try {
  489. rd.setRenameScore(-1);
  490. fail();
  491. } catch (IllegalArgumentException e) {
  492. // pass
  493. }
  494. try {
  495. rd.setRenameScore(101);
  496. fail();
  497. } catch (IllegalArgumentException e) {
  498. // pass
  499. }
  500. }
  501. @Test
  502. public void testRenameLimit() throws Exception {
  503. ObjectId aId = blob("foo\nbar\nbaz\nblarg\n");
  504. ObjectId bId = blob("foo\nbar\nbaz\nblah\n");
  505. DiffEntry a = DiffEntry.add(PATH_A, aId);
  506. DiffEntry b = DiffEntry.delete(PATH_B, bId);
  507. ObjectId cId = blob("a\nb\nc\nd\n");
  508. ObjectId dId = blob("a\nb\nc\n");
  509. DiffEntry c = DiffEntry.add(PATH_H, cId);
  510. DiffEntry d = DiffEntry.delete(PATH_Q, dId);
  511. rd.add(a);
  512. rd.add(b);
  513. rd.add(c);
  514. rd.add(d);
  515. rd.setRenameLimit(1);
  516. assertTrue(rd.isOverRenameLimit());
  517. List<DiffEntry> entries = rd.compute();
  518. assertEquals(4, entries.size());
  519. assertSame(a, entries.get(0));
  520. assertSame(b, entries.get(1));
  521. assertSame(c, entries.get(2));
  522. assertSame(d, entries.get(3));
  523. }
  524. private ObjectId blob(String content) throws Exception {
  525. return testDb.blob(content).copy();
  526. }
  527. private static void assertRename(DiffEntry o, DiffEntry n, int score,
  528. DiffEntry rename) {
  529. assertEquals(ChangeType.RENAME, rename.getChangeType());
  530. assertEquals(o.getOldPath(), rename.getOldPath());
  531. assertEquals(n.getNewPath(), rename.getNewPath());
  532. assertEquals(o.getOldMode(), rename.getOldMode());
  533. assertEquals(n.getNewMode(), rename.getNewMode());
  534. assertEquals(o.getOldId(), rename.getOldId());
  535. assertEquals(n.getNewId(), rename.getNewId());
  536. assertEquals(score, rename.getScore());
  537. }
  538. private static void assertCopy(DiffEntry o, DiffEntry n, int score,
  539. DiffEntry copy) {
  540. assertEquals(ChangeType.COPY, copy.getChangeType());
  541. assertEquals(o.getOldPath(), copy.getOldPath());
  542. assertEquals(n.getNewPath(), copy.getNewPath());
  543. assertEquals(o.getOldMode(), copy.getOldMode());
  544. assertEquals(n.getNewMode(), copy.getNewMode());
  545. assertEquals(o.getOldId(), copy.getOldId());
  546. assertEquals(n.getNewId(), copy.getNewId());
  547. assertEquals(score, copy.getScore());
  548. }
  549. private static void assertAdd(String newName, ObjectId newId,
  550. FileMode newMode, DiffEntry add) {
  551. assertEquals(DiffEntry.DEV_NULL, add.oldPath);
  552. assertEquals(DiffEntry.A_ZERO, add.oldId);
  553. assertEquals(FileMode.MISSING, add.oldMode);
  554. assertEquals(ChangeType.ADD, add.changeType);
  555. assertEquals(newName, add.newPath);
  556. assertEquals(AbbreviatedObjectId.fromObjectId(newId), add.newId);
  557. assertEquals(newMode, add.newMode);
  558. }
  559. private static void assertDelete(String oldName, ObjectId oldId,
  560. FileMode oldMode, DiffEntry delete) {
  561. assertEquals(DiffEntry.DEV_NULL, delete.newPath);
  562. assertEquals(DiffEntry.A_ZERO, delete.newId);
  563. assertEquals(FileMode.MISSING, delete.newMode);
  564. assertEquals(ChangeType.DELETE, delete.changeType);
  565. assertEquals(oldName, delete.oldPath);
  566. assertEquals(AbbreviatedObjectId.fromObjectId(oldId), delete.oldId);
  567. assertEquals(oldMode, delete.oldMode);
  568. }
  569. }