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.

ApplyCommandTest.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. * Copyright (C) 2011, 2021 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.api;
  11. import static org.junit.Assert.assertEquals;
  12. import static org.junit.Assert.assertFalse;
  13. import static org.junit.Assert.assertTrue;
  14. import static org.junit.Assert.fail;
  15. import java.io.ByteArrayOutputStream;
  16. import java.io.File;
  17. import java.io.IOException;
  18. import java.io.InputStream;
  19. import java.io.OutputStream;
  20. import org.eclipse.jgit.api.errors.PatchApplyException;
  21. import org.eclipse.jgit.api.errors.PatchFormatException;
  22. import org.eclipse.jgit.attributes.FilterCommand;
  23. import org.eclipse.jgit.attributes.FilterCommandFactory;
  24. import org.eclipse.jgit.attributes.FilterCommandRegistry;
  25. import org.eclipse.jgit.diff.RawText;
  26. import org.eclipse.jgit.junit.RepositoryTestCase;
  27. import org.eclipse.jgit.lib.Config;
  28. import org.eclipse.jgit.lib.ConfigConstants;
  29. import org.junit.Test;
  30. public class ApplyCommandTest extends RepositoryTestCase {
  31. private RawText a;
  32. private RawText b;
  33. private ApplyResult init(String name) throws Exception {
  34. return init(name, true, true);
  35. }
  36. private ApplyResult init(final String name, final boolean preExists,
  37. final boolean postExists) throws Exception {
  38. try (Git git = new Git(db)) {
  39. if (preExists) {
  40. a = new RawText(readFile(name + "_PreImage"));
  41. write(new File(db.getDirectory().getParent(), name),
  42. a.getString(0, a.size(), false));
  43. git.add().addFilepattern(name).call();
  44. git.commit().setMessage("PreImage").call();
  45. }
  46. if (postExists) {
  47. b = new RawText(readFile(name + "_PostImage"));
  48. }
  49. return git
  50. .apply()
  51. .setPatch(getTestResource(name + ".patch")).call();
  52. }
  53. }
  54. @Test
  55. public void testCrLf() throws Exception {
  56. try {
  57. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  58. ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
  59. ApplyResult result = init("crlf", true, true);
  60. assertEquals(1, result.getUpdatedFiles().size());
  61. assertEquals(new File(db.getWorkTree(), "crlf"),
  62. result.getUpdatedFiles().get(0));
  63. checkFile(new File(db.getWorkTree(), "crlf"),
  64. b.getString(0, b.size(), false));
  65. } finally {
  66. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  67. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  68. }
  69. }
  70. @Test
  71. public void testCrLfOff() throws Exception {
  72. try {
  73. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  74. ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
  75. ApplyResult result = init("crlf", true, true);
  76. assertEquals(1, result.getUpdatedFiles().size());
  77. assertEquals(new File(db.getWorkTree(), "crlf"),
  78. result.getUpdatedFiles().get(0));
  79. checkFile(new File(db.getWorkTree(), "crlf"),
  80. b.getString(0, b.size(), false));
  81. } finally {
  82. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  83. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  84. }
  85. }
  86. @Test
  87. public void testCrLfEmptyCommitted() throws Exception {
  88. try {
  89. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  90. ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
  91. ApplyResult result = init("crlf3", true, true);
  92. assertEquals(1, result.getUpdatedFiles().size());
  93. assertEquals(new File(db.getWorkTree(), "crlf3"),
  94. result.getUpdatedFiles().get(0));
  95. checkFile(new File(db.getWorkTree(), "crlf3"),
  96. b.getString(0, b.size(), false));
  97. } finally {
  98. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  99. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  100. }
  101. }
  102. @Test
  103. public void testCrLfNewFile() throws Exception {
  104. try {
  105. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  106. ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
  107. ApplyResult result = init("crlf4", false, true);
  108. assertEquals(1, result.getUpdatedFiles().size());
  109. assertEquals(new File(db.getWorkTree(), "crlf4"),
  110. result.getUpdatedFiles().get(0));
  111. checkFile(new File(db.getWorkTree(), "crlf4"),
  112. b.getString(0, b.size(), false));
  113. } finally {
  114. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  115. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  116. }
  117. }
  118. @Test
  119. public void testPatchWithCrLf() throws Exception {
  120. try {
  121. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  122. ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
  123. ApplyResult result = init("crlf2", true, true);
  124. assertEquals(1, result.getUpdatedFiles().size());
  125. assertEquals(new File(db.getWorkTree(), "crlf2"),
  126. result.getUpdatedFiles().get(0));
  127. checkFile(new File(db.getWorkTree(), "crlf2"),
  128. b.getString(0, b.size(), false));
  129. } finally {
  130. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  131. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  132. }
  133. }
  134. @Test
  135. public void testPatchWithCrLf2() throws Exception {
  136. String name = "crlf2";
  137. try (Git git = new Git(db)) {
  138. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  139. ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
  140. a = new RawText(readFile(name + "_PreImage"));
  141. write(new File(db.getWorkTree(), name),
  142. a.getString(0, a.size(), false));
  143. git.add().addFilepattern(name).call();
  144. git.commit().setMessage("PreImage").call();
  145. b = new RawText(readFile(name + "_PostImage"));
  146. db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  147. ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
  148. ApplyResult result = git.apply()
  149. .setPatch(getTestResource(name + ".patch")).call();
  150. assertEquals(1, result.getUpdatedFiles().size());
  151. assertEquals(new File(db.getWorkTree(), name),
  152. result.getUpdatedFiles().get(0));
  153. checkFile(new File(db.getWorkTree(), name),
  154. b.getString(0, b.size(), false));
  155. } finally {
  156. db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
  157. ConfigConstants.CONFIG_KEY_AUTOCRLF);
  158. }
  159. }
  160. // Clean/smudge filter for testFiltering. The smudgetest test resources were
  161. // created with C git using a clean filter sed -e "s/A/E/g" and the smudge
  162. // filter sed -e "s/E/A/g". To keep the test independent of the presence of
  163. // sed, implement this with a built-in filter.
  164. private static class ReplaceFilter extends FilterCommand {
  165. private final char toReplace;
  166. private final char replacement;
  167. ReplaceFilter(InputStream in, OutputStream out, char toReplace,
  168. char replacement) {
  169. super(in, out);
  170. this.toReplace = toReplace;
  171. this.replacement = replacement;
  172. }
  173. @Override
  174. public int run() throws IOException {
  175. int b = in.read();
  176. if (b < 0) {
  177. in.close();
  178. out.close();
  179. return -1;
  180. }
  181. if ((b & 0xFF) == toReplace) {
  182. b = replacement;
  183. }
  184. out.write(b);
  185. return 1;
  186. }
  187. }
  188. @Test
  189. public void testFiltering() throws Exception {
  190. // Set up filter
  191. FilterCommandFactory clean = (repo, in, out) -> {
  192. return new ReplaceFilter(in, out, 'A', 'E');
  193. };
  194. FilterCommandFactory smudge = (repo, in, out) -> {
  195. return new ReplaceFilter(in, out, 'E', 'A');
  196. };
  197. FilterCommandRegistry.register("jgit://builtin/a2e/clean", clean);
  198. FilterCommandRegistry.register("jgit://builtin/a2e/smudge", smudge);
  199. try (Git git = new Git(db)) {
  200. Config config = db.getConfig();
  201. config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
  202. "clean", "jgit://builtin/a2e/clean");
  203. config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
  204. "smudge", "jgit://builtin/a2e/smudge");
  205. write(new File(db.getWorkTree(), ".gitattributes"),
  206. "smudgetest filter=a2e");
  207. git.add().addFilepattern(".gitattributes").call();
  208. git.commit().setMessage("Attributes").call();
  209. ApplyResult result = init("smudgetest", true, true);
  210. assertEquals(1, result.getUpdatedFiles().size());
  211. assertEquals(new File(db.getWorkTree(), "smudgetest"),
  212. result.getUpdatedFiles().get(0));
  213. checkFile(new File(db.getWorkTree(), "smudgetest"),
  214. b.getString(0, b.size(), false));
  215. } finally {
  216. // Tear down filter
  217. FilterCommandRegistry.unregister("jgit://builtin/a2e/clean");
  218. FilterCommandRegistry.unregister("jgit://builtin/a2e/smudge");
  219. }
  220. }
  221. @Test
  222. public void testAddA1() throws Exception {
  223. ApplyResult result = init("A1", false, true);
  224. assertEquals(1, result.getUpdatedFiles().size());
  225. assertEquals(new File(db.getWorkTree(), "A1"), result.getUpdatedFiles()
  226. .get(0));
  227. checkFile(new File(db.getWorkTree(), "A1"),
  228. b.getString(0, b.size(), false));
  229. }
  230. @Test
  231. public void testAddA2() throws Exception {
  232. ApplyResult result = init("A2", false, true);
  233. assertEquals(1, result.getUpdatedFiles().size());
  234. assertEquals(new File(db.getWorkTree(), "A2"), result.getUpdatedFiles()
  235. .get(0));
  236. checkFile(new File(db.getWorkTree(), "A2"),
  237. b.getString(0, b.size(), false));
  238. }
  239. @Test
  240. public void testAddA3() throws Exception {
  241. ApplyResult result = init("A3", false, true);
  242. assertEquals(1, result.getUpdatedFiles().size());
  243. assertEquals(new File(db.getWorkTree(), "A3"),
  244. result.getUpdatedFiles().get(0));
  245. checkFile(new File(db.getWorkTree(), "A3"),
  246. b.getString(0, b.size(), false));
  247. }
  248. @Test
  249. public void testAddA1Sub() throws Exception {
  250. ApplyResult result = init("A1_sub", false, false);
  251. assertEquals(1, result.getUpdatedFiles().size());
  252. assertEquals(new File(db.getWorkTree(), "sub/A1"), result
  253. .getUpdatedFiles().get(0));
  254. }
  255. @Test
  256. public void testDeleteD() throws Exception {
  257. ApplyResult result = init("D", true, false);
  258. assertEquals(1, result.getUpdatedFiles().size());
  259. assertEquals(new File(db.getWorkTree(), "D"), result.getUpdatedFiles()
  260. .get(0));
  261. assertFalse(new File(db.getWorkTree(), "D").exists());
  262. }
  263. @Test(expected = PatchFormatException.class)
  264. public void testFailureF1() throws Exception {
  265. init("F1", true, false);
  266. }
  267. @Test(expected = PatchApplyException.class)
  268. public void testFailureF2() throws Exception {
  269. init("F2", true, false);
  270. }
  271. @Test
  272. public void testModifyE() throws Exception {
  273. ApplyResult result = init("E");
  274. assertEquals(1, result.getUpdatedFiles().size());
  275. assertEquals(new File(db.getWorkTree(), "E"), result.getUpdatedFiles()
  276. .get(0));
  277. checkFile(new File(db.getWorkTree(), "E"),
  278. b.getString(0, b.size(), false));
  279. }
  280. @Test
  281. public void testModifyW() throws Exception {
  282. ApplyResult result = init("W");
  283. assertEquals(1, result.getUpdatedFiles().size());
  284. assertEquals(new File(db.getWorkTree(), "W"),
  285. result.getUpdatedFiles().get(0));
  286. checkFile(new File(db.getWorkTree(), "W"),
  287. b.getString(0, b.size(), false));
  288. }
  289. @Test
  290. public void testAddM1() throws Exception {
  291. ApplyResult result = init("M1", false, true);
  292. assertEquals(1, result.getUpdatedFiles().size());
  293. assertTrue(result.getUpdatedFiles().get(0).canExecute());
  294. checkFile(new File(db.getWorkTree(), "M1"),
  295. b.getString(0, b.size(), false));
  296. }
  297. @Test
  298. public void testModifyM2() throws Exception {
  299. ApplyResult result = init("M2", true, true);
  300. assertEquals(1, result.getUpdatedFiles().size());
  301. assertTrue(result.getUpdatedFiles().get(0).canExecute());
  302. checkFile(new File(db.getWorkTree(), "M2"),
  303. b.getString(0, b.size(), false));
  304. }
  305. @Test
  306. public void testModifyM3() throws Exception {
  307. ApplyResult result = init("M3", true, true);
  308. assertEquals(1, result.getUpdatedFiles().size());
  309. assertFalse(result.getUpdatedFiles().get(0).canExecute());
  310. checkFile(new File(db.getWorkTree(), "M3"),
  311. b.getString(0, b.size(), false));
  312. }
  313. @Test
  314. public void testModifyX() throws Exception {
  315. ApplyResult result = init("X");
  316. assertEquals(1, result.getUpdatedFiles().size());
  317. assertEquals(new File(db.getWorkTree(), "X"), result.getUpdatedFiles()
  318. .get(0));
  319. checkFile(new File(db.getWorkTree(), "X"),
  320. b.getString(0, b.size(), false));
  321. }
  322. @Test
  323. public void testModifyY() throws Exception {
  324. ApplyResult result = init("Y");
  325. assertEquals(1, result.getUpdatedFiles().size());
  326. assertEquals(new File(db.getWorkTree(), "Y"), result.getUpdatedFiles()
  327. .get(0));
  328. checkFile(new File(db.getWorkTree(), "Y"),
  329. b.getString(0, b.size(), false));
  330. }
  331. @Test
  332. public void testModifyZ() throws Exception {
  333. ApplyResult result = init("Z");
  334. assertEquals(1, result.getUpdatedFiles().size());
  335. assertEquals(new File(db.getWorkTree(), "Z"), result.getUpdatedFiles()
  336. .get(0));
  337. checkFile(new File(db.getWorkTree(), "Z"),
  338. b.getString(0, b.size(), false));
  339. }
  340. @Test
  341. public void testModifyNL1() throws Exception {
  342. ApplyResult result = init("NL1");
  343. assertEquals(1, result.getUpdatedFiles().size());
  344. assertEquals(new File(db.getWorkTree(), "NL1"), result
  345. .getUpdatedFiles().get(0));
  346. checkFile(new File(db.getWorkTree(), "NL1"),
  347. b.getString(0, b.size(), false));
  348. }
  349. @Test
  350. public void testNonASCII() throws Exception {
  351. ApplyResult result = init("NonASCII");
  352. assertEquals(1, result.getUpdatedFiles().size());
  353. assertEquals(new File(db.getWorkTree(), "NonASCII"),
  354. result.getUpdatedFiles().get(0));
  355. checkFile(new File(db.getWorkTree(), "NonASCII"),
  356. b.getString(0, b.size(), false));
  357. }
  358. @Test
  359. public void testNonASCII2() throws Exception {
  360. ApplyResult result = init("NonASCII2");
  361. assertEquals(1, result.getUpdatedFiles().size());
  362. assertEquals(new File(db.getWorkTree(), "NonASCII2"),
  363. result.getUpdatedFiles().get(0));
  364. checkFile(new File(db.getWorkTree(), "NonASCII2"),
  365. b.getString(0, b.size(), false));
  366. }
  367. @Test
  368. public void testNonASCIIAdd() throws Exception {
  369. ApplyResult result = init("NonASCIIAdd");
  370. assertEquals(1, result.getUpdatedFiles().size());
  371. assertEquals(new File(db.getWorkTree(), "NonASCIIAdd"),
  372. result.getUpdatedFiles().get(0));
  373. checkFile(new File(db.getWorkTree(), "NonASCIIAdd"),
  374. b.getString(0, b.size(), false));
  375. }
  376. @Test
  377. public void testNonASCIIAdd2() throws Exception {
  378. ApplyResult result = init("NonASCIIAdd2", false, true);
  379. assertEquals(1, result.getUpdatedFiles().size());
  380. assertEquals(new File(db.getWorkTree(), "NonASCIIAdd2"),
  381. result.getUpdatedFiles().get(0));
  382. checkFile(new File(db.getWorkTree(), "NonASCIIAdd2"),
  383. b.getString(0, b.size(), false));
  384. }
  385. @Test
  386. public void testNonASCIIDel() throws Exception {
  387. ApplyResult result = init("NonASCIIDel", true, false);
  388. assertEquals(1, result.getUpdatedFiles().size());
  389. assertEquals(new File(db.getWorkTree(), "NonASCIIDel"),
  390. result.getUpdatedFiles().get(0));
  391. assertFalse(new File(db.getWorkTree(), "NonASCIIDel").exists());
  392. }
  393. @Test
  394. public void testRenameNoHunks() throws Exception {
  395. ApplyResult result = init("RenameNoHunks", true, true);
  396. assertEquals(1, result.getUpdatedFiles().size());
  397. assertEquals(new File(db.getWorkTree(), "RenameNoHunks"), result.getUpdatedFiles()
  398. .get(0));
  399. checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"),
  400. b.getString(0, b.size(), false));
  401. }
  402. @Test
  403. public void testRenameWithHunks() throws Exception {
  404. ApplyResult result = init("RenameWithHunks", true, true);
  405. assertEquals(1, result.getUpdatedFiles().size());
  406. assertEquals(new File(db.getWorkTree(), "RenameWithHunks"), result.getUpdatedFiles()
  407. .get(0));
  408. checkFile(new File(db.getWorkTree(), "nested/subdir/Renamed"),
  409. b.getString(0, b.size(), false));
  410. }
  411. @Test
  412. public void testCopyWithHunks() throws Exception {
  413. ApplyResult result = init("CopyWithHunks", true, true);
  414. assertEquals(1, result.getUpdatedFiles().size());
  415. assertEquals(new File(db.getWorkTree(), "CopyWithHunks"), result.getUpdatedFiles()
  416. .get(0));
  417. checkFile(new File(db.getWorkTree(), "CopyResult"),
  418. b.getString(0, b.size(), false));
  419. }
  420. @Test
  421. public void testShiftUp() throws Exception {
  422. ApplyResult result = init("ShiftUp");
  423. assertEquals(1, result.getUpdatedFiles().size());
  424. assertEquals(new File(db.getWorkTree(), "ShiftUp"),
  425. result.getUpdatedFiles().get(0));
  426. checkFile(new File(db.getWorkTree(), "ShiftUp"),
  427. b.getString(0, b.size(), false));
  428. }
  429. @Test
  430. public void testShiftUp2() throws Exception {
  431. ApplyResult result = init("ShiftUp2");
  432. assertEquals(1, result.getUpdatedFiles().size());
  433. assertEquals(new File(db.getWorkTree(), "ShiftUp2"),
  434. result.getUpdatedFiles().get(0));
  435. checkFile(new File(db.getWorkTree(), "ShiftUp2"),
  436. b.getString(0, b.size(), false));
  437. }
  438. @Test
  439. public void testShiftDown() throws Exception {
  440. ApplyResult result = init("ShiftDown");
  441. assertEquals(1, result.getUpdatedFiles().size());
  442. assertEquals(new File(db.getWorkTree(), "ShiftDown"),
  443. result.getUpdatedFiles().get(0));
  444. checkFile(new File(db.getWorkTree(), "ShiftDown"),
  445. b.getString(0, b.size(), false));
  446. }
  447. @Test
  448. public void testShiftDown2() throws Exception {
  449. ApplyResult result = init("ShiftDown2");
  450. assertEquals(1, result.getUpdatedFiles().size());
  451. assertEquals(new File(db.getWorkTree(), "ShiftDown2"),
  452. result.getUpdatedFiles().get(0));
  453. checkFile(new File(db.getWorkTree(), "ShiftDown2"),
  454. b.getString(0, b.size(), false));
  455. }
  456. private static byte[] readFile(String patchFile) throws IOException {
  457. final InputStream in = getTestResource(patchFile);
  458. if (in == null) {
  459. fail("No " + patchFile + " test vector");
  460. return null; // Never happens
  461. }
  462. try {
  463. final byte[] buf = new byte[1024];
  464. final ByteArrayOutputStream temp = new ByteArrayOutputStream();
  465. int n;
  466. while ((n = in.read(buf)) > 0)
  467. temp.write(buf, 0, n);
  468. return temp.toByteArray();
  469. } finally {
  470. in.close();
  471. }
  472. }
  473. private static InputStream getTestResource(String patchFile) {
  474. return ApplyCommandTest.class.getClassLoader()
  475. .getResourceAsStream("org/eclipse/jgit/diff/" + patchFile);
  476. }
  477. }