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.

AddCommandTest.java 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /*
  2. * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
  3. * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
  4. * and other copyright owners as documented in the project's IP log.
  5. *
  6. * This program and the accompanying materials are made available
  7. * under the terms of the Eclipse Distribution License v1.0 which
  8. * accompanies this distribution, is reproduced below, and is
  9. * available at http://www.eclipse.org/org/documents/edl-v10.php
  10. *
  11. * All rights reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or
  14. * without modification, are permitted provided that the following
  15. * conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. *
  20. * - Redistributions in binary form must reproduce the above
  21. * copyright notice, this list of conditions and the following
  22. * disclaimer in the documentation and/or other materials provided
  23. * with the distribution.
  24. *
  25. * - Neither the name of the Eclipse Foundation, Inc. nor the
  26. * names of its contributors may be used to endorse or promote
  27. * products derived from this software without specific prior
  28. * written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  31. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  32. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  33. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  35. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  39. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  42. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43. */
  44. package org.eclipse.jgit.api;
  45. import static org.junit.Assert.assertEquals;
  46. import static org.junit.Assert.assertNotNull;
  47. import static org.junit.Assert.fail;
  48. import java.io.File;
  49. import java.io.FileInputStream;
  50. import java.io.IOException;
  51. import java.io.PrintWriter;
  52. import org.eclipse.jgit.api.errors.GitAPIException;
  53. import org.eclipse.jgit.api.errors.NoFilepatternException;
  54. import org.eclipse.jgit.dircache.DirCache;
  55. import org.eclipse.jgit.dircache.DirCacheBuilder;
  56. import org.eclipse.jgit.dircache.DirCacheEntry;
  57. import org.eclipse.jgit.junit.RepositoryTestCase;
  58. import org.eclipse.jgit.lib.ConfigConstants;
  59. import org.eclipse.jgit.lib.Constants;
  60. import org.eclipse.jgit.lib.FileMode;
  61. import org.eclipse.jgit.lib.ObjectId;
  62. import org.eclipse.jgit.lib.ObjectInserter;
  63. import org.eclipse.jgit.lib.StoredConfig;
  64. import org.eclipse.jgit.revwalk.RevCommit;
  65. import org.eclipse.jgit.treewalk.TreeWalk;
  66. import org.eclipse.jgit.util.FS;
  67. import org.eclipse.jgit.util.FileUtils;
  68. import org.junit.Test;
  69. public class AddCommandTest extends RepositoryTestCase {
  70. @Test
  71. public void testAddNothing() throws GitAPIException {
  72. Git git = new Git(db);
  73. try {
  74. git.add().call();
  75. fail("Expected IllegalArgumentException");
  76. } catch (NoFilepatternException e) {
  77. // expected
  78. }
  79. }
  80. @Test
  81. public void testAddNonExistingSingleFile() throws GitAPIException {
  82. Git git = new Git(db);
  83. DirCache dc = git.add().addFilepattern("a.txt").call();
  84. assertEquals(0, dc.getEntryCount());
  85. }
  86. @Test
  87. public void testAddExistingSingleFile() throws IOException, GitAPIException {
  88. File file = new File(db.getWorkTree(), "a.txt");
  89. FileUtils.createNewFile(file);
  90. PrintWriter writer = new PrintWriter(file);
  91. writer.print("content");
  92. writer.close();
  93. Git git = new Git(db);
  94. git.add().addFilepattern("a.txt").call();
  95. assertEquals(
  96. "[a.txt, mode:100644, content:content]",
  97. indexState(CONTENT));
  98. }
  99. @Test
  100. public void testAddExistingSingleSmallFileWithNewLine() throws IOException,
  101. GitAPIException {
  102. File file = new File(db.getWorkTree(), "a.txt");
  103. FileUtils.createNewFile(file);
  104. PrintWriter writer = new PrintWriter(file);
  105. writer.print("row1\r\nrow2");
  106. writer.close();
  107. Git git = new Git(db);
  108. db.getConfig().setString("core", null, "autocrlf", "false");
  109. git.add().addFilepattern("a.txt").call();
  110. assertEquals("[a.txt, mode:100644, content:row1\r\nrow2]",
  111. indexState(CONTENT));
  112. db.getConfig().setString("core", null, "autocrlf", "true");
  113. git.add().addFilepattern("a.txt").call();
  114. assertEquals("[a.txt, mode:100644, content:row1\nrow2]",
  115. indexState(CONTENT));
  116. db.getConfig().setString("core", null, "autocrlf", "input");
  117. git.add().addFilepattern("a.txt").call();
  118. assertEquals("[a.txt, mode:100644, content:row1\nrow2]",
  119. indexState(CONTENT));
  120. }
  121. @Test
  122. public void testAddExistingSingleMediumSizeFileWithNewLine()
  123. throws IOException, GitAPIException {
  124. File file = new File(db.getWorkTree(), "a.txt");
  125. FileUtils.createNewFile(file);
  126. StringBuilder data = new StringBuilder();
  127. for (int i = 0; i < 1000; ++i) {
  128. data.append("row1\r\nrow2");
  129. }
  130. String crData = data.toString();
  131. PrintWriter writer = new PrintWriter(file);
  132. writer.print(crData);
  133. writer.close();
  134. String lfData = data.toString().replaceAll("\r", "");
  135. Git git = new Git(db);
  136. db.getConfig().setString("core", null, "autocrlf", "false");
  137. git.add().addFilepattern("a.txt").call();
  138. assertEquals("[a.txt, mode:100644, content:" + data + "]",
  139. indexState(CONTENT));
  140. db.getConfig().setString("core", null, "autocrlf", "true");
  141. git.add().addFilepattern("a.txt").call();
  142. assertEquals("[a.txt, mode:100644, content:" + lfData + "]",
  143. indexState(CONTENT));
  144. db.getConfig().setString("core", null, "autocrlf", "input");
  145. git.add().addFilepattern("a.txt").call();
  146. assertEquals("[a.txt, mode:100644, content:" + lfData + "]",
  147. indexState(CONTENT));
  148. }
  149. @Test
  150. public void testAddExistingSingleBinaryFile() throws IOException,
  151. GitAPIException {
  152. File file = new File(db.getWorkTree(), "a.txt");
  153. FileUtils.createNewFile(file);
  154. PrintWriter writer = new PrintWriter(file);
  155. writer.print("row1\r\nrow2\u0000");
  156. writer.close();
  157. Git git = new Git(db);
  158. db.getConfig().setString("core", null, "autocrlf", "false");
  159. git.add().addFilepattern("a.txt").call();
  160. assertEquals("[a.txt, mode:100644, content:row1\r\nrow2\u0000]",
  161. indexState(CONTENT));
  162. db.getConfig().setString("core", null, "autocrlf", "true");
  163. git.add().addFilepattern("a.txt").call();
  164. assertEquals("[a.txt, mode:100644, content:row1\r\nrow2\u0000]",
  165. indexState(CONTENT));
  166. db.getConfig().setString("core", null, "autocrlf", "input");
  167. git.add().addFilepattern("a.txt").call();
  168. assertEquals("[a.txt, mode:100644, content:row1\r\nrow2\u0000]",
  169. indexState(CONTENT));
  170. }
  171. @Test
  172. public void testAddExistingSingleFileInSubDir() throws IOException,
  173. GitAPIException {
  174. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  175. File file = new File(db.getWorkTree(), "sub/a.txt");
  176. FileUtils.createNewFile(file);
  177. PrintWriter writer = new PrintWriter(file);
  178. writer.print("content");
  179. writer.close();
  180. Git git = new Git(db);
  181. git.add().addFilepattern("sub/a.txt").call();
  182. assertEquals(
  183. "[sub/a.txt, mode:100644, content:content]",
  184. indexState(CONTENT));
  185. }
  186. @Test
  187. public void testAddExistingSingleFileTwice() throws IOException,
  188. GitAPIException {
  189. File file = new File(db.getWorkTree(), "a.txt");
  190. FileUtils.createNewFile(file);
  191. PrintWriter writer = new PrintWriter(file);
  192. writer.print("content");
  193. writer.close();
  194. Git git = new Git(db);
  195. DirCache dc = git.add().addFilepattern("a.txt").call();
  196. dc.getEntry(0).getObjectId();
  197. writer = new PrintWriter(file);
  198. writer.print("other content");
  199. writer.close();
  200. dc = git.add().addFilepattern("a.txt").call();
  201. assertEquals(
  202. "[a.txt, mode:100644, content:other content]",
  203. indexState(CONTENT));
  204. }
  205. @Test
  206. public void testAddExistingSingleFileTwiceWithCommit() throws Exception {
  207. File file = new File(db.getWorkTree(), "a.txt");
  208. FileUtils.createNewFile(file);
  209. PrintWriter writer = new PrintWriter(file);
  210. writer.print("content");
  211. writer.close();
  212. Git git = new Git(db);
  213. DirCache dc = git.add().addFilepattern("a.txt").call();
  214. dc.getEntry(0).getObjectId();
  215. git.commit().setMessage("commit a.txt").call();
  216. writer = new PrintWriter(file);
  217. writer.print("other content");
  218. writer.close();
  219. dc = git.add().addFilepattern("a.txt").call();
  220. assertEquals(
  221. "[a.txt, mode:100644, content:other content]",
  222. indexState(CONTENT));
  223. }
  224. @Test
  225. public void testAddRemovedFile() throws Exception {
  226. File file = new File(db.getWorkTree(), "a.txt");
  227. FileUtils.createNewFile(file);
  228. PrintWriter writer = new PrintWriter(file);
  229. writer.print("content");
  230. writer.close();
  231. Git git = new Git(db);
  232. DirCache dc = git.add().addFilepattern("a.txt").call();
  233. dc.getEntry(0).getObjectId();
  234. FileUtils.delete(file);
  235. // is supposed to do nothing
  236. dc = git.add().addFilepattern("a.txt").call();
  237. assertEquals(
  238. "[a.txt, mode:100644, content:content]",
  239. indexState(CONTENT));
  240. }
  241. @Test
  242. public void testAddRemovedCommittedFile() throws Exception {
  243. File file = new File(db.getWorkTree(), "a.txt");
  244. FileUtils.createNewFile(file);
  245. PrintWriter writer = new PrintWriter(file);
  246. writer.print("content");
  247. writer.close();
  248. Git git = new Git(db);
  249. DirCache dc = git.add().addFilepattern("a.txt").call();
  250. git.commit().setMessage("commit a.txt").call();
  251. dc.getEntry(0).getObjectId();
  252. FileUtils.delete(file);
  253. // is supposed to do nothing
  254. dc = git.add().addFilepattern("a.txt").call();
  255. assertEquals(
  256. "[a.txt, mode:100644, content:content]",
  257. indexState(CONTENT));
  258. }
  259. @Test
  260. public void testAddWithConflicts() throws Exception {
  261. // prepare conflict
  262. File file = new File(db.getWorkTree(), "a.txt");
  263. FileUtils.createNewFile(file);
  264. PrintWriter writer = new PrintWriter(file);
  265. writer.print("content");
  266. writer.close();
  267. File file2 = new File(db.getWorkTree(), "b.txt");
  268. FileUtils.createNewFile(file2);
  269. writer = new PrintWriter(file2);
  270. writer.print("content b");
  271. writer.close();
  272. ObjectInserter newObjectInserter = db.newObjectInserter();
  273. DirCache dc = db.lockDirCache();
  274. DirCacheBuilder builder = dc.builder();
  275. addEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0);
  276. addEntryToBuilder("a.txt", file, newObjectInserter, builder, 1);
  277. writer = new PrintWriter(file);
  278. writer.print("other content");
  279. writer.close();
  280. addEntryToBuilder("a.txt", file, newObjectInserter, builder, 3);
  281. writer = new PrintWriter(file);
  282. writer.print("our content");
  283. writer.close();
  284. addEntryToBuilder("a.txt", file, newObjectInserter, builder, 2)
  285. .getObjectId();
  286. builder.commit();
  287. assertEquals(
  288. "[a.txt, mode:100644, stage:1, content:content]" +
  289. "[a.txt, mode:100644, stage:2, content:our content]" +
  290. "[a.txt, mode:100644, stage:3, content:other content]" +
  291. "[b.txt, mode:100644, content:content b]",
  292. indexState(CONTENT));
  293. // now the test begins
  294. Git git = new Git(db);
  295. dc = git.add().addFilepattern("a.txt").call();
  296. assertEquals(
  297. "[a.txt, mode:100644, content:our content]" +
  298. "[b.txt, mode:100644, content:content b]",
  299. indexState(CONTENT));
  300. }
  301. @Test
  302. public void testAddTwoFiles() throws Exception {
  303. File file = new File(db.getWorkTree(), "a.txt");
  304. FileUtils.createNewFile(file);
  305. PrintWriter writer = new PrintWriter(file);
  306. writer.print("content");
  307. writer.close();
  308. File file2 = new File(db.getWorkTree(), "b.txt");
  309. FileUtils.createNewFile(file2);
  310. writer = new PrintWriter(file2);
  311. writer.print("content b");
  312. writer.close();
  313. Git git = new Git(db);
  314. git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
  315. assertEquals(
  316. "[a.txt, mode:100644, content:content]" +
  317. "[b.txt, mode:100644, content:content b]",
  318. indexState(CONTENT));
  319. }
  320. @Test
  321. public void testAddFolder() throws Exception {
  322. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  323. File file = new File(db.getWorkTree(), "sub/a.txt");
  324. FileUtils.createNewFile(file);
  325. PrintWriter writer = new PrintWriter(file);
  326. writer.print("content");
  327. writer.close();
  328. File file2 = new File(db.getWorkTree(), "sub/b.txt");
  329. FileUtils.createNewFile(file2);
  330. writer = new PrintWriter(file2);
  331. writer.print("content b");
  332. writer.close();
  333. Git git = new Git(db);
  334. git.add().addFilepattern("sub").call();
  335. assertEquals(
  336. "[sub/a.txt, mode:100644, content:content]" +
  337. "[sub/b.txt, mode:100644, content:content b]",
  338. indexState(CONTENT));
  339. }
  340. @Test
  341. public void testAddIgnoredFile() throws Exception {
  342. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  343. File file = new File(db.getWorkTree(), "sub/a.txt");
  344. FileUtils.createNewFile(file);
  345. PrintWriter writer = new PrintWriter(file);
  346. writer.print("content");
  347. writer.close();
  348. File ignoreFile = new File(db.getWorkTree(), ".gitignore");
  349. FileUtils.createNewFile(ignoreFile);
  350. writer = new PrintWriter(ignoreFile);
  351. writer.print("sub/b.txt");
  352. writer.close();
  353. File file2 = new File(db.getWorkTree(), "sub/b.txt");
  354. FileUtils.createNewFile(file2);
  355. writer = new PrintWriter(file2);
  356. writer.print("content b");
  357. writer.close();
  358. Git git = new Git(db);
  359. git.add().addFilepattern("sub").call();
  360. assertEquals(
  361. "[sub/a.txt, mode:100644, content:content]",
  362. indexState(CONTENT));
  363. }
  364. @Test
  365. public void testAddWholeRepo() throws Exception {
  366. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  367. File file = new File(db.getWorkTree(), "sub/a.txt");
  368. FileUtils.createNewFile(file);
  369. PrintWriter writer = new PrintWriter(file);
  370. writer.print("content");
  371. writer.close();
  372. File file2 = new File(db.getWorkTree(), "sub/b.txt");
  373. FileUtils.createNewFile(file2);
  374. writer = new PrintWriter(file2);
  375. writer.print("content b");
  376. writer.close();
  377. Git git = new Git(db);
  378. git.add().addFilepattern(".").call();
  379. assertEquals(
  380. "[sub/a.txt, mode:100644, content:content]" +
  381. "[sub/b.txt, mode:100644, content:content b]",
  382. indexState(CONTENT));
  383. }
  384. // the same three cases as in testAddWithParameterUpdate
  385. // file a exists in workdir and in index -> added
  386. // file b exists not in workdir but in index -> unchanged
  387. // file c exists in workdir but not in index -> added
  388. @Test
  389. public void testAddWithoutParameterUpdate() throws Exception {
  390. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  391. File file = new File(db.getWorkTree(), "sub/a.txt");
  392. FileUtils.createNewFile(file);
  393. PrintWriter writer = new PrintWriter(file);
  394. writer.print("content");
  395. writer.close();
  396. File file2 = new File(db.getWorkTree(), "sub/b.txt");
  397. FileUtils.createNewFile(file2);
  398. writer = new PrintWriter(file2);
  399. writer.print("content b");
  400. writer.close();
  401. Git git = new Git(db);
  402. git.add().addFilepattern("sub").call();
  403. assertEquals(
  404. "[sub/a.txt, mode:100644, content:content]" +
  405. "[sub/b.txt, mode:100644, content:content b]",
  406. indexState(CONTENT));
  407. git.commit().setMessage("commit").call();
  408. // new unstaged file sub/c.txt
  409. File file3 = new File(db.getWorkTree(), "sub/c.txt");
  410. FileUtils.createNewFile(file3);
  411. writer = new PrintWriter(file3);
  412. writer.print("content c");
  413. writer.close();
  414. // file sub/a.txt is modified
  415. writer = new PrintWriter(file);
  416. writer.print("modified content");
  417. writer.close();
  418. // file sub/b.txt is deleted
  419. FileUtils.delete(file2);
  420. git.add().addFilepattern("sub").call();
  421. // change in sub/a.txt is staged
  422. // deletion of sub/b.txt is not staged
  423. // sub/c.txt is staged
  424. assertEquals(
  425. "[sub/a.txt, mode:100644, content:modified content]" +
  426. "[sub/b.txt, mode:100644, content:content b]" +
  427. "[sub/c.txt, mode:100644, content:content c]",
  428. indexState(CONTENT));
  429. }
  430. // file a exists in workdir and in index -> added
  431. // file b exists not in workdir but in index -> deleted
  432. // file c exists in workdir but not in index -> unchanged
  433. @Test
  434. public void testAddWithParameterUpdate() throws Exception {
  435. FileUtils.mkdir(new File(db.getWorkTree(), "sub"));
  436. File file = new File(db.getWorkTree(), "sub/a.txt");
  437. FileUtils.createNewFile(file);
  438. PrintWriter writer = new PrintWriter(file);
  439. writer.print("content");
  440. writer.close();
  441. File file2 = new File(db.getWorkTree(), "sub/b.txt");
  442. FileUtils.createNewFile(file2);
  443. writer = new PrintWriter(file2);
  444. writer.print("content b");
  445. writer.close();
  446. Git git = new Git(db);
  447. git.add().addFilepattern("sub").call();
  448. assertEquals(
  449. "[sub/a.txt, mode:100644, content:content]" +
  450. "[sub/b.txt, mode:100644, content:content b]",
  451. indexState(CONTENT));
  452. git.commit().setMessage("commit").call();
  453. // new unstaged file sub/c.txt
  454. File file3 = new File(db.getWorkTree(), "sub/c.txt");
  455. FileUtils.createNewFile(file3);
  456. writer = new PrintWriter(file3);
  457. writer.print("content c");
  458. writer.close();
  459. // file sub/a.txt is modified
  460. writer = new PrintWriter(file);
  461. writer.print("modified content");
  462. writer.close();
  463. FileUtils.delete(file2);
  464. // change in sub/a.txt is staged
  465. // deletion of sub/b.txt is staged
  466. // sub/c.txt is not staged
  467. git.add().addFilepattern("sub").setUpdate(true).call();
  468. // change in sub/a.txt is staged
  469. assertEquals(
  470. "[sub/a.txt, mode:100644, content:modified content]",
  471. indexState(CONTENT));
  472. }
  473. @Test
  474. public void testAssumeUnchanged() throws Exception {
  475. Git git = new Git(db);
  476. String path = "a.txt";
  477. writeTrashFile(path, "content");
  478. git.add().addFilepattern(path).call();
  479. String path2 = "b.txt";
  480. writeTrashFile(path2, "content");
  481. git.add().addFilepattern(path2).call();
  482. git.commit().setMessage("commit").call();
  483. assertEquals("[a.txt, mode:100644, content:"
  484. + "content, assume-unchanged:false]"
  485. + "[b.txt, mode:100644, content:content, "
  486. + "assume-unchanged:false]", indexState(CONTENT
  487. | ASSUME_UNCHANGED));
  488. assumeUnchanged(path2);
  489. assertEquals("[a.txt, mode:100644, content:content, "
  490. + "assume-unchanged:false][b.txt, mode:100644, "
  491. + "content:content, assume-unchanged:true]", indexState(CONTENT
  492. | ASSUME_UNCHANGED));
  493. writeTrashFile(path, "more content");
  494. writeTrashFile(path2, "more content");
  495. git.add().addFilepattern(".").call();
  496. assertEquals("[a.txt, mode:100644, content:more content,"
  497. + " assume-unchanged:false][b.txt, mode:100644,"
  498. + "" + ""
  499. + " content:content, assume-unchanged:true]",
  500. indexState(CONTENT
  501. | ASSUME_UNCHANGED));
  502. }
  503. @Test
  504. public void testExecutableRetention() throws Exception {
  505. StoredConfig config = db.getConfig();
  506. config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  507. ConfigConstants.CONFIG_KEY_FILEMODE, true);
  508. config.save();
  509. FS executableFs = new FS() {
  510. public boolean supportsExecute() {
  511. return true;
  512. }
  513. public boolean setExecute(File f, boolean canExec) {
  514. return true;
  515. }
  516. public ProcessBuilder runInShell(String cmd, String[] args) {
  517. return null;
  518. }
  519. public boolean retryFailedLockFileCommit() {
  520. return false;
  521. }
  522. public FS newInstance() {
  523. return this;
  524. }
  525. protected File discoverGitPrefix() {
  526. return null;
  527. }
  528. public boolean canExecute(File f) {
  529. return true;
  530. }
  531. @Override
  532. public boolean isCaseSensitive() {
  533. return false;
  534. }
  535. };
  536. Git git = Git.open(db.getDirectory(), executableFs);
  537. String path = "a.txt";
  538. writeTrashFile(path, "content");
  539. git.add().addFilepattern(path).call();
  540. RevCommit commit1 = git.commit().setMessage("commit").call();
  541. TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree());
  542. assertNotNull(walk);
  543. assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
  544. FS nonExecutableFs = new FS() {
  545. public boolean supportsExecute() {
  546. return false;
  547. }
  548. public boolean setExecute(File f, boolean canExec) {
  549. return false;
  550. }
  551. public ProcessBuilder runInShell(String cmd, String[] args) {
  552. return null;
  553. }
  554. public boolean retryFailedLockFileCommit() {
  555. return false;
  556. }
  557. public FS newInstance() {
  558. return this;
  559. }
  560. protected File discoverGitPrefix() {
  561. return null;
  562. }
  563. public boolean canExecute(File f) {
  564. return false;
  565. }
  566. @Override
  567. public boolean isCaseSensitive() {
  568. return false;
  569. }
  570. };
  571. config = db.getConfig();
  572. config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
  573. ConfigConstants.CONFIG_KEY_FILEMODE, false);
  574. config.save();
  575. Git git2 = Git.open(db.getDirectory(), nonExecutableFs);
  576. writeTrashFile(path, "content2");
  577. git2.add().addFilepattern(path).call();
  578. RevCommit commit2 = git2.commit().setMessage("commit2").call();
  579. walk = TreeWalk.forPath(db, path, commit2.getTree());
  580. assertNotNull(walk);
  581. assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
  582. }
  583. private static DirCacheEntry addEntryToBuilder(String path, File file,
  584. ObjectInserter newObjectInserter, DirCacheBuilder builder, int stage)
  585. throws IOException {
  586. FileInputStream inputStream = new FileInputStream(file);
  587. ObjectId id = newObjectInserter.insert(
  588. Constants.OBJ_BLOB, file.length(), inputStream);
  589. inputStream.close();
  590. DirCacheEntry entry = new DirCacheEntry(path, stage);
  591. entry.setObjectId(id);
  592. entry.setFileMode(FileMode.REGULAR_FILE);
  593. entry.setLastModified(file.lastModified());
  594. entry.setLength((int) file.length());
  595. builder.add(entry);
  596. return entry;
  597. }
  598. private void assumeUnchanged(String path) throws IOException {
  599. final DirCache dirc = db.lockDirCache();
  600. final DirCacheEntry ent = dirc.getEntry(path);
  601. if (ent != null)
  602. ent.setAssumeValid(true);
  603. dirc.write();
  604. if (!dirc.commit())
  605. throw new IOException("could not commit");
  606. }
  607. }