Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

FileReftableTest.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * Copyright (C) 2019, Google Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.storage.file;
  11. import static org.eclipse.jgit.lib.RefUpdate.Result.FAST_FORWARD;
  12. import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED;
  13. import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE;
  14. import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE;
  15. import static org.junit.Assert.assertEquals;
  16. import static org.junit.Assert.assertFalse;
  17. import static org.junit.Assert.assertNotEquals;
  18. import static org.junit.Assert.assertNotNull;
  19. import static org.junit.Assert.assertNotSame;
  20. import static org.junit.Assert.assertNull;
  21. import static org.junit.Assert.assertSame;
  22. import static org.junit.Assert.assertTrue;
  23. import static org.junit.Assert.fail;
  24. import java.io.File;
  25. import java.io.IOException;
  26. import java.security.SecureRandom;
  27. import java.util.ArrayList;
  28. import java.util.List;
  29. import org.eclipse.jgit.lib.AnyObjectId;
  30. import org.eclipse.jgit.lib.Constants;
  31. import org.eclipse.jgit.lib.NullProgressMonitor;
  32. import org.eclipse.jgit.lib.ObjectId;
  33. import org.eclipse.jgit.lib.PersonIdent;
  34. import org.eclipse.jgit.lib.Ref;
  35. import org.eclipse.jgit.lib.RefRename;
  36. import org.eclipse.jgit.lib.RefUpdate;
  37. import org.eclipse.jgit.lib.RefUpdate.Result;
  38. import org.eclipse.jgit.lib.ReflogEntry;
  39. import org.eclipse.jgit.lib.ReflogReader;
  40. import org.eclipse.jgit.lib.RepositoryCache;
  41. import org.eclipse.jgit.revwalk.RevWalk;
  42. import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
  43. import org.eclipse.jgit.transport.ReceiveCommand;
  44. import org.junit.Test;
  45. public class FileReftableTest extends SampleDataRepositoryTestCase {
  46. String bCommit;
  47. @Override
  48. public void setUp() throws Exception {
  49. super.setUp();
  50. Ref b = db.exactRef("refs/heads/b");
  51. bCommit = b.getObjectId().getName();
  52. db.convertToReftable(false, false);
  53. }
  54. @SuppressWarnings("boxing")
  55. @Test
  56. public void testRacyReload() throws Exception {
  57. ObjectId id = db.resolve("master");
  58. int retry = 0;
  59. try (FileRepository repo1 = new FileRepository(db.getDirectory());
  60. FileRepository repo2 = new FileRepository(db.getDirectory())) {
  61. FileRepository repos[] = { repo1, repo2 };
  62. for (int i = 0; i < 10; i++) {
  63. for (int j = 0; j < 2; j++) {
  64. FileRepository repo = repos[j];
  65. RefUpdate u = repo.getRefDatabase().newUpdate(
  66. String.format("branch%d", i * 10 + j), false);
  67. u.setNewObjectId(id);
  68. RefUpdate.Result r = u.update();
  69. if (!r.equals(Result.NEW)) {
  70. retry++;
  71. u = repo.getRefDatabase().newUpdate(
  72. String.format("branch%d", i * 10 + j), false);
  73. u.setNewObjectId(id);
  74. r = u.update();
  75. assertEquals(r, Result.NEW);
  76. }
  77. }
  78. }
  79. // only the first one succeeds
  80. assertEquals(retry, 19);
  81. }
  82. }
  83. @Test
  84. public void testCompactFully() throws Exception {
  85. ObjectId c1 = db.resolve("master^^");
  86. ObjectId c2 = db.resolve("master^");
  87. for (int i = 0; i < 5; i++) {
  88. RefUpdate u = db.updateRef("refs/heads/master");
  89. u.setForceUpdate(true);
  90. u.setNewObjectId((i%2) == 0 ? c1 : c2);
  91. assertEquals(u.update(), FORCED);
  92. }
  93. File tableDir = new File(db.getDirectory(), Constants.REFTABLE);
  94. assertTrue(tableDir.listFiles().length > 2);
  95. ((FileReftableDatabase)db.getRefDatabase()).compactFully();
  96. assertEquals(tableDir.listFiles().length,2);
  97. }
  98. @Test
  99. public void testOpenConvert() throws Exception {
  100. try (FileRepository repo = new FileRepository(db.getDirectory())) {
  101. assertTrue(repo.getRefDatabase() instanceof FileReftableDatabase);
  102. }
  103. }
  104. @Test
  105. public void testConvert() throws Exception {
  106. Ref h = db.exactRef("HEAD");
  107. assertTrue(h.isSymbolic());
  108. assertEquals("refs/heads/master", h.getTarget().getName());
  109. Ref b = db.exactRef("refs/heads/b");
  110. assertFalse(b.isSymbolic());
  111. assertTrue(b.isPeeled());
  112. assertEquals(bCommit, b.getObjectId().name());
  113. assertTrue(db.getRefDatabase().hasFastTipsWithSha1());
  114. }
  115. @Test
  116. public void testConvertToRefdir() throws Exception {
  117. db.convertToPackedRefs(false, false);
  118. assertTrue(db.getRefDatabase() instanceof RefDirectory);
  119. Ref h = db.exactRef("HEAD");
  120. assertTrue(h.isSymbolic());
  121. assertEquals("refs/heads/master", h.getTarget().getName());
  122. Ref b = db.exactRef("refs/heads/b");
  123. assertFalse(b.isSymbolic());
  124. assertTrue(b.isPeeled());
  125. assertEquals(bCommit, b.getObjectId().name());
  126. assertFalse(db.getRefDatabase().hasFastTipsWithSha1());
  127. }
  128. @Test
  129. public void testConvertToRefdirReflog() throws Exception {
  130. Ref a = db.exactRef("refs/heads/a");
  131. String aCommit = a.getObjectId().getName();
  132. RefUpdate u = db.updateRef("refs/heads/master");
  133. u.setForceUpdate(true);
  134. u.setNewObjectId(ObjectId.fromString(aCommit));
  135. u.setForceRefLog(true);
  136. u.setRefLogMessage("apple", false);
  137. u.update();
  138. RefUpdate v = db.updateRef("refs/heads/master");
  139. v.setForceUpdate(true);
  140. v.setNewObjectId(ObjectId.fromString(bCommit));
  141. v.setForceRefLog(true);
  142. v.setRefLogMessage("banana", false);
  143. v.update();
  144. db.convertToPackedRefs(true, false);
  145. List<ReflogEntry> logs = db.getReflogReader("refs/heads/master").getReverseEntries(2);
  146. assertEquals(logs.get(0).getComment(), "banana");
  147. assertEquals(logs.get(1).getComment(), "apple");
  148. }
  149. @Test
  150. public void testBatchrefUpdate() throws Exception {
  151. ObjectId cur = db.resolve("master");
  152. ObjectId prev = db.resolve("master^");
  153. PersonIdent person = new PersonIdent("name", "mail@example.com");
  154. ReceiveCommand rc1 = new ReceiveCommand(ObjectId.zeroId(), cur, "refs/heads/batch1");
  155. ReceiveCommand rc2 = new ReceiveCommand(ObjectId.zeroId(), prev, "refs/heads/batch2");
  156. String msg = "message";
  157. try (RevWalk rw = new RevWalk(db)) {
  158. db.getRefDatabase().newBatchUpdate()
  159. .addCommand(rc1, rc2)
  160. .setAtomic(true)
  161. .setRefLogIdent(person)
  162. .setRefLogMessage(msg, false)
  163. .execute(rw, NullProgressMonitor.INSTANCE);
  164. }
  165. assertEquals(rc1.getResult(), ReceiveCommand.Result.OK);
  166. assertEquals(rc2.getResult(), ReceiveCommand.Result.OK);
  167. ReflogEntry e = db.getReflogReader("refs/heads/batch1").getLastEntry();
  168. assertEquals(msg, e.getComment());
  169. assertEquals(person, e.getWho());
  170. assertEquals(cur, e.getNewId());
  171. e = db.getReflogReader("refs/heads/batch2").getLastEntry();
  172. assertEquals(msg, e.getComment());
  173. assertEquals(person, e.getWho());
  174. assertEquals(prev, e.getNewId());
  175. assertEquals(cur, db.exactRef("refs/heads/batch1").getObjectId());
  176. assertEquals(prev, db.exactRef("refs/heads/batch2").getObjectId());
  177. }
  178. @Test
  179. public void testFastforwardStatus() throws Exception {
  180. ObjectId cur = db.resolve("master");
  181. ObjectId prev = db.resolve("master^");
  182. RefUpdate u = db.updateRef("refs/heads/master");
  183. u.setNewObjectId(prev);
  184. u.setForceUpdate(true);
  185. assertEquals(FORCED, u.update());
  186. RefUpdate u2 = db.updateRef("refs/heads/master");
  187. u2.setNewObjectId(cur);
  188. assertEquals(FAST_FORWARD, u2.update());
  189. }
  190. @Test
  191. public void testUpdateChecksOldValue() throws Exception {
  192. ObjectId cur = db.resolve("master");
  193. ObjectId prev = db.resolve("master^");
  194. RefUpdate u1 = db.updateRef("refs/heads/master");
  195. RefUpdate u2 = db.updateRef("refs/heads/master");
  196. u1.setExpectedOldObjectId(cur);
  197. u1.setNewObjectId(prev);
  198. u1.setForceUpdate(true);
  199. u2.setExpectedOldObjectId(cur);
  200. u2.setNewObjectId(prev);
  201. u2.setForceUpdate(true);
  202. assertEquals(FORCED, u1.update());
  203. assertEquals(LOCK_FAILURE, u2.update());
  204. }
  205. @Test
  206. public void testWritesymref() throws Exception {
  207. writeSymref(Constants.HEAD, "refs/heads/a");
  208. assertNotNull(db.exactRef("refs/heads/b"));
  209. }
  210. @Test
  211. public void testFastforwardStatus2() throws Exception {
  212. writeSymref(Constants.HEAD, "refs/heads/a");
  213. ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
  214. RefUpdate u = db.updateRef("refs/heads/a");
  215. u.setNewObjectId(bId);
  216. u.setRefLogMessage("Setup", false);
  217. assertEquals(FAST_FORWARD, u.update());
  218. }
  219. @Test
  220. public void testDelete() throws Exception {
  221. RefUpdate up = db.getRefDatabase().newUpdate("refs/heads/a", false);
  222. up.setForceUpdate(true);
  223. RefUpdate.Result res = up.delete();
  224. assertEquals(res, FORCED);
  225. assertNull(db.exactRef("refs/heads/a"));
  226. }
  227. @Test
  228. public void testDeleteWithoutHead() throws IOException {
  229. // Prepare repository without HEAD
  230. RefUpdate refUpdate = db.updateRef(Constants.HEAD, true);
  231. refUpdate.setForceUpdate(true);
  232. refUpdate.setNewObjectId(ObjectId.zeroId());
  233. RefUpdate.Result updateResult = refUpdate.update();
  234. assertEquals(FORCED, updateResult);
  235. Ref r = db.exactRef("HEAD");
  236. assertEquals(ObjectId.zeroId(), r.getObjectId());
  237. RefUpdate.Result deleteHeadResult = db.updateRef(Constants.HEAD)
  238. .delete();
  239. // why does doDelete say NEW ?
  240. assertEquals(RefUpdate.Result.NO_CHANGE, deleteHeadResult);
  241. // Any result is ok as long as it's not an NPE
  242. db.updateRef(Constants.R_HEADS + "master").delete();
  243. }
  244. @Test
  245. public void testUpdateRefDetached() throws Exception {
  246. ObjectId pid = db.resolve("refs/heads/master");
  247. ObjectId ppid = db.resolve("refs/heads/master^");
  248. RefUpdate updateRef = db.updateRef("HEAD", true);
  249. updateRef.setForceUpdate(true);
  250. updateRef.setNewObjectId(ppid);
  251. RefUpdate.Result update = updateRef.update();
  252. assertEquals(FORCED, update);
  253. assertEquals(ppid, db.resolve("HEAD"));
  254. Ref ref = db.exactRef("HEAD");
  255. assertEquals("HEAD", ref.getName());
  256. assertTrue("is detached", !ref.isSymbolic());
  257. // the branch HEAD referred to is left untouched
  258. assertEquals(pid, db.resolve("refs/heads/master"));
  259. ReflogReader reflogReader = db.getReflogReader("HEAD");
  260. ReflogEntry e = reflogReader.getReverseEntries().get(0);
  261. assertEquals(ppid, e.getNewId());
  262. assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
  263. assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
  264. assertEquals(1250379778000L, e.getWho().getWhen().getTime());
  265. assertEquals(pid, e.getOldId());
  266. }
  267. @Test
  268. public void testWriteReflog() throws Exception {
  269. ObjectId pid = db.resolve("refs/heads/master^");
  270. RefUpdate updateRef = db.updateRef("refs/heads/master");
  271. updateRef.setNewObjectId(pid);
  272. String msg = "REFLOG!";
  273. updateRef.setRefLogMessage(msg, true);
  274. PersonIdent person = new PersonIdent("name", "mail@example.com");
  275. updateRef.setRefLogIdent(person);
  276. updateRef.setForceUpdate(true);
  277. RefUpdate.Result update = updateRef.update();
  278. assertEquals(FORCED, update); // internal
  279. ReflogReader r = db.getReflogReader("refs/heads/master");
  280. ReflogEntry e = r.getLastEntry();
  281. assertEquals(e.getNewId(), pid);
  282. assertEquals(e.getComment(), "REFLOG!: FORCED");
  283. assertEquals(e.getWho(), person);
  284. }
  285. @Test
  286. public void testLooseDelete() throws IOException {
  287. final String newRef = "refs/heads/abc";
  288. assertNull(db.exactRef(newRef));
  289. RefUpdate ref = db.updateRef(newRef);
  290. ObjectId nonZero = db.resolve(Constants.HEAD);
  291. assertNotEquals(nonZero, ObjectId.zeroId());
  292. ref.setNewObjectId(nonZero);
  293. assertEquals(RefUpdate.Result.NEW, ref.update());
  294. ref = db.updateRef(newRef);
  295. ref.setNewObjectId(db.resolve(Constants.HEAD));
  296. assertEquals(ref.delete(), RefUpdate.Result.NO_CHANGE);
  297. // Differs from RefupdateTest. Deleting a loose ref leaves reflog trail.
  298. ReflogReader reader = db.getReflogReader("refs/heads/abc");
  299. assertEquals(ObjectId.zeroId(), reader.getReverseEntry(1).getOldId());
  300. assertEquals(nonZero, reader.getReverseEntry(1).getNewId());
  301. assertEquals(nonZero, reader.getReverseEntry(0).getOldId());
  302. assertEquals(ObjectId.zeroId(), reader.getReverseEntry(0).getNewId());
  303. }
  304. private static class SubclassedId extends ObjectId {
  305. SubclassedId(AnyObjectId src) {
  306. super(src);
  307. }
  308. }
  309. @Test
  310. public void testNoCacheObjectIdSubclass() throws IOException {
  311. final String newRef = "refs/heads/abc";
  312. final RefUpdate ru = updateRef(newRef);
  313. final SubclassedId newid = new SubclassedId(ru.getNewObjectId());
  314. ru.setNewObjectId(newid);
  315. RefUpdate.Result update = ru.update();
  316. assertEquals(RefUpdate.Result.NEW, update);
  317. Ref r = db.exactRef(newRef);
  318. assertEquals(newRef, r.getName());
  319. assertNotNull(r.getObjectId());
  320. assertNotSame(newid, r.getObjectId());
  321. assertSame(ObjectId.class, r.getObjectId().getClass());
  322. assertEquals(newid, r.getObjectId());
  323. List<ReflogEntry> reverseEntries1 = db.getReflogReader("refs/heads/abc")
  324. .getReverseEntries();
  325. ReflogEntry entry1 = reverseEntries1.get(0);
  326. assertEquals(1, reverseEntries1.size());
  327. assertEquals(ObjectId.zeroId(), entry1.getOldId());
  328. assertEquals(r.getObjectId(), entry1.getNewId());
  329. assertEquals(new PersonIdent(db).toString(),
  330. entry1.getWho().toString());
  331. assertEquals("", entry1.getComment());
  332. List<ReflogEntry> reverseEntries2 = db.getReflogReader("HEAD")
  333. .getReverseEntries();
  334. assertEquals(0, reverseEntries2.size());
  335. }
  336. @Test
  337. public void testDeleteSymref() throws IOException {
  338. RefUpdate dst = updateRef("refs/heads/abc");
  339. assertEquals(RefUpdate.Result.NEW, dst.update());
  340. ObjectId id = dst.getNewObjectId();
  341. RefUpdate u = db.updateRef("refs/symref");
  342. assertEquals(RefUpdate.Result.NEW, u.link(dst.getName()));
  343. Ref ref = db.exactRef(u.getName());
  344. assertNotNull(ref);
  345. assertTrue(ref.isSymbolic());
  346. assertEquals(dst.getName(), ref.getLeaf().getName());
  347. assertEquals(id, ref.getLeaf().getObjectId());
  348. u = db.updateRef(u.getName());
  349. u.setDetachingSymbolicRef();
  350. u.setForceUpdate(true);
  351. assertEquals(FORCED, u.delete());
  352. assertNull(db.exactRef(u.getName()));
  353. ref = db.exactRef(dst.getName());
  354. assertNotNull(ref);
  355. assertFalse(ref.isSymbolic());
  356. assertEquals(id, ref.getObjectId());
  357. }
  358. @Test
  359. public void writeUnbornHead() throws Exception {
  360. RefUpdate.Result r = db.updateRef("HEAD").link("refs/heads/unborn");
  361. assertEquals(FORCED, r);
  362. Ref head = db.exactRef("HEAD");
  363. assertTrue(head.isSymbolic());
  364. assertEquals(head.getTarget().getName(), "refs/heads/unborn");
  365. }
  366. /**
  367. * Update the HEAD ref when the referenced branch is unborn
  368. *
  369. * @throws Exception
  370. */
  371. @Test
  372. public void testUpdateRefDetachedUnbornHead() throws Exception {
  373. ObjectId ppid = db.resolve("refs/heads/master^");
  374. writeSymref("HEAD", "refs/heads/unborn");
  375. RefUpdate updateRef = db.updateRef("HEAD", true);
  376. updateRef.setForceUpdate(true);
  377. updateRef.setNewObjectId(ppid);
  378. RefUpdate.Result update = updateRef.update();
  379. assertEquals(RefUpdate.Result.NEW, update);
  380. assertEquals(ppid, db.resolve("HEAD"));
  381. Ref ref = db.exactRef("HEAD");
  382. assertEquals("HEAD", ref.getName());
  383. assertTrue("is detached", !ref.isSymbolic());
  384. // the branch HEAD referred to is left untouched
  385. assertNull(db.resolve("refs/heads/unborn"));
  386. ReflogReader reflogReader = db.getReflogReader("HEAD");
  387. ReflogEntry e = reflogReader.getReverseEntries().get(0);
  388. assertEquals(ObjectId.zeroId(), e.getOldId());
  389. assertEquals(ppid, e.getNewId());
  390. assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
  391. assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
  392. assertEquals(1250379778000L, e.getWho().getWhen().getTime());
  393. }
  394. @Test
  395. public void testDeleteNotFound() throws IOException {
  396. RefUpdate ref = updateRef("refs/heads/doesnotexist");
  397. assertNull(db.exactRef(ref.getName()));
  398. assertEquals(RefUpdate.Result.NEW, ref.delete());
  399. assertNull(db.exactRef(ref.getName()));
  400. }
  401. @Test
  402. public void testRenameSymref() throws IOException {
  403. db.resolve("HEAD");
  404. RefRename r = db.renameRef("HEAD", "KOPF");
  405. assertEquals(IO_FAILURE, r.rename());
  406. }
  407. @Test
  408. public void testRenameCurrentBranch() throws IOException {
  409. ObjectId rb = db.resolve("refs/heads/b");
  410. writeSymref(Constants.HEAD, "refs/heads/b");
  411. ObjectId oldHead = db.resolve(Constants.HEAD);
  412. assertEquals("internal test condition, b == HEAD", oldHead, rb);
  413. RefRename renameRef = db.renameRef("refs/heads/b",
  414. "refs/heads/new/name");
  415. RefUpdate.Result result = renameRef.rename();
  416. assertEquals(RefUpdate.Result.RENAMED, result);
  417. assertEquals(rb, db.resolve("refs/heads/new/name"));
  418. assertNull(db.resolve("refs/heads/b"));
  419. assertEquals(rb, db.resolve(Constants.HEAD));
  420. List<String> names = new ArrayList<>();
  421. names.add("HEAD");
  422. names.add("refs/heads/b");
  423. names.add("refs/heads/new/name");
  424. for (String nm : names) {
  425. ReflogReader rd = db.getReflogReader(nm);
  426. assertNotNull(rd);
  427. ReflogEntry last = rd.getLastEntry();
  428. ObjectId id = last.getNewId();
  429. assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
  430. id = last.getNewId();
  431. assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
  432. String want = "Branch: renamed b to new/name";
  433. assertEquals(want, last.getComment());
  434. }
  435. }
  436. @Test
  437. public void isGitRepository() {
  438. assertTrue(RepositoryCache.FileKey.isGitRepository(db.getDirectory(), db.getFS()));
  439. }
  440. @Test
  441. public void testRenameDestExists() throws IOException {
  442. ObjectId rb = db.resolve("refs/heads/b");
  443. writeSymref(Constants.HEAD, "refs/heads/b");
  444. ObjectId oldHead = db.resolve(Constants.HEAD);
  445. assertEquals("internal test condition, b == HEAD", oldHead, rb);
  446. RefRename renameRef = db.renameRef("refs/heads/b", "refs/heads/a");
  447. RefUpdate.Result result = renameRef.rename();
  448. assertEquals(RefUpdate.Result.LOCK_FAILURE, result);
  449. }
  450. @Test
  451. public void testRenameAtomic() throws IOException {
  452. ObjectId prevId = db.resolve("refs/heads/master^");
  453. RefRename rename = db.renameRef("refs/heads/master",
  454. "refs/heads/newmaster");
  455. RefUpdate updateRef = db.updateRef("refs/heads/master");
  456. updateRef.setNewObjectId(prevId);
  457. updateRef.setForceUpdate(true);
  458. assertEquals(FORCED, updateRef.update());
  459. assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename());
  460. }
  461. @Test
  462. public void compactFully() throws Exception {
  463. FileReftableDatabase refDb = (FileReftableDatabase) db.getRefDatabase();
  464. PersonIdent person = new PersonIdent("jane", "jane@invalid");
  465. ObjectId aId = db.exactRef("refs/heads/a").getObjectId();
  466. ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
  467. SecureRandom random = new SecureRandom();
  468. List<String> strs = new ArrayList<>();
  469. for (int i = 0; i < 1024; i++) {
  470. strs.add(String.format("%02x",
  471. Integer.valueOf(random.nextInt(256))));
  472. }
  473. String randomStr = String.join("", strs);
  474. String refName = "branch";
  475. for (long i = 0; i < 2; i++) {
  476. RefUpdate ru = refDb.newUpdate(refName, false);
  477. ru.setNewObjectId(i % 2 == 0 ? aId : bId);
  478. ru.setForceUpdate(true);
  479. // Only write a large string in the first table, so it becomes much larger
  480. // than the second, and the result is not autocompacted.
  481. ru.setRefLogMessage(i == 0 ? randomStr : "short", false);
  482. ru.setRefLogIdent(person);
  483. RefUpdate.Result res = ru.update();
  484. assertTrue(res == Result.NEW || res == FORCED);
  485. }
  486. assertEquals(refDb.exactRef(refName).getObjectId(), bId);
  487. assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
  488. refDb.compactFully();
  489. assertEquals(refDb.exactRef(refName).getObjectId(), bId);
  490. assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
  491. }
  492. @Test
  493. public void reftableRefsStorageClass() throws IOException {
  494. Ref b = db.exactRef("refs/heads/b");
  495. assertEquals(Ref.Storage.PACKED, b.getStorage());
  496. }
  497. private RefUpdate updateRef(String name) throws IOException {
  498. final RefUpdate ref = db.updateRef(name);
  499. ref.setNewObjectId(db.resolve(Constants.HEAD));
  500. return ref;
  501. }
  502. private void writeSymref(String src, String dst) throws IOException {
  503. RefUpdate u = db.updateRef(src);
  504. switch (u.link(dst)) {
  505. case NEW:
  506. case FORCED:
  507. case NO_CHANGE:
  508. break;
  509. default:
  510. fail("link " + src + " to " + dst);
  511. }
  512. }
  513. }