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.

MergeCommandTest.java 56KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. /*
  2. * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
  3. * Copyright (C) 2010-2012, 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.assertFalse;
  47. import static org.junit.Assert.assertNull;
  48. import static org.junit.Assert.assertTrue;
  49. import static org.junit.Assert.fail;
  50. import java.io.File;
  51. import java.util.Iterator;
  52. import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
  53. import org.eclipse.jgit.api.MergeResult.MergeStatus;
  54. import org.eclipse.jgit.api.errors.InvalidMergeHeadsException;
  55. import org.eclipse.jgit.junit.RepositoryTestCase;
  56. import org.eclipse.jgit.junit.TestRepository;
  57. import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
  58. import org.eclipse.jgit.lib.Constants;
  59. import org.eclipse.jgit.lib.Ref;
  60. import org.eclipse.jgit.lib.Repository;
  61. import org.eclipse.jgit.lib.RepositoryState;
  62. import org.eclipse.jgit.merge.MergeStrategy;
  63. import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
  64. import org.eclipse.jgit.revwalk.RevCommit;
  65. import org.eclipse.jgit.util.FS;
  66. import org.eclipse.jgit.util.FileUtils;
  67. import org.eclipse.jgit.util.GitDateFormatter;
  68. import org.eclipse.jgit.util.GitDateFormatter.Format;
  69. import org.junit.Before;
  70. import org.junit.Test;
  71. import org.junit.experimental.theories.DataPoints;
  72. import org.junit.experimental.theories.Theories;
  73. import org.junit.experimental.theories.Theory;
  74. import org.junit.runner.RunWith;
  75. @RunWith(Theories.class)
  76. public class MergeCommandTest extends RepositoryTestCase {
  77. public static @DataPoints
  78. MergeStrategy[] mergeStrategies = MergeStrategy.get();
  79. private GitDateFormatter dateFormatter;
  80. @Override
  81. @Before
  82. public void setUp() throws Exception {
  83. super.setUp();
  84. dateFormatter = new GitDateFormatter(Format.DEFAULT);
  85. }
  86. @Test
  87. public void testMergeInItself() throws Exception {
  88. Git git = new Git(db);
  89. git.commit().setMessage("initial commit").call();
  90. MergeResult result = git.merge().include(db.getRef(Constants.HEAD)).call();
  91. assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
  92. // no reflog entry written by merge
  93. assertEquals("commit (initial): initial commit",
  94. db
  95. .getReflogReader(Constants.HEAD).getLastEntry().getComment());
  96. assertEquals("commit (initial): initial commit",
  97. db
  98. .getReflogReader(db.getBranch()).getLastEntry().getComment());
  99. }
  100. @Test
  101. public void testAlreadyUpToDate() throws Exception {
  102. Git git = new Git(db);
  103. RevCommit first = git.commit().setMessage("initial commit").call();
  104. createBranch(first, "refs/heads/branch1");
  105. RevCommit second = git.commit().setMessage("second commit").call();
  106. MergeResult result = git.merge().include(db.getRef("refs/heads/branch1")).call();
  107. assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
  108. assertEquals(second, result.getNewHead());
  109. // no reflog entry written by merge
  110. assertEquals("commit: second commit", db
  111. .getReflogReader(Constants.HEAD).getLastEntry().getComment());
  112. assertEquals("commit: second commit", db
  113. .getReflogReader(db.getBranch()).getLastEntry().getComment());
  114. }
  115. @Test
  116. public void testFastForward() throws Exception {
  117. Git git = new Git(db);
  118. RevCommit first = git.commit().setMessage("initial commit").call();
  119. createBranch(first, "refs/heads/branch1");
  120. RevCommit second = git.commit().setMessage("second commit").call();
  121. checkoutBranch("refs/heads/branch1");
  122. MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
  123. assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
  124. assertEquals(second, result.getNewHead());
  125. assertEquals("merge refs/heads/master: Fast-forward",
  126. db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
  127. assertEquals("merge refs/heads/master: Fast-forward",
  128. db.getReflogReader(db.getBranch()).getLastEntry().getComment());
  129. }
  130. @Test
  131. public void testFastForwardNoCommit() throws Exception {
  132. Git git = new Git(db);
  133. RevCommit first = git.commit().setMessage("initial commit").call();
  134. createBranch(first, "refs/heads/branch1");
  135. RevCommit second = git.commit().setMessage("second commit").call();
  136. checkoutBranch("refs/heads/branch1");
  137. MergeResult result = git.merge().include(db.getRef(Constants.MASTER))
  138. .setCommit(false).call();
  139. assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
  140. result.getMergeStatus());
  141. assertEquals(second, result.getNewHead());
  142. assertEquals("merge refs/heads/master: Fast-forward", db
  143. .getReflogReader(Constants.HEAD).getLastEntry().getComment());
  144. assertEquals("merge refs/heads/master: Fast-forward", db
  145. .getReflogReader(db.getBranch()).getLastEntry().getComment());
  146. }
  147. @Test
  148. public void testFastForwardWithFiles() throws Exception {
  149. Git git = new Git(db);
  150. writeTrashFile("file1", "file1");
  151. git.add().addFilepattern("file1").call();
  152. RevCommit first = git.commit().setMessage("initial commit").call();
  153. assertTrue(new File(db.getWorkTree(), "file1").exists());
  154. createBranch(first, "refs/heads/branch1");
  155. writeTrashFile("file2", "file2");
  156. git.add().addFilepattern("file2").call();
  157. RevCommit second = git.commit().setMessage("second commit").call();
  158. assertTrue(new File(db.getWorkTree(), "file2").exists());
  159. checkoutBranch("refs/heads/branch1");
  160. assertFalse(new File(db.getWorkTree(), "file2").exists());
  161. MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
  162. assertTrue(new File(db.getWorkTree(), "file1").exists());
  163. assertTrue(new File(db.getWorkTree(), "file2").exists());
  164. assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
  165. assertEquals(second, result.getNewHead());
  166. assertEquals("merge refs/heads/master: Fast-forward",
  167. db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
  168. assertEquals("merge refs/heads/master: Fast-forward",
  169. db.getReflogReader(db.getBranch()).getLastEntry().getComment());
  170. }
  171. @Test
  172. public void testMultipleHeads() throws Exception {
  173. Git git = new Git(db);
  174. writeTrashFile("file1", "file1");
  175. git.add().addFilepattern("file1").call();
  176. RevCommit first = git.commit().setMessage("initial commit").call();
  177. createBranch(first, "refs/heads/branch1");
  178. writeTrashFile("file2", "file2");
  179. git.add().addFilepattern("file2").call();
  180. RevCommit second = git.commit().setMessage("second commit").call();
  181. writeTrashFile("file3", "file3");
  182. git.add().addFilepattern("file3").call();
  183. git.commit().setMessage("third commit").call();
  184. checkoutBranch("refs/heads/branch1");
  185. assertFalse(new File(db.getWorkTree(), "file2").exists());
  186. assertFalse(new File(db.getWorkTree(), "file3").exists());
  187. MergeCommand merge = git.merge();
  188. merge.include(second.getId());
  189. merge.include(db.getRef(Constants.MASTER));
  190. try {
  191. merge.call();
  192. fail("Expected exception not thrown when merging multiple heads");
  193. } catch (InvalidMergeHeadsException e) {
  194. // expected this exception
  195. }
  196. }
  197. @Theory
  198. public void testMergeSuccessAllStrategies(MergeStrategy mergeStrategy)
  199. throws Exception {
  200. Git git = new Git(db);
  201. RevCommit first = git.commit().setMessage("first").call();
  202. createBranch(first, "refs/heads/side");
  203. writeTrashFile("a", "a");
  204. git.add().addFilepattern("a").call();
  205. git.commit().setMessage("second").call();
  206. checkoutBranch("refs/heads/side");
  207. writeTrashFile("b", "b");
  208. git.add().addFilepattern("b").call();
  209. git.commit().setMessage("third").call();
  210. MergeResult result = git.merge().setStrategy(mergeStrategy)
  211. .include(db.getRef(Constants.MASTER)).call();
  212. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  213. assertEquals(
  214. "merge refs/heads/master: Merge made by "
  215. + mergeStrategy.getName() + ".",
  216. db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
  217. assertEquals(
  218. "merge refs/heads/master: Merge made by "
  219. + mergeStrategy.getName() + ".",
  220. db.getReflogReader(db.getBranch()).getLastEntry().getComment());
  221. }
  222. @Theory
  223. public void testMergeSuccessAllStrategiesNoCommit(
  224. MergeStrategy mergeStrategy) throws Exception {
  225. Git git = new Git(db);
  226. RevCommit first = git.commit().setMessage("first").call();
  227. createBranch(first, "refs/heads/side");
  228. writeTrashFile("a", "a");
  229. git.add().addFilepattern("a").call();
  230. git.commit().setMessage("second").call();
  231. checkoutBranch("refs/heads/side");
  232. writeTrashFile("b", "b");
  233. git.add().addFilepattern("b").call();
  234. RevCommit thirdCommit = git.commit().setMessage("third").call();
  235. MergeResult result = git.merge().setStrategy(mergeStrategy)
  236. .setCommit(false)
  237. .include(db.getRef(Constants.MASTER)).call();
  238. assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
  239. assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
  240. thirdCommit.getId());
  241. }
  242. @Test
  243. public void testContentMerge() throws Exception {
  244. Git git = new Git(db);
  245. writeTrashFile("a", "1\na\n3\n");
  246. writeTrashFile("b", "1\nb\n3\n");
  247. writeTrashFile("c/c/c", "1\nc\n3\n");
  248. git.add().addFilepattern("a").addFilepattern("b")
  249. .addFilepattern("c/c/c").call();
  250. RevCommit initialCommit = git.commit().setMessage("initial").call();
  251. createBranch(initialCommit, "refs/heads/side");
  252. checkoutBranch("refs/heads/side");
  253. writeTrashFile("a", "1\na(side)\n3\n");
  254. writeTrashFile("b", "1\nb(side)\n3\n");
  255. git.add().addFilepattern("a").addFilepattern("b").call();
  256. RevCommit secondCommit = git.commit().setMessage("side").call();
  257. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  258. checkoutBranch("refs/heads/master");
  259. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  260. writeTrashFile("a", "1\na(main)\n3\n");
  261. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  262. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  263. git.commit().setMessage("main").call();
  264. MergeResult result = git.merge().include(secondCommit.getId())
  265. .setStrategy(MergeStrategy.RESOLVE).call();
  266. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  267. assertEquals(
  268. "1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n",
  269. read(new File(db.getWorkTree(), "a")));
  270. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  271. assertEquals("1\nc(main)\n3\n",
  272. read(new File(db.getWorkTree(), "c/c/c")));
  273. assertEquals(1, result.getConflicts().size());
  274. assertEquals(3, result.getConflicts().get("a")[0].length);
  275. assertEquals(RepositoryState.MERGING, db.getRepositoryState());
  276. }
  277. @Test
  278. public void testMergeTag() throws Exception {
  279. Git git = new Git(db);
  280. writeTrashFile("a", "a");
  281. git.add().addFilepattern("a").call();
  282. RevCommit initialCommit = git.commit().setMessage("initial").call();
  283. createBranch(initialCommit, "refs/heads/side");
  284. checkoutBranch("refs/heads/side");
  285. writeTrashFile("b", "b");
  286. git.add().addFilepattern("b").call();
  287. RevCommit secondCommit = git.commit().setMessage("side").call();
  288. Ref tag = git.tag().setAnnotated(true).setMessage("my tag 01")
  289. .setName("tag01").setObjectId(secondCommit).call();
  290. checkoutBranch("refs/heads/master");
  291. writeTrashFile("a", "a2");
  292. git.add().addFilepattern("a").call();
  293. git.commit().setMessage("main").call();
  294. MergeResult result = git.merge().include(tag).setStrategy(MergeStrategy.RESOLVE).call();
  295. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  296. }
  297. @Test
  298. public void testMergeMessage() throws Exception {
  299. Git git = new Git(db);
  300. writeTrashFile("a", "1\na\n3\n");
  301. git.add().addFilepattern("a").call();
  302. RevCommit initialCommit = git.commit().setMessage("initial").call();
  303. createBranch(initialCommit, "refs/heads/side");
  304. checkoutBranch("refs/heads/side");
  305. writeTrashFile("a", "1\na(side)\n3\n");
  306. git.add().addFilepattern("a").call();
  307. git.commit().setMessage("side").call();
  308. checkoutBranch("refs/heads/master");
  309. writeTrashFile("a", "1\na(main)\n3\n");
  310. git.add().addFilepattern("a").call();
  311. git.commit().setMessage("main").call();
  312. Ref sideBranch = db.getRef("side");
  313. git.merge().include(sideBranch)
  314. .setStrategy(MergeStrategy.RESOLVE).call();
  315. assertEquals("Merge branch 'side'\n\nConflicts:\n\ta\n",
  316. db.readMergeCommitMsg());
  317. }
  318. @Test
  319. public void testMergeNonVersionedPaths() throws Exception {
  320. Git git = new Git(db);
  321. writeTrashFile("a", "1\na\n3\n");
  322. writeTrashFile("b", "1\nb\n3\n");
  323. writeTrashFile("c/c/c", "1\nc\n3\n");
  324. git.add().addFilepattern("a").addFilepattern("b")
  325. .addFilepattern("c/c/c").call();
  326. RevCommit initialCommit = git.commit().setMessage("initial").call();
  327. createBranch(initialCommit, "refs/heads/side");
  328. checkoutBranch("refs/heads/side");
  329. writeTrashFile("a", "1\na(side)\n3\n");
  330. writeTrashFile("b", "1\nb(side)\n3\n");
  331. git.add().addFilepattern("a").addFilepattern("b").call();
  332. RevCommit secondCommit = git.commit().setMessage("side").call();
  333. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  334. checkoutBranch("refs/heads/master");
  335. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  336. writeTrashFile("a", "1\na(main)\n3\n");
  337. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  338. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  339. git.commit().setMessage("main").call();
  340. writeTrashFile("d", "1\nd\n3\n");
  341. assertTrue(new File(db.getWorkTree(), "e").mkdir());
  342. MergeResult result = git.merge().include(secondCommit.getId())
  343. .setStrategy(MergeStrategy.RESOLVE).call();
  344. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  345. assertEquals(
  346. "1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n",
  347. read(new File(db.getWorkTree(), "a")));
  348. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  349. assertEquals("1\nc(main)\n3\n",
  350. read(new File(db.getWorkTree(), "c/c/c")));
  351. assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
  352. File dir = new File(db.getWorkTree(), "e");
  353. assertTrue(dir.isDirectory());
  354. assertEquals(1, result.getConflicts().size());
  355. assertEquals(3, result.getConflicts().get("a")[0].length);
  356. assertEquals(RepositoryState.MERGING, db.getRepositoryState());
  357. }
  358. @Test
  359. public void testMultipleCreations() throws Exception {
  360. Git git = new Git(db);
  361. writeTrashFile("a", "1\na\n3\n");
  362. git.add().addFilepattern("a").call();
  363. RevCommit initialCommit = git.commit().setMessage("initial").call();
  364. createBranch(initialCommit, "refs/heads/side");
  365. checkoutBranch("refs/heads/side");
  366. writeTrashFile("b", "1\nb(side)\n3\n");
  367. git.add().addFilepattern("b").call();
  368. RevCommit secondCommit = git.commit().setMessage("side").call();
  369. checkoutBranch("refs/heads/master");
  370. writeTrashFile("b", "1\nb(main)\n3\n");
  371. git.add().addFilepattern("b").call();
  372. git.commit().setMessage("main").call();
  373. MergeResult result = git.merge().include(secondCommit.getId())
  374. .setStrategy(MergeStrategy.RESOLVE).call();
  375. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  376. }
  377. @Test
  378. public void testMultipleCreationsSameContent() throws Exception {
  379. Git git = new Git(db);
  380. writeTrashFile("a", "1\na\n3\n");
  381. git.add().addFilepattern("a").call();
  382. RevCommit initialCommit = git.commit().setMessage("initial").call();
  383. createBranch(initialCommit, "refs/heads/side");
  384. checkoutBranch("refs/heads/side");
  385. writeTrashFile("b", "1\nb(1)\n3\n");
  386. git.add().addFilepattern("b").call();
  387. RevCommit secondCommit = git.commit().setMessage("side").call();
  388. checkoutBranch("refs/heads/master");
  389. writeTrashFile("b", "1\nb(1)\n3\n");
  390. git.add().addFilepattern("b").call();
  391. git.commit().setMessage("main").call();
  392. MergeResult result = git.merge().include(secondCommit.getId())
  393. .setStrategy(MergeStrategy.RESOLVE).call();
  394. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  395. assertEquals("1\nb(1)\n3\n", read(new File(db.getWorkTree(), "b")));
  396. assertEquals("merge " + secondCommit.getId().getName()
  397. + ": Merge made by resolve.", db
  398. .getReflogReader(Constants.HEAD)
  399. .getLastEntry().getComment());
  400. assertEquals("merge " + secondCommit.getId().getName()
  401. + ": Merge made by resolve.", db
  402. .getReflogReader(db.getBranch())
  403. .getLastEntry().getComment());
  404. }
  405. @Test
  406. public void testSuccessfulContentMerge() throws Exception {
  407. Git git = new Git(db);
  408. writeTrashFile("a", "1\na\n3\n");
  409. writeTrashFile("b", "1\nb\n3\n");
  410. writeTrashFile("c/c/c", "1\nc\n3\n");
  411. git.add().addFilepattern("a").addFilepattern("b")
  412. .addFilepattern("c/c/c").call();
  413. RevCommit initialCommit = git.commit().setMessage("initial").call();
  414. createBranch(initialCommit, "refs/heads/side");
  415. checkoutBranch("refs/heads/side");
  416. writeTrashFile("a", "1(side)\na\n3\n");
  417. writeTrashFile("b", "1\nb(side)\n3\n");
  418. git.add().addFilepattern("a").addFilepattern("b").call();
  419. RevCommit secondCommit = git.commit().setMessage("side").call();
  420. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  421. checkoutBranch("refs/heads/master");
  422. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  423. writeTrashFile("a", "1\na\n3(main)\n");
  424. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  425. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  426. RevCommit thirdCommit = git.commit().setMessage("main").call();
  427. MergeResult result = git.merge().include(secondCommit.getId())
  428. .setStrategy(MergeStrategy.RESOLVE).call();
  429. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  430. assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
  431. "a")));
  432. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  433. assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(),
  434. "c/c/c")));
  435. assertEquals(null, result.getConflicts());
  436. assertEquals(2, result.getMergedCommits().length);
  437. assertEquals(thirdCommit, result.getMergedCommits()[0]);
  438. assertEquals(secondCommit, result.getMergedCommits()[1]);
  439. Iterator<RevCommit> it = git.log().call().iterator();
  440. RevCommit newHead = it.next();
  441. assertEquals(newHead, result.getNewHead());
  442. assertEquals(2, newHead.getParentCount());
  443. assertEquals(thirdCommit, newHead.getParent(0));
  444. assertEquals(secondCommit, newHead.getParent(1));
  445. assertEquals(
  446. "Merge commit '3fa334456d236a92db020289fe0bf481d91777b4'",
  447. newHead.getFullMessage());
  448. // @TODO fix me
  449. assertEquals(RepositoryState.SAFE, db.getRepositoryState());
  450. // test index state
  451. }
  452. @Test
  453. public void testSuccessfulContentMergeNoCommit() throws Exception {
  454. Git git = new Git(db);
  455. writeTrashFile("a", "1\na\n3\n");
  456. writeTrashFile("b", "1\nb\n3\n");
  457. writeTrashFile("c/c/c", "1\nc\n3\n");
  458. git.add().addFilepattern("a").addFilepattern("b")
  459. .addFilepattern("c/c/c").call();
  460. RevCommit initialCommit = git.commit().setMessage("initial").call();
  461. createBranch(initialCommit, "refs/heads/side");
  462. checkoutBranch("refs/heads/side");
  463. writeTrashFile("a", "1(side)\na\n3\n");
  464. writeTrashFile("b", "1\nb(side)\n3\n");
  465. git.add().addFilepattern("a").addFilepattern("b").call();
  466. RevCommit secondCommit = git.commit().setMessage("side").call();
  467. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  468. checkoutBranch("refs/heads/master");
  469. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  470. writeTrashFile("a", "1\na\n3(main)\n");
  471. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  472. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  473. RevCommit thirdCommit = git.commit().setMessage("main").call();
  474. MergeResult result = git.merge().include(secondCommit.getId())
  475. .setCommit(false)
  476. .setStrategy(MergeStrategy.RESOLVE).call();
  477. assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
  478. assertEquals(db.getRef(Constants.HEAD).getTarget().getObjectId(),
  479. thirdCommit.getId());
  480. assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
  481. "a")));
  482. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  483. assertEquals("1\nc(main)\n3\n",
  484. read(new File(db.getWorkTree(), "c/c/c")));
  485. assertEquals(null, result.getConflicts());
  486. assertEquals(2, result.getMergedCommits().length);
  487. assertEquals(thirdCommit, result.getMergedCommits()[0]);
  488. assertEquals(secondCommit, result.getMergedCommits()[1]);
  489. assertNull(result.getNewHead());
  490. assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
  491. }
  492. @Test
  493. public void testSuccessfulContentMergeAndDirtyworkingTree()
  494. throws Exception {
  495. Git git = new Git(db);
  496. writeTrashFile("a", "1\na\n3\n");
  497. writeTrashFile("b", "1\nb\n3\n");
  498. writeTrashFile("d", "1\nd\n3\n");
  499. writeTrashFile("c/c/c", "1\nc\n3\n");
  500. git.add().addFilepattern("a").addFilepattern("b")
  501. .addFilepattern("c/c/c").addFilepattern("d").call();
  502. RevCommit initialCommit = git.commit().setMessage("initial").call();
  503. createBranch(initialCommit, "refs/heads/side");
  504. checkoutBranch("refs/heads/side");
  505. writeTrashFile("a", "1(side)\na\n3\n");
  506. writeTrashFile("b", "1\nb(side)\n3\n");
  507. git.add().addFilepattern("a").addFilepattern("b").call();
  508. RevCommit secondCommit = git.commit().setMessage("side").call();
  509. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  510. checkoutBranch("refs/heads/master");
  511. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  512. writeTrashFile("a", "1\na\n3(main)\n");
  513. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  514. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  515. RevCommit thirdCommit = git.commit().setMessage("main").call();
  516. writeTrashFile("d", "--- dirty ---");
  517. MergeResult result = git.merge().include(secondCommit.getId())
  518. .setStrategy(MergeStrategy.RESOLVE).call();
  519. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  520. assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
  521. "a")));
  522. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  523. assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(),
  524. "c/c/c")));
  525. assertEquals("--- dirty ---", read(new File(db.getWorkTree(), "d")));
  526. assertEquals(null, result.getConflicts());
  527. assertEquals(2, result.getMergedCommits().length);
  528. assertEquals(thirdCommit, result.getMergedCommits()[0]);
  529. assertEquals(secondCommit, result.getMergedCommits()[1]);
  530. Iterator<RevCommit> it = git.log().call().iterator();
  531. RevCommit newHead = it.next();
  532. assertEquals(newHead, result.getNewHead());
  533. assertEquals(2, newHead.getParentCount());
  534. assertEquals(thirdCommit, newHead.getParent(0));
  535. assertEquals(secondCommit, newHead.getParent(1));
  536. assertEquals(
  537. "Merge commit '064d54d98a4cdb0fed1802a21c656bfda67fe879'",
  538. newHead.getFullMessage());
  539. assertEquals(RepositoryState.SAFE, db.getRepositoryState());
  540. }
  541. @Test
  542. public void testSingleDeletion() throws Exception {
  543. Git git = new Git(db);
  544. writeTrashFile("a", "1\na\n3\n");
  545. writeTrashFile("b", "1\nb\n3\n");
  546. writeTrashFile("d", "1\nd\n3\n");
  547. writeTrashFile("c/c/c", "1\nc\n3\n");
  548. git.add().addFilepattern("a").addFilepattern("b")
  549. .addFilepattern("c/c/c").addFilepattern("d").call();
  550. RevCommit initialCommit = git.commit().setMessage("initial").call();
  551. createBranch(initialCommit, "refs/heads/side");
  552. checkoutBranch("refs/heads/side");
  553. assertTrue(new File(db.getWorkTree(), "b").delete());
  554. git.add().addFilepattern("b").setUpdate(true).call();
  555. RevCommit secondCommit = git.commit().setMessage("side").call();
  556. assertFalse(new File(db.getWorkTree(), "b").exists());
  557. checkoutBranch("refs/heads/master");
  558. assertTrue(new File(db.getWorkTree(), "b").exists());
  559. writeTrashFile("a", "1\na\n3(main)\n");
  560. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  561. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  562. RevCommit thirdCommit = git.commit().setMessage("main").call();
  563. // We are merging a deletion into our branch
  564. MergeResult result = git.merge().include(secondCommit.getId())
  565. .setStrategy(MergeStrategy.RESOLVE).call();
  566. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  567. assertEquals("1\na\n3(main)\n", read(new File(db.getWorkTree(), "a")));
  568. assertFalse(new File(db.getWorkTree(), "b").exists());
  569. assertEquals("1\nc(main)\n3\n",
  570. read(new File(db.getWorkTree(), "c/c/c")));
  571. assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
  572. // Do the opposite, be on a branch where we have deleted a file and
  573. // merge in a old commit where this file was not deleted
  574. checkoutBranch("refs/heads/side");
  575. assertFalse(new File(db.getWorkTree(), "b").exists());
  576. result = git.merge().include(thirdCommit.getId())
  577. .setStrategy(MergeStrategy.RESOLVE).call();
  578. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  579. assertEquals("1\na\n3(main)\n", read(new File(db.getWorkTree(), "a")));
  580. assertFalse(new File(db.getWorkTree(), "b").exists());
  581. assertEquals("1\nc(main)\n3\n",
  582. read(new File(db.getWorkTree(), "c/c/c")));
  583. assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
  584. }
  585. @Test
  586. public void testMultipleDeletions() throws Exception {
  587. Git git = new Git(db);
  588. writeTrashFile("a", "1\na\n3\n");
  589. git.add().addFilepattern("a").call();
  590. RevCommit initialCommit = git.commit().setMessage("initial").call();
  591. createBranch(initialCommit, "refs/heads/side");
  592. checkoutBranch("refs/heads/side");
  593. assertTrue(new File(db.getWorkTree(), "a").delete());
  594. git.add().addFilepattern("a").setUpdate(true).call();
  595. RevCommit secondCommit = git.commit().setMessage("side").call();
  596. assertFalse(new File(db.getWorkTree(), "a").exists());
  597. checkoutBranch("refs/heads/master");
  598. assertTrue(new File(db.getWorkTree(), "a").exists());
  599. assertTrue(new File(db.getWorkTree(), "a").delete());
  600. git.add().addFilepattern("a").setUpdate(true).call();
  601. git.commit().setMessage("main").call();
  602. // We are merging a deletion into our branch
  603. MergeResult result = git.merge().include(secondCommit.getId())
  604. .setStrategy(MergeStrategy.RESOLVE).call();
  605. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  606. }
  607. @Test
  608. public void testDeletionAndConflict() throws Exception {
  609. Git git = new Git(db);
  610. writeTrashFile("a", "1\na\n3\n");
  611. writeTrashFile("b", "1\nb\n3\n");
  612. writeTrashFile("d", "1\nd\n3\n");
  613. writeTrashFile("c/c/c", "1\nc\n3\n");
  614. git.add().addFilepattern("a").addFilepattern("b")
  615. .addFilepattern("c/c/c").addFilepattern("d").call();
  616. RevCommit initialCommit = git.commit().setMessage("initial").call();
  617. createBranch(initialCommit, "refs/heads/side");
  618. checkoutBranch("refs/heads/side");
  619. assertTrue(new File(db.getWorkTree(), "b").delete());
  620. writeTrashFile("a", "1\na\n3(side)\n");
  621. git.add().addFilepattern("b").setUpdate(true).call();
  622. git.add().addFilepattern("a").setUpdate(true).call();
  623. RevCommit secondCommit = git.commit().setMessage("side").call();
  624. assertFalse(new File(db.getWorkTree(), "b").exists());
  625. checkoutBranch("refs/heads/master");
  626. assertTrue(new File(db.getWorkTree(), "b").exists());
  627. writeTrashFile("a", "1\na\n3(main)\n");
  628. writeTrashFile("c/c/c", "1\nc(main)\n3\n");
  629. git.add().addFilepattern("a").addFilepattern("c/c/c").call();
  630. git.commit().setMessage("main").call();
  631. // We are merging a deletion into our branch
  632. MergeResult result = git.merge().include(secondCommit.getId())
  633. .setStrategy(MergeStrategy.RESOLVE).call();
  634. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  635. assertEquals(
  636. "1\na\n<<<<<<< HEAD\n3(main)\n=======\n3(side)\n>>>>>>> 54ffed45d62d252715fc20e41da92d44c48fb0ff\n",
  637. read(new File(db.getWorkTree(), "a")));
  638. assertFalse(new File(db.getWorkTree(), "b").exists());
  639. assertEquals("1\nc(main)\n3\n",
  640. read(new File(db.getWorkTree(), "c/c/c")));
  641. assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
  642. }
  643. @Test
  644. public void testDeletionOnMasterConflict() throws Exception {
  645. Git git = new Git(db);
  646. writeTrashFile("a", "1\na\n3\n");
  647. writeTrashFile("b", "1\nb\n3\n");
  648. git.add().addFilepattern("a").addFilepattern("b").call();
  649. RevCommit initialCommit = git.commit().setMessage("initial").call();
  650. // create side branch and modify "a"
  651. createBranch(initialCommit, "refs/heads/side");
  652. checkoutBranch("refs/heads/side");
  653. writeTrashFile("a", "1\na(side)\n3\n");
  654. git.add().addFilepattern("a").call();
  655. RevCommit secondCommit = git.commit().setMessage("side").call();
  656. // delete a on master to generate conflict
  657. checkoutBranch("refs/heads/master");
  658. git.rm().addFilepattern("a").call();
  659. git.commit().setMessage("main").call();
  660. // merge side with master
  661. MergeResult result = git.merge().include(secondCommit.getId())
  662. .setStrategy(MergeStrategy.RESOLVE).call();
  663. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  664. // result should be 'a' conflicting with workspace content from side
  665. assertTrue(new File(db.getWorkTree(), "a").exists());
  666. assertEquals("1\na(side)\n3\n", read(new File(db.getWorkTree(), "a")));
  667. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  668. }
  669. @Test
  670. public void testDeletionOnSideConflict() throws Exception {
  671. Git git = new Git(db);
  672. writeTrashFile("a", "1\na\n3\n");
  673. writeTrashFile("b", "1\nb\n3\n");
  674. git.add().addFilepattern("a").addFilepattern("b").call();
  675. RevCommit initialCommit = git.commit().setMessage("initial").call();
  676. // create side branch and delete "a"
  677. createBranch(initialCommit, "refs/heads/side");
  678. checkoutBranch("refs/heads/side");
  679. git.rm().addFilepattern("a").call();
  680. RevCommit secondCommit = git.commit().setMessage("side").call();
  681. // update a on master to generate conflict
  682. checkoutBranch("refs/heads/master");
  683. writeTrashFile("a", "1\na(main)\n3\n");
  684. git.add().addFilepattern("a").call();
  685. git.commit().setMessage("main").call();
  686. // merge side with master
  687. MergeResult result = git.merge().include(secondCommit.getId())
  688. .setStrategy(MergeStrategy.RESOLVE).call();
  689. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  690. assertTrue(new File(db.getWorkTree(), "a").exists());
  691. assertEquals("1\na(main)\n3\n", read(new File(db.getWorkTree(), "a")));
  692. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  693. assertEquals(1, result.getConflicts().size());
  694. assertEquals(3, result.getConflicts().get("a")[0].length);
  695. }
  696. @Test
  697. public void testModifiedAndRenamed() throws Exception {
  698. // this test is essentially the same as testDeletionOnSideConflict,
  699. // however if once rename support is added this test should result in a
  700. // successful merge instead of a conflict
  701. Git git = new Git(db);
  702. writeTrashFile("x", "add x");
  703. git.add().addFilepattern("x").call();
  704. RevCommit initial = git.commit().setMessage("add x").call();
  705. createBranch(initial, "refs/heads/d1");
  706. createBranch(initial, "refs/heads/d2");
  707. // rename x to y on d1
  708. checkoutBranch("refs/heads/d1");
  709. new File(db.getWorkTree(), "x")
  710. .renameTo(new File(db.getWorkTree(), "y"));
  711. git.rm().addFilepattern("x").call();
  712. git.add().addFilepattern("y").call();
  713. RevCommit d1Commit = git.commit().setMessage("d1 rename x -> y").call();
  714. checkoutBranch("refs/heads/d2");
  715. writeTrashFile("x", "d2 change");
  716. git.add().addFilepattern("x").call();
  717. RevCommit d2Commit = git.commit().setMessage("d2 change in x").call();
  718. checkoutBranch("refs/heads/master");
  719. MergeResult d1Merge = git.merge().include(d1Commit).call();
  720. assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
  721. d1Merge.getMergeStatus());
  722. MergeResult d2Merge = git.merge().include(d2Commit).call();
  723. assertEquals(MergeResult.MergeStatus.CONFLICTING,
  724. d2Merge.getMergeStatus());
  725. assertEquals(1, d2Merge.getConflicts().size());
  726. assertEquals(3, d2Merge.getConflicts().get("x")[0].length);
  727. }
  728. @Test
  729. public void testMergeFailingWithDirtyWorkingTree() throws Exception {
  730. Git git = new Git(db);
  731. writeTrashFile("a", "1\na\n3\n");
  732. writeTrashFile("b", "1\nb\n3\n");
  733. git.add().addFilepattern("a").addFilepattern("b").call();
  734. RevCommit initialCommit = git.commit().setMessage("initial").call();
  735. createBranch(initialCommit, "refs/heads/side");
  736. checkoutBranch("refs/heads/side");
  737. writeTrashFile("a", "1(side)\na\n3\n");
  738. writeTrashFile("b", "1\nb(side)\n3\n");
  739. git.add().addFilepattern("a").addFilepattern("b").call();
  740. RevCommit secondCommit = git.commit().setMessage("side").call();
  741. assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
  742. checkoutBranch("refs/heads/master");
  743. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  744. writeTrashFile("a", "1\na\n3(main)\n");
  745. git.add().addFilepattern("a").call();
  746. git.commit().setMessage("main").call();
  747. writeTrashFile("a", "--- dirty ---");
  748. MergeResult result = git.merge().include(secondCommit.getId())
  749. .setStrategy(MergeStrategy.RESOLVE).call();
  750. assertEquals(MergeStatus.FAILED, result.getMergeStatus());
  751. assertEquals("--- dirty ---", read(new File(db.getWorkTree(), "a")));
  752. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  753. assertEquals(null, result.getConflicts());
  754. assertEquals(RepositoryState.SAFE, db.getRepositoryState());
  755. }
  756. @Test
  757. public void testMergeConflictFileFolder() throws Exception {
  758. Git git = new Git(db);
  759. writeTrashFile("a", "1\na\n3\n");
  760. writeTrashFile("b", "1\nb\n3\n");
  761. git.add().addFilepattern("a").addFilepattern("b").call();
  762. RevCommit initialCommit = git.commit().setMessage("initial").call();
  763. createBranch(initialCommit, "refs/heads/side");
  764. checkoutBranch("refs/heads/side");
  765. writeTrashFile("c/c/c", "1\nc(side)\n3\n");
  766. writeTrashFile("d", "1\nd(side)\n3\n");
  767. git.add().addFilepattern("c/c/c").addFilepattern("d").call();
  768. RevCommit secondCommit = git.commit().setMessage("side").call();
  769. checkoutBranch("refs/heads/master");
  770. writeTrashFile("c", "1\nc(main)\n3\n");
  771. writeTrashFile("d/d/d", "1\nd(main)\n3\n");
  772. git.add().addFilepattern("c").addFilepattern("d/d/d").call();
  773. git.commit().setMessage("main").call();
  774. MergeResult result = git.merge().include(secondCommit.getId())
  775. .setStrategy(MergeStrategy.RESOLVE).call();
  776. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  777. assertEquals("1\na\n3\n", read(new File(db.getWorkTree(), "a")));
  778. assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
  779. assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(), "c")));
  780. assertEquals("1\nd(main)\n3\n", read(new File(db.getWorkTree(), "d/d/d")));
  781. assertEquals(null, result.getConflicts());
  782. assertEquals(RepositoryState.MERGING, db.getRepositoryState());
  783. }
  784. @Test
  785. public void testSuccessfulMergeFailsDueToDirtyIndex() throws Exception {
  786. Git git = new Git(db);
  787. File fileA = writeTrashFile("a", "a");
  788. RevCommit initialCommit = addAllAndCommit(git);
  789. // switch branch
  790. createBranch(initialCommit, "refs/heads/side");
  791. checkoutBranch("refs/heads/side");
  792. // modify file a
  793. write(fileA, "a(side)");
  794. writeTrashFile("b", "b");
  795. RevCommit sideCommit = addAllAndCommit(git);
  796. // switch branch
  797. checkoutBranch("refs/heads/master");
  798. writeTrashFile("c", "c");
  799. addAllAndCommit(git);
  800. // modify and add file a
  801. write(fileA, "a(modified)");
  802. git.add().addFilepattern("a").call();
  803. // do not commit
  804. // get current index state
  805. String indexState = indexState(CONTENT);
  806. // merge
  807. MergeResult result = git.merge().include(sideCommit.getId())
  808. .setStrategy(MergeStrategy.RESOLVE).call();
  809. checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX,
  810. indexState, fileA);
  811. }
  812. @Test
  813. public void testConflictingMergeFailsDueToDirtyIndex() throws Exception {
  814. Git git = new Git(db);
  815. File fileA = writeTrashFile("a", "a");
  816. RevCommit initialCommit = addAllAndCommit(git);
  817. // switch branch
  818. createBranch(initialCommit, "refs/heads/side");
  819. checkoutBranch("refs/heads/side");
  820. // modify file a
  821. write(fileA, "a(side)");
  822. writeTrashFile("b", "b");
  823. RevCommit sideCommit = addAllAndCommit(git);
  824. // switch branch
  825. checkoutBranch("refs/heads/master");
  826. // modify file a - this will cause a conflict during merge
  827. write(fileA, "a(master)");
  828. writeTrashFile("c", "c");
  829. addAllAndCommit(git);
  830. // modify and add file a
  831. write(fileA, "a(modified)");
  832. git.add().addFilepattern("a").call();
  833. // do not commit
  834. // get current index state
  835. String indexState = indexState(CONTENT);
  836. // merge
  837. MergeResult result = git.merge().include(sideCommit.getId())
  838. .setStrategy(MergeStrategy.RESOLVE).call();
  839. checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX,
  840. indexState, fileA);
  841. }
  842. @Test
  843. public void testSuccessfulMergeFailsDueToDirtyWorktree() throws Exception {
  844. Git git = new Git(db);
  845. File fileA = writeTrashFile("a", "a");
  846. RevCommit initialCommit = addAllAndCommit(git);
  847. // switch branch
  848. createBranch(initialCommit, "refs/heads/side");
  849. checkoutBranch("refs/heads/side");
  850. // modify file a
  851. write(fileA, "a(side)");
  852. writeTrashFile("b", "b");
  853. RevCommit sideCommit = addAllAndCommit(git);
  854. // switch branch
  855. checkoutBranch("refs/heads/master");
  856. writeTrashFile("c", "c");
  857. addAllAndCommit(git);
  858. // modify file a
  859. write(fileA, "a(modified)");
  860. // do not add and commit
  861. // get current index state
  862. String indexState = indexState(CONTENT);
  863. // merge
  864. MergeResult result = git.merge().include(sideCommit.getId())
  865. .setStrategy(MergeStrategy.RESOLVE).call();
  866. checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE,
  867. indexState, fileA);
  868. }
  869. @Test
  870. public void testConflictingMergeFailsDueToDirtyWorktree() throws Exception {
  871. Git git = new Git(db);
  872. File fileA = writeTrashFile("a", "a");
  873. RevCommit initialCommit = addAllAndCommit(git);
  874. // switch branch
  875. createBranch(initialCommit, "refs/heads/side");
  876. checkoutBranch("refs/heads/side");
  877. // modify file a
  878. write(fileA, "a(side)");
  879. writeTrashFile("b", "b");
  880. RevCommit sideCommit = addAllAndCommit(git);
  881. // switch branch
  882. checkoutBranch("refs/heads/master");
  883. // modify file a - this will cause a conflict during merge
  884. write(fileA, "a(master)");
  885. writeTrashFile("c", "c");
  886. addAllAndCommit(git);
  887. // modify file a
  888. write(fileA, "a(modified)");
  889. // do not add and commit
  890. // get current index state
  891. String indexState = indexState(CONTENT);
  892. // merge
  893. MergeResult result = git.merge().include(sideCommit.getId())
  894. .setStrategy(MergeStrategy.RESOLVE).call();
  895. checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE,
  896. indexState, fileA);
  897. }
  898. @Test
  899. public void testMergeRemovingFolders() throws Exception {
  900. File folder1 = new File(db.getWorkTree(), "folder1");
  901. File folder2 = new File(db.getWorkTree(), "folder2");
  902. FileUtils.mkdir(folder1);
  903. FileUtils.mkdir(folder2);
  904. File file = new File(folder1, "file1.txt");
  905. write(file, "folder1--file1.txt");
  906. file = new File(folder1, "file2.txt");
  907. write(file, "folder1--file2.txt");
  908. file = new File(folder2, "file1.txt");
  909. write(file, "folder--file1.txt");
  910. file = new File(folder2, "file2.txt");
  911. write(file, "folder2--file2.txt");
  912. Git git = new Git(db);
  913. git.add().addFilepattern(folder1.getName())
  914. .addFilepattern(folder2.getName()).call();
  915. RevCommit commit1 = git.commit().setMessage("adding folders").call();
  916. recursiveDelete(folder1);
  917. recursiveDelete(folder2);
  918. git.rm().addFilepattern("folder1/file1.txt")
  919. .addFilepattern("folder1/file2.txt")
  920. .addFilepattern("folder2/file1.txt")
  921. .addFilepattern("folder2/file2.txt").call();
  922. RevCommit commit2 = git.commit()
  923. .setMessage("removing folders on 'branch'").call();
  924. git.checkout().setName(commit1.name()).call();
  925. MergeResult result = git.merge().include(commit2.getId())
  926. .setStrategy(MergeStrategy.RESOLVE).call();
  927. assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
  928. result.getMergeStatus());
  929. assertEquals(commit2, result.getNewHead());
  930. assertFalse(folder1.exists());
  931. assertFalse(folder2.exists());
  932. }
  933. @Test
  934. public void testMergeRemovingFoldersWithoutFastForward() throws Exception {
  935. File folder1 = new File(db.getWorkTree(), "folder1");
  936. File folder2 = new File(db.getWorkTree(), "folder2");
  937. FileUtils.mkdir(folder1);
  938. FileUtils.mkdir(folder2);
  939. File file = new File(folder1, "file1.txt");
  940. write(file, "folder1--file1.txt");
  941. file = new File(folder1, "file2.txt");
  942. write(file, "folder1--file2.txt");
  943. file = new File(folder2, "file1.txt");
  944. write(file, "folder--file1.txt");
  945. file = new File(folder2, "file2.txt");
  946. write(file, "folder2--file2.txt");
  947. Git git = new Git(db);
  948. git.add().addFilepattern(folder1.getName())
  949. .addFilepattern(folder2.getName()).call();
  950. RevCommit base = git.commit().setMessage("adding folders").call();
  951. recursiveDelete(folder1);
  952. recursiveDelete(folder2);
  953. git.rm().addFilepattern("folder1/file1.txt")
  954. .addFilepattern("folder1/file2.txt")
  955. .addFilepattern("folder2/file1.txt")
  956. .addFilepattern("folder2/file2.txt").call();
  957. RevCommit other = git.commit()
  958. .setMessage("removing folders on 'branch'").call();
  959. git.checkout().setName(base.name()).call();
  960. file = new File(folder2, "file3.txt");
  961. write(file, "folder2--file3.txt");
  962. git.add().addFilepattern(folder2.getName()).call();
  963. git.commit().setMessage("adding another file").call();
  964. MergeResult result = git.merge().include(other.getId())
  965. .setStrategy(MergeStrategy.RESOLVE).call();
  966. assertEquals(MergeResult.MergeStatus.MERGED,
  967. result.getMergeStatus());
  968. assertFalse(folder1.exists());
  969. }
  970. @Test
  971. public void testFileModeMerge() throws Exception {
  972. if (!FS.DETECTED.supportsExecute())
  973. return;
  974. // Only Java6
  975. Git git = new Git(db);
  976. writeTrashFile("mergeableMode", "a");
  977. setExecutable(git, "mergeableMode", false);
  978. writeTrashFile("conflictingModeWithBase", "a");
  979. setExecutable(git, "conflictingModeWithBase", false);
  980. RevCommit initialCommit = addAllAndCommit(git);
  981. // switch branch
  982. createBranch(initialCommit, "refs/heads/side");
  983. checkoutBranch("refs/heads/side");
  984. setExecutable(git, "mergeableMode", true);
  985. writeTrashFile("conflictingModeNoBase", "b");
  986. setExecutable(git, "conflictingModeNoBase", true);
  987. RevCommit sideCommit = addAllAndCommit(git);
  988. // switch branch
  989. createBranch(initialCommit, "refs/heads/side2");
  990. checkoutBranch("refs/heads/side2");
  991. setExecutable(git, "mergeableMode", false);
  992. assertFalse(new File(git.getRepository().getWorkTree(),
  993. "conflictingModeNoBase").exists());
  994. writeTrashFile("conflictingModeNoBase", "b");
  995. setExecutable(git, "conflictingModeNoBase", false);
  996. addAllAndCommit(git);
  997. // merge
  998. MergeResult result = git.merge().include(sideCommit.getId())
  999. .setStrategy(MergeStrategy.RESOLVE).call();
  1000. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  1001. assertTrue(canExecute(git, "mergeableMode"));
  1002. assertFalse(canExecute(git, "conflictingModeNoBase"));
  1003. }
  1004. @Test
  1005. public void testFileModeMergeWithDirtyWorkTree() throws Exception {
  1006. if (!FS.DETECTED.supportsExecute())
  1007. return;
  1008. // Only Java6 (or set x bit in index)
  1009. Git git = new Git(db);
  1010. writeTrashFile("mergeableButDirty", "a");
  1011. setExecutable(git, "mergeableButDirty", false);
  1012. RevCommit initialCommit = addAllAndCommit(git);
  1013. // switch branch
  1014. createBranch(initialCommit, "refs/heads/side");
  1015. checkoutBranch("refs/heads/side");
  1016. setExecutable(git, "mergeableButDirty", true);
  1017. RevCommit sideCommit = addAllAndCommit(git);
  1018. // switch branch
  1019. createBranch(initialCommit, "refs/heads/side2");
  1020. checkoutBranch("refs/heads/side2");
  1021. setExecutable(git, "mergeableButDirty", false);
  1022. addAllAndCommit(git);
  1023. writeTrashFile("mergeableButDirty", "b");
  1024. // merge
  1025. MergeResult result = git.merge().include(sideCommit.getId())
  1026. .setStrategy(MergeStrategy.RESOLVE).call();
  1027. assertEquals(MergeStatus.FAILED, result.getMergeStatus());
  1028. assertFalse(canExecute(git, "mergeableButDirty"));
  1029. }
  1030. @Test
  1031. public void testSquashFastForward() throws Exception {
  1032. Git git = new Git(db);
  1033. writeTrashFile("file1", "file1");
  1034. git.add().addFilepattern("file1").call();
  1035. RevCommit first = git.commit().setMessage("initial commit").call();
  1036. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1037. createBranch(first, "refs/heads/branch1");
  1038. checkoutBranch("refs/heads/branch1");
  1039. writeTrashFile("file2", "file2");
  1040. git.add().addFilepattern("file2").call();
  1041. RevCommit second = git.commit().setMessage("second commit").call();
  1042. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1043. writeTrashFile("file3", "file3");
  1044. git.add().addFilepattern("file3").call();
  1045. RevCommit third = git.commit().setMessage("third commit").call();
  1046. assertTrue(new File(db.getWorkTree(), "file3").exists());
  1047. checkoutBranch("refs/heads/master");
  1048. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1049. assertFalse(new File(db.getWorkTree(), "file2").exists());
  1050. assertFalse(new File(db.getWorkTree(), "file3").exists());
  1051. MergeResult result = git.merge().include(db.getRef("branch1"))
  1052. .setSquash(true).call();
  1053. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1054. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1055. assertTrue(new File(db.getWorkTree(), "file3").exists());
  1056. assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
  1057. result.getMergeStatus());
  1058. assertEquals(first, result.getNewHead()); // HEAD didn't move
  1059. assertEquals(first, db.resolve(Constants.HEAD + "^{commit}"));
  1060. assertEquals(
  1061. "Squashed commit of the following:\n\ncommit "
  1062. + third.getName()
  1063. + "\nAuthor: "
  1064. + third.getAuthorIdent().getName()
  1065. + " <"
  1066. + third.getAuthorIdent().getEmailAddress()
  1067. + ">\nDate: "
  1068. + dateFormatter.formatDate(third
  1069. .getAuthorIdent())
  1070. + "\n\n\tthird commit\n\ncommit "
  1071. + second.getName()
  1072. + "\nAuthor: "
  1073. + second.getAuthorIdent().getName()
  1074. + " <"
  1075. + second.getAuthorIdent().getEmailAddress()
  1076. + ">\nDate: "
  1077. + dateFormatter.formatDate(second
  1078. .getAuthorIdent()) + "\n\n\tsecond commit\n",
  1079. db.readSquashCommitMsg());
  1080. assertNull(db.readMergeCommitMsg());
  1081. Status stat = git.status().call();
  1082. assertEquals(Sets.of("file2", "file3"), stat.getAdded());
  1083. }
  1084. @Test
  1085. public void testSquashMerge() throws Exception {
  1086. Git git = new Git(db);
  1087. writeTrashFile("file1", "file1");
  1088. git.add().addFilepattern("file1").call();
  1089. RevCommit first = git.commit().setMessage("initial commit").call();
  1090. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1091. createBranch(first, "refs/heads/branch1");
  1092. writeTrashFile("file2", "file2");
  1093. git.add().addFilepattern("file2").call();
  1094. RevCommit second = git.commit().setMessage("second commit").call();
  1095. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1096. checkoutBranch("refs/heads/branch1");
  1097. writeTrashFile("file3", "file3");
  1098. git.add().addFilepattern("file3").call();
  1099. RevCommit third = git.commit().setMessage("third commit").call();
  1100. assertTrue(new File(db.getWorkTree(), "file3").exists());
  1101. checkoutBranch("refs/heads/master");
  1102. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1103. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1104. assertFalse(new File(db.getWorkTree(), "file3").exists());
  1105. MergeResult result = git.merge().include(db.getRef("branch1"))
  1106. .setSquash(true).call();
  1107. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1108. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1109. assertTrue(new File(db.getWorkTree(), "file3").exists());
  1110. assertEquals(MergeResult.MergeStatus.MERGED_SQUASHED,
  1111. result.getMergeStatus());
  1112. assertEquals(second, result.getNewHead()); // HEAD didn't move
  1113. assertEquals(second, db.resolve(Constants.HEAD + "^{commit}"));
  1114. assertEquals(
  1115. "Squashed commit of the following:\n\ncommit "
  1116. + third.getName()
  1117. + "\nAuthor: "
  1118. + third.getAuthorIdent().getName()
  1119. + " <"
  1120. + third.getAuthorIdent().getEmailAddress()
  1121. + ">\nDate: "
  1122. + dateFormatter.formatDate(third
  1123. .getAuthorIdent()) + "\n\n\tthird commit\n",
  1124. db.readSquashCommitMsg());
  1125. assertNull(db.readMergeCommitMsg());
  1126. Status stat = git.status().call();
  1127. assertEquals(Sets.of("file3"), stat.getAdded());
  1128. }
  1129. @Test
  1130. public void testSquashMergeConflict() throws Exception {
  1131. Git git = new Git(db);
  1132. writeTrashFile("file1", "file1");
  1133. git.add().addFilepattern("file1").call();
  1134. RevCommit first = git.commit().setMessage("initial commit").call();
  1135. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1136. createBranch(first, "refs/heads/branch1");
  1137. writeTrashFile("file2", "master");
  1138. git.add().addFilepattern("file2").call();
  1139. RevCommit second = git.commit().setMessage("second commit").call();
  1140. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1141. checkoutBranch("refs/heads/branch1");
  1142. writeTrashFile("file2", "branch");
  1143. git.add().addFilepattern("file2").call();
  1144. RevCommit third = git.commit().setMessage("third commit").call();
  1145. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1146. checkoutBranch("refs/heads/master");
  1147. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1148. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1149. MergeResult result = git.merge().include(db.getRef("branch1"))
  1150. .setSquash(true).call();
  1151. assertTrue(new File(db.getWorkTree(), "file1").exists());
  1152. assertTrue(new File(db.getWorkTree(), "file2").exists());
  1153. assertEquals(MergeResult.MergeStatus.CONFLICTING,
  1154. result.getMergeStatus());
  1155. assertNull(result.getNewHead());
  1156. assertEquals(second, db.resolve(Constants.HEAD + "^{commit}"));
  1157. assertEquals(
  1158. "Squashed commit of the following:\n\ncommit "
  1159. + third.getName()
  1160. + "\nAuthor: "
  1161. + third.getAuthorIdent().getName()
  1162. + " <"
  1163. + third.getAuthorIdent().getEmailAddress()
  1164. + ">\nDate: "
  1165. + dateFormatter.formatDate(third
  1166. .getAuthorIdent()) + "\n\n\tthird commit\n",
  1167. db.readSquashCommitMsg());
  1168. assertEquals("\nConflicts:\n\tfile2\n", db.readMergeCommitMsg());
  1169. Status stat = git.status().call();
  1170. assertEquals(Sets.of("file2"), stat.getConflicting());
  1171. }
  1172. @Test
  1173. public void testFastForwardOnly() throws Exception {
  1174. Git git = new Git(db);
  1175. RevCommit initialCommit = git.commit().setMessage("initial commit")
  1176. .call();
  1177. createBranch(initialCommit, "refs/heads/branch1");
  1178. git.commit().setMessage("second commit").call();
  1179. checkoutBranch("refs/heads/branch1");
  1180. MergeCommand merge = git.merge();
  1181. merge.setFastForward(FastForwardMode.FF_ONLY);
  1182. merge.include(db.getRef(Constants.MASTER));
  1183. MergeResult result = merge.call();
  1184. assertEquals(MergeStatus.FAST_FORWARD, result.getMergeStatus());
  1185. }
  1186. @Test
  1187. public void testNoFastForward() throws Exception {
  1188. Git git = new Git(db);
  1189. RevCommit initialCommit = git.commit().setMessage("initial commit")
  1190. .call();
  1191. createBranch(initialCommit, "refs/heads/branch1");
  1192. git.commit().setMessage("second commit").call();
  1193. checkoutBranch("refs/heads/branch1");
  1194. MergeCommand merge = git.merge();
  1195. merge.setFastForward(FastForwardMode.NO_FF);
  1196. merge.include(db.getRef(Constants.MASTER));
  1197. MergeResult result = merge.call();
  1198. assertEquals(MergeStatus.MERGED, result.getMergeStatus());
  1199. }
  1200. @Test
  1201. public void testNoFastForwardNoCommit() throws Exception {
  1202. // given
  1203. Git git = new Git(db);
  1204. RevCommit initialCommit = git.commit().setMessage("initial commit")
  1205. .call();
  1206. createBranch(initialCommit, "refs/heads/branch1");
  1207. RevCommit secondCommit = git.commit().setMessage("second commit")
  1208. .call();
  1209. checkoutBranch("refs/heads/branch1");
  1210. // when
  1211. MergeCommand merge = git.merge();
  1212. merge.setFastForward(FastForwardMode.NO_FF);
  1213. merge.include(db.getRef(Constants.MASTER));
  1214. merge.setCommit(false);
  1215. MergeResult result = merge.call();
  1216. // then
  1217. assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
  1218. assertEquals(2, result.getMergedCommits().length);
  1219. assertEquals(initialCommit, result.getMergedCommits()[0]);
  1220. assertEquals(secondCommit, result.getMergedCommits()[1]);
  1221. assertNull(result.getNewHead());
  1222. assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
  1223. }
  1224. @Test
  1225. public void testFastForwardOnlyNotPossible() throws Exception {
  1226. Git git = new Git(db);
  1227. RevCommit initialCommit = git.commit().setMessage("initial commit")
  1228. .call();
  1229. createBranch(initialCommit, "refs/heads/branch1");
  1230. git.commit().setMessage("second commit").call();
  1231. checkoutBranch("refs/heads/branch1");
  1232. writeTrashFile("file1", "branch1");
  1233. git.add().addFilepattern("file").call();
  1234. git.commit().setMessage("second commit on branch1").call();
  1235. MergeCommand merge = git.merge();
  1236. merge.setFastForward(FastForwardMode.FF_ONLY);
  1237. merge.include(db.getRef(Constants.MASTER));
  1238. MergeResult result = merge.call();
  1239. assertEquals(MergeStatus.ABORTED, result.getMergeStatus());
  1240. }
  1241. @Test
  1242. public void testRecursiveMergeWithConflict() throws Exception {
  1243. TestRepository<Repository> db_t = new TestRepository<Repository>(db);
  1244. BranchBuilder master = db_t.branch("master");
  1245. RevCommit m0 = master.commit().add("f", "1\n2\n3\n4\n5\n6\n7\n8\n9\n")
  1246. .message("m0").create();
  1247. RevCommit m1 = master.commit()
  1248. .add("f", "1-master\n2\n3\n4\n5\n6\n7\n8\n9\n").message("m1")
  1249. .create();
  1250. db_t.getRevWalk().parseCommit(m1);
  1251. BranchBuilder side = db_t.branch("side");
  1252. RevCommit s1 = side.commit().parent(m0)
  1253. .add("f", "1\n2\n3\n4\n5\n6\n7\n8\n9-side\n").message("s1")
  1254. .create();
  1255. RevCommit s2 = side.commit().parent(m1)
  1256. .add("f", "1-master\n2\n3\n4\n5\n6\n7-res(side)\n8\n9-side\n")
  1257. .message("s2(merge)").create();
  1258. master.commit().parent(s1)
  1259. .add("f", "1-master\n2\n3\n4\n5\n6\n7-conflict\n8\n9-side\n")
  1260. .message("m2(merge)").create();
  1261. Git git = Git.wrap(db);
  1262. git.checkout().setName("master").call();
  1263. MergeResult result = git.merge().setStrategy(MergeStrategy.RECURSIVE)
  1264. .include("side", s2).call();
  1265. assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
  1266. }
  1267. private static void setExecutable(Git git, String path, boolean executable) {
  1268. FS.DETECTED.setExecute(
  1269. new File(git.getRepository().getWorkTree(), path), executable);
  1270. }
  1271. private static boolean canExecute(Git git, String path) {
  1272. return FS.DETECTED.canExecute(new File(git.getRepository()
  1273. .getWorkTree(), path));
  1274. }
  1275. private static RevCommit addAllAndCommit(final Git git) throws Exception {
  1276. git.add().addFilepattern(".").call();
  1277. return git.commit().setMessage("message").call();
  1278. }
  1279. private void checkMergeFailedResult(final MergeResult result,
  1280. final MergeFailureReason reason,
  1281. final String indexState, final File fileA) throws Exception {
  1282. assertEquals(MergeStatus.FAILED, result.getMergeStatus());
  1283. assertEquals(reason, result.getFailingPaths().get("a"));
  1284. assertEquals("a(modified)", read(fileA));
  1285. assertFalse(new File(db.getWorkTree(), "b").exists());
  1286. assertEquals("c", read(new File(db.getWorkTree(), "c")));
  1287. assertEquals(indexState, indexState(CONTENT));
  1288. assertEquals(null, result.getConflicts());
  1289. assertEquals(RepositoryState.SAFE, db.getRepositoryState());
  1290. }
  1291. }