1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jgit.internal.storage.file;
15
16 import static java.nio.charset.StandardCharsets.ISO_8859_1;
17 import static java.nio.charset.StandardCharsets.UTF_8;
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNotSame;
22 import static org.junit.Assert.assertThrows;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.IOException;
29 import java.io.UnsupportedEncodingException;
30 import java.time.Instant;
31
32 import org.eclipse.jgit.errors.ConfigInvalidException;
33 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
34 import org.eclipse.jgit.errors.MissingObjectException;
35 import org.eclipse.jgit.internal.JGitText;
36 import org.eclipse.jgit.lib.AnyObjectId;
37 import org.eclipse.jgit.lib.CommitBuilder;
38 import org.eclipse.jgit.lib.Constants;
39 import org.eclipse.jgit.lib.FileMode;
40 import org.eclipse.jgit.lib.ObjectDatabase;
41 import org.eclipse.jgit.lib.ObjectId;
42 import org.eclipse.jgit.lib.ObjectInserter;
43 import org.eclipse.jgit.lib.PersonIdent;
44 import org.eclipse.jgit.lib.RefUpdate;
45 import org.eclipse.jgit.lib.Repository;
46 import org.eclipse.jgit.lib.TagBuilder;
47 import org.eclipse.jgit.lib.TreeFormatter;
48 import org.eclipse.jgit.revwalk.RevCommit;
49 import org.eclipse.jgit.revwalk.RevTag;
50 import org.eclipse.jgit.revwalk.RevWalk;
51 import org.eclipse.jgit.storage.file.FileBasedConfig;
52 import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
53 import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
54 import org.eclipse.jgit.util.FS;
55 import org.eclipse.jgit.util.FileUtils;
56 import org.eclipse.jgit.util.IO;
57 import org.junit.Test;
58
59 public class T0003_BasicTest extends SampleDataRepositoryTestCase {
60
61 @Test
62 public void test001_Initalize() {
63 final File gitdir = new File(trash, Constants.DOT_GIT);
64 final File hooks = new File(gitdir, "hooks");
65 final File objects = new File(gitdir, Constants.OBJECTS);
66 final File objects_pack = new File(objects, "pack");
67 final File objects_info = new File(objects, "info");
68 final File refs = new File(gitdir, "refs");
69 final File refs_heads = new File(refs, "heads");
70 final File refs_tags = new File(refs, "tags");
71 final File HEAD = new File(gitdir, "HEAD");
72
73 assertTrue("Exists " + trash, trash.isDirectory());
74 assertTrue("Exists " + hooks, hooks.isDirectory());
75 assertTrue("Exists " + objects, objects.isDirectory());
76 assertTrue("Exists " + objects_pack, objects_pack.isDirectory());
77 assertTrue("Exists " + objects_info, objects_info.isDirectory());
78 assertEquals(2L, objects.listFiles().length);
79 assertTrue("Exists " + refs, refs.isDirectory());
80 assertTrue("Exists " + refs_heads, refs_heads.isDirectory());
81 assertTrue("Exists " + refs_tags, refs_tags.isDirectory());
82 assertTrue("Exists " + HEAD, HEAD.isFile());
83 assertEquals(23, HEAD.length());
84 }
85
86 @Test
87 public void test000_openRepoBadArgs() throws IOException {
88 try {
89 new FileRepositoryBuilder().build();
90 fail("Must pass either GIT_DIR or GIT_WORK_TREE");
91 } catch (IllegalArgumentException e) {
92 assertEquals(JGitText.get().eitherGitDirOrWorkTreeRequired, e
93 .getMessage());
94 }
95 }
96
97
98
99
100
101
102
103 @Test
104 public void test000_openrepo_default_gitDirSet() throws IOException {
105 File repo1Parent = new File(trash.getParentFile(), "r1");
106 try (Repository repo1initial = new FileRepository(
107 new File(repo1Parent, Constants.DOT_GIT))) {
108 repo1initial.create();
109 }
110
111 File theDir = new File(repo1Parent, Constants.DOT_GIT);
112 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
113 .setGitDir(theDir).build()) {
114 assertEqualsPath(theDir, r.getDirectory());
115 assertEqualsPath(repo1Parent, r.getWorkTree());
116 assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
117 assertEqualsPath(new File(theDir, Constants.OBJECTS),
118 r.getObjectDatabase().getDirectory());
119 }
120 }
121
122
123
124
125
126
127
128 @Test
129 public void test000_openrepo_default_gitDirAndWorkTreeSet()
130 throws IOException {
131 File repo1Parent = new File(trash.getParentFile(), "r1");
132 try (Repository repo1initial = new FileRepository(
133 new File(repo1Parent, Constants.DOT_GIT))) {
134 repo1initial.create();
135 }
136
137 File theDir = new File(repo1Parent, Constants.DOT_GIT);
138 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
139 .setGitDir(theDir).setWorkTree(repo1Parent.getParentFile())
140 .build()) {
141 assertEqualsPath(theDir, r.getDirectory());
142 assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree());
143 assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
144 assertEqualsPath(new File(theDir, Constants.OBJECTS),
145 r.getObjectDatabase().getDirectory());
146 }
147 }
148
149
150
151
152
153
154
155 @Test
156 public void test000_openrepo_default_workDirSet() throws IOException {
157 File repo1Parent = new File(trash.getParentFile(), "r1");
158 try (Repository repo1initial = new FileRepository(
159 new File(repo1Parent, Constants.DOT_GIT))) {
160 repo1initial.create();
161 }
162
163 File theDir = new File(repo1Parent, Constants.DOT_GIT);
164 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
165 .setWorkTree(repo1Parent).build()) {
166 assertEqualsPath(theDir, r.getDirectory());
167 assertEqualsPath(repo1Parent, r.getWorkTree());
168 assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
169 assertEqualsPath(new File(theDir, Constants.OBJECTS),
170 r.getObjectDatabase().getDirectory());
171 }
172 }
173
174
175
176
177
178
179 @Test
180 public void test000_openrepo_default_absolute_workdirconfig()
181 throws IOException {
182 File repo1Parent = new File(trash.getParentFile(), "r1");
183 File workdir = new File(trash.getParentFile(), "rw");
184 FileUtils.mkdir(workdir);
185 try (FileRepository repo1initial = new FileRepository(
186 new File(repo1Parent, Constants.DOT_GIT))) {
187 repo1initial.create();
188 final FileBasedConfig cfg = repo1initial.getConfig();
189 cfg.setString("core", null, "worktree", workdir.getAbsolutePath());
190 cfg.save();
191 }
192
193 File theDir = new File(repo1Parent, Constants.DOT_GIT);
194 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
195 .setGitDir(theDir).build()) {
196 assertEqualsPath(theDir, r.getDirectory());
197 assertEqualsPath(workdir, r.getWorkTree());
198 assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
199 assertEqualsPath(new File(theDir, Constants.OBJECTS),
200 r.getObjectDatabase().getDirectory());
201 }
202 }
203
204
205
206
207
208
209 @Test
210 public void test000_openrepo_default_relative_workdirconfig()
211 throws IOException {
212 File repo1Parent = new File(trash.getParentFile(), "r1");
213 File workdir = new File(trash.getParentFile(), "rw");
214 FileUtils.mkdir(workdir);
215 try (FileRepository repo1initial = new FileRepository(
216 new File(repo1Parent, Constants.DOT_GIT))) {
217 repo1initial.create();
218 final FileBasedConfig cfg = repo1initial.getConfig();
219 cfg.setString("core", null, "worktree", "../../rw");
220 cfg.save();
221 }
222
223 File theDir = new File(repo1Parent, Constants.DOT_GIT);
224 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
225 .setGitDir(theDir).build()) {
226 assertEqualsPath(theDir, r.getDirectory());
227 assertEqualsPath(workdir, r.getWorkTree());
228 assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
229 assertEqualsPath(new File(theDir, Constants.OBJECTS),
230 r.getObjectDatabase().getDirectory());
231 }
232 }
233
234
235
236
237
238
239
240 @Test
241 public void test000_openrepo_alternate_index_file_and_objdirs()
242 throws IOException {
243 File repo1Parent = new File(trash.getParentFile(), "r1");
244 File indexFile = new File(trash, "idx");
245 File objDir = new File(trash, "../obj");
246 File altObjDir = db.getObjectDatabase().getDirectory();
247 try (Repository repo1initial = new FileRepository(
248 new File(repo1Parent, Constants.DOT_GIT))) {
249 repo1initial.create();
250 }
251
252 File theDir = new File(repo1Parent, Constants.DOT_GIT);
253 try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
254 .setGitDir(theDir).setObjectDirectory(objDir)
255 .addAlternateObjectDirectory(altObjDir)
256 .setIndexFile(indexFile)
257 .build()) {
258 assertEqualsPath(theDir, r.getDirectory());
259 assertEqualsPath(theDir.getParentFile(), r.getWorkTree());
260 assertEqualsPath(indexFile, r.getIndexFile());
261 assertEqualsPath(objDir, r.getObjectDatabase().getDirectory());
262 assertNotNull(r.open(ObjectId
263 .fromString("6db9c2ebf75590eef973081736730a9ea169a0c4")));
264 }
265 }
266
267 protected void assertEqualsPath(File expected, File actual)
268 throws IOException {
269 assertEquals(expected.getCanonicalPath(), actual.getCanonicalPath());
270 }
271
272 @Test
273 public void test002_WriteEmptyTree() throws IOException {
274
275
276
277
278 try (Repository newdb = createBareRepository()) {
279 try (ObjectInserter oi = newdb.newObjectInserter()) {
280 final ObjectId treeId = oi.insert(new TreeFormatter());
281 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904",
282 treeId.name());
283 }
284
285 final File o = new File(
286 new File(new File(newdb.getDirectory(), Constants.OBJECTS),
287 "4b"),
288 "825dc642cb6eb9a060e54bf8d69288fbee4904");
289 assertTrue("Exists " + o, o.isFile());
290 assertTrue("Read-only " + o, !o.canWrite());
291 }
292 }
293
294 @Test
295 public void test002_WriteEmptyTree2() throws IOException {
296
297
298 final ObjectId treeId = insertTree(new TreeFormatter());
299 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", treeId.name());
300 final File o = new File(new File(
301 new File(db.getDirectory(), Constants.OBJECTS), "4b"),
302 "825dc642cb6eb9a060e54bf8d69288fbee4904");
303 assertFalse("Exists " + o, o.isFile());
304 }
305
306 @Test
307 public void test002_CreateBadTree() throws Exception {
308
309
310 final TreeFormatter formatter = new TreeFormatter();
311 assertThrows(JGitText.get().invalidTreeZeroLengthName,
312 IllegalArgumentException.class,
313 () -> formatter.append("", FileMode.TREE, ObjectId.fromString(
314 "4b825dc642cb6eb9a060e54bf8d69288fbee4904")));
315 }
316
317 @Test
318 public void test006_ReadUglyConfig() throws IOException,
319 ConfigInvalidException {
320 final File cfg = new File(db.getDirectory(), Constants.CONFIG);
321 final FileBasedConfig c = new FileBasedConfig(cfg, db.getFS());
322 final String configStr = " [core];comment\n\tfilemode = yes\n"
323 + "[user]\n"
324 + " email = A U Thor <thor@example.com> # Just an example...\n"
325 + " name = \"A Thor \\\\ \\\"\\t \"\n"
326 + " defaultCheckInComment = a many line\\n\\\ncomment\\n\\\n"
327 + " to test\n";
328 write(cfg, configStr);
329 c.load();
330 assertEquals("yes", c.getString("core", null, "filemode"));
331 assertEquals("A U Thor <thor@example.com>", c.getString("user", null,
332 "email"));
333 assertEquals("A Thor \\ \"\t ", c.getString("user", null, "name"));
334 assertEquals("a many line\ncomment\n to test", c.getString("user",
335 null, "defaultCheckInComment"));
336 c.save();
337
338
339
340 final String expectedStr = " [core];comment\n\tfilemode = yes\n"
341 + "[user]\n"
342 + " email = A U Thor <thor@example.com> # Just an example...\n"
343 + " name = \"A Thor \\\\ \\\"\\t \"\n"
344 + " defaultCheckInComment = a many line\\ncomment\\n to test\n";
345 assertEquals(expectedStr, new String(IO.readFully(cfg), UTF_8));
346 }
347
348 @Test
349 public void test007_Open() throws IOException {
350 try (FileRepository db2 = new FileRepository(db.getDirectory())) {
351 assertEquals(db.getDirectory(), db2.getDirectory());
352 assertEquals(db.getObjectDatabase().getDirectory(), db2
353 .getObjectDatabase().getDirectory());
354 assertNotSame(db.getConfig(), db2.getConfig());
355 }
356 }
357
358 @Test
359 public void test008_FailOnWrongVersion() throws IOException {
360 final File cfg = new File(db.getDirectory(), Constants.CONFIG);
361 final String badvers = "ihopethisisneveraversion";
362 final String configStr = "[core]\n" + "\trepositoryFormatVersion="
363 + badvers + "\n";
364 write(cfg, configStr);
365
366 try (FileRepository unused = new FileRepository(db.getDirectory())) {
367 fail("incorrectly opened a bad repository");
368 } catch (IllegalArgumentException ioe) {
369 assertNotNull(ioe.getMessage());
370 }
371 }
372
373 @Test
374 public void test009_CreateCommitOldFormat() throws IOException {
375 final ObjectId treeId = insertTree(new TreeFormatter());
376 final CommitBuilder c = new CommitBuilder();
377 c.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
378 c.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
379 c.setMessage("A Commit\n");
380 c.setTreeId(treeId);
381 assertEquals(treeId, c.getTreeId());
382
383 ObjectId actid = insertCommit(c);
384
385 final ObjectId cmtid = ObjectId
386 .fromString("9208b2459ea6609a5af68627cc031796d0d9329b");
387 assertEquals(cmtid, actid);
388
389
390 ObjectDatabase odb = db.getObjectDatabase();
391 assertTrue("is ObjectDirectory", odb instanceof ObjectDirectory);
392 try (XInputStream xis = new XInputStream(
393 new FileInputStream(((ObjectDirectory) odb).fileFor(cmtid)))) {
394 assertEquals(0x78, xis.readUInt8());
395 assertEquals(0x9c, xis.readUInt8());
396 assertEquals(0, 0x789c % 31);
397 }
398
399
400 RevCommit c2 = parseCommit(actid);
401 assertNotNull(c2);
402 assertEquals(c.getMessage(), c2.getFullMessage());
403 assertEquals(c.getTreeId(), c2.getTree());
404 assertEquals(c.getAuthor(), c2.getAuthorIdent());
405 assertEquals(c.getCommitter(), c2.getCommitterIdent());
406 }
407
408 @Test
409 public void test020_createBlobTag() throws IOException {
410 final ObjectId emptyId = insertEmptyBlob();
411 final TagBuilder t = new TagBuilder();
412 t.setObjectId(emptyId, Constants.OBJ_BLOB);
413 t.setTag("test020");
414 t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60));
415 t.setMessage("test020 tagged\n");
416 ObjectId actid = insertTag(t);
417 assertEquals("6759556b09fbb4fd8ae5e315134481cc25d46954", actid.name());
418
419 RevTag mapTag = parseTag(actid);
420 assertEquals(Constants.OBJ_BLOB, mapTag.getObject().getType());
421 assertEquals("test020 tagged\n", mapTag.getFullMessage());
422 assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag
423 .getTaggerIdent());
424 assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag
425 .getObject().getId().name());
426 }
427
428 @Test
429 public void test021_createTreeTag() throws IOException {
430 final ObjectId emptyId = insertEmptyBlob();
431 TreeFormatter almostEmptyTree = new TreeFormatter();
432 almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
433 final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
434 final TagBuilder t = new TagBuilder();
435 t.setObjectId(almostEmptyTreeId, Constants.OBJ_TREE);
436 t.setTag("test021");
437 t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60));
438 t.setMessage("test021 tagged\n");
439 ObjectId actid = insertTag(t);
440 assertEquals("b0517bc8dbe2096b419d42424cd7030733f4abe5", actid.name());
441
442 RevTag mapTag = parseTag(actid);
443 assertEquals(Constants.OBJ_TREE, mapTag.getObject().getType());
444 assertEquals("test021 tagged\n", mapTag.getFullMessage());
445 assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag
446 .getTaggerIdent());
447 assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag
448 .getObject().getId().name());
449 }
450
451 @Test
452 public void test022_createCommitTag() throws IOException {
453 final ObjectId emptyId = insertEmptyBlob();
454 TreeFormatter almostEmptyTree = new TreeFormatter();
455 almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
456 final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
457 final CommitBuilder almostEmptyCommit = new CommitBuilder();
458 almostEmptyCommit.setAuthor(new PersonIdent(author, 1154236443000L,
459 -2 * 60));
460 almostEmptyCommit.setCommitter(new PersonIdent(author, 1154236443000L,
461 -2 * 60));
462 almostEmptyCommit.setMessage("test022\n");
463 almostEmptyCommit.setTreeId(almostEmptyTreeId);
464 ObjectId almostEmptyCommitId = insertCommit(almostEmptyCommit);
465 final TagBuilder t = new TagBuilder();
466 t.setObjectId(almostEmptyCommitId, Constants.OBJ_COMMIT);
467 t.setTag("test022");
468 t.setTagger(new PersonIdent(author, 1154236443000L, -4 * 60));
469 t.setMessage("test022 tagged\n");
470 ObjectId actid = insertTag(t);
471 assertEquals("0ce2ebdb36076ef0b38adbe077a07d43b43e3807", actid.name());
472
473 RevTag mapTag = parseTag(actid);
474 assertEquals(Constants.OBJ_COMMIT, mapTag.getObject().getType());
475 assertEquals("test022 tagged\n", mapTag.getFullMessage());
476 assertEquals(new PersonIdent(author, 1154236443000L, -4 * 60), mapTag
477 .getTaggerIdent());
478 assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag
479 .getObject().getId().name());
480 }
481
482 @Test
483 public void test023_createCommitNonAnullii() throws IOException {
484 final ObjectId emptyId = insertEmptyBlob();
485 TreeFormatter almostEmptyTree = new TreeFormatter();
486 almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
487 final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
488 CommitBuilder commit = new CommitBuilder();
489 commit.setTreeId(almostEmptyTreeId);
490 commit.setAuthor(new PersonIdent("Joe H\u00e4cker", "joe@example.com",
491 4294967295000L, 60));
492 commit.setCommitter(new PersonIdent("Joe Hacker", "joe2@example.com",
493 4294967295000L, 60));
494 commit.setEncoding(UTF_8);
495 commit.setMessage("\u00dcbergeeks");
496 ObjectId cid = insertCommit(commit);
497 assertEquals("4680908112778718f37e686cbebcc912730b3154", cid.name());
498
499 RevCommit loadedCommit = parseCommit(cid);
500 assertEquals(commit.getMessage(), loadedCommit.getFullMessage());
501 }
502
503 @Test
504 public void test024_createCommitNonAscii() throws IOException {
505 final ObjectId emptyId = insertEmptyBlob();
506 TreeFormatter almostEmptyTree = new TreeFormatter();
507 almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
508 final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
509 CommitBuilder commit = new CommitBuilder();
510 commit.setTreeId(almostEmptyTreeId);
511 commit.setAuthor(new PersonIdent("Joe H\u00e4cker", "joe@example.com",
512 4294967295000L, 60));
513 commit.setCommitter(new PersonIdent("Joe Hacker", "joe2@example.com",
514 4294967295000L, 60));
515 commit.setEncoding(ISO_8859_1);
516 commit.setMessage("\u00dcbergeeks");
517 ObjectId cid = insertCommit(commit);
518 assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.name());
519 }
520
521 @Test
522 public void test025_computeSha1NoStore() {
523 byte[] data = "test025 some data, more than 16 bytes to get good coverage"
524 .getBytes(ISO_8859_1);
525 try (ObjectInserter.Formatter formatter = new ObjectInserter.Formatter()) {
526 final ObjectId id = formatter.idFor(Constants.OBJ_BLOB, data);
527 assertEquals("4f561df5ecf0dfbd53a0dc0f37262fef075d9dde", id.name());
528 }
529 }
530
531 @Test
532 public void test026_CreateCommitMultipleparents() throws IOException {
533 final ObjectId treeId;
534 try (ObjectInserter oi = db.newObjectInserter()) {
535 final ObjectId blobId = oi.insert(Constants.OBJ_BLOB,
536 "and this is the data in me\n".getBytes(UTF_8
537 .name()));
538 TreeFormatter fmt = new TreeFormatter();
539 fmt.append("i-am-a-file", FileMode.REGULAR_FILE, blobId);
540 treeId = oi.insert(fmt);
541 oi.flush();
542 }
543 assertEquals(ObjectId
544 .fromString("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"), treeId);
545
546 final CommitBuilder c1 = new CommitBuilder();
547 c1.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
548 c1.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
549 c1.setMessage("A Commit\n");
550 c1.setTreeId(treeId);
551 assertEquals(treeId, c1.getTreeId());
552 ObjectId actid1 = insertCommit(c1);
553 final ObjectId cmtid1 = ObjectId
554 .fromString("803aec4aba175e8ab1d666873c984c0308179099");
555 assertEquals(cmtid1, actid1);
556
557 final CommitBuilder c2 = new CommitBuilder();
558 c2.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
559 c2.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
560 c2.setMessage("A Commit 2\n");
561 c2.setTreeId(treeId);
562 assertEquals(treeId, c2.getTreeId());
563 c2.setParentIds(actid1);
564 ObjectId actid2 = insertCommit(c2);
565 final ObjectId cmtid2 = ObjectId
566 .fromString("95d068687c91c5c044fb8c77c5154d5247901553");
567 assertEquals(cmtid2, actid2);
568
569 RevCommit rm2 = parseCommit(cmtid2);
570 assertNotSame(c2, rm2);
571
572 assertEquals(c2.getAuthor(), rm2.getAuthorIdent());
573 assertEquals(actid2, rm2.getId());
574 assertEquals(c2.getMessage(), rm2.getFullMessage());
575 assertEquals(c2.getTreeId(), rm2.getTree().getId());
576 assertEquals(1, rm2.getParentCount());
577 assertEquals(actid1, rm2.getParent(0));
578
579 final CommitBuilder c3 = new CommitBuilder();
580 c3.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
581 c3.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
582 c3.setMessage("A Commit 3\n");
583 c3.setTreeId(treeId);
584 assertEquals(treeId, c3.getTreeId());
585 c3.setParentIds(actid1, actid2);
586 ObjectId actid3 = insertCommit(c3);
587 final ObjectId cmtid3 = ObjectId
588 .fromString("ce6e1ce48fbeeb15a83f628dc8dc2debefa066f4");
589 assertEquals(cmtid3, actid3);
590
591 RevCommit rm3 = parseCommit(cmtid3);
592 assertNotSame(c3, rm3);
593
594 assertEquals(c3.getAuthor(), rm3.getAuthorIdent());
595 assertEquals(actid3, rm3.getId());
596 assertEquals(c3.getMessage(), rm3.getFullMessage());
597 assertEquals(c3.getTreeId(), rm3.getTree().getId());
598 assertEquals(2, rm3.getParentCount());
599 assertEquals(actid1, rm3.getParent(0));
600 assertEquals(actid2, rm3.getParent(1));
601
602 final CommitBuilder c4 = new CommitBuilder();
603 c4.setAuthor(new PersonIdent(author, 1154236443000L, -4 * 60));
604 c4.setCommitter(new PersonIdent(committer, 1154236443000L, -4 * 60));
605 c4.setMessage("A Commit 4\n");
606 c4.setTreeId(treeId);
607 assertEquals(treeId, c3.getTreeId());
608 c4.setParentIds(actid1, actid2, actid3);
609 ObjectId actid4 = insertCommit(c4);
610 final ObjectId cmtid4 = ObjectId
611 .fromString("d1fca9fe3fef54e5212eb67902c8ed3e79736e27");
612 assertEquals(cmtid4, actid4);
613
614 RevCommit rm4 = parseCommit(cmtid4);
615 assertNotSame(c4, rm3);
616
617 assertEquals(c4.getAuthor(), rm4.getAuthorIdent());
618 assertEquals(actid4, rm4.getId());
619 assertEquals(c4.getMessage(), rm4.getFullMessage());
620 assertEquals(c4.getTreeId(), rm4.getTree().getId());
621 assertEquals(3, rm4.getParentCount());
622 assertEquals(actid1, rm4.getParent(0));
623 assertEquals(actid2, rm4.getParent(1));
624 assertEquals(actid3, rm4.getParent(2));
625 }
626
627 @Test
628 public void test027_UnpackedRefHigherPriorityThanPacked()
629 throws IOException {
630 String unpackedId = "7f822839a2fe9760f386cbbbcb3f92c5fe81def7";
631 write(new File(db.getDirectory(), "refs/heads/a"), unpackedId + "\n");
632
633 ObjectId resolved = db.resolve("refs/heads/a");
634 assertEquals(unpackedId, resolved.name());
635 }
636
637 @Test
638 public void test028_LockPackedRef() throws IOException {
639 ObjectId id1;
640 ObjectId id2;
641 try (ObjectInserter ins = db.newObjectInserter()) {
642 id1 = ins.insert(
643 Constants.OBJ_BLOB, "contents1".getBytes(UTF_8));
644 id2 = ins.insert(
645 Constants.OBJ_BLOB, "contents2".getBytes(UTF_8));
646 ins.flush();
647 }
648
649 writeTrashFile(".git/packed-refs",
650 id1.name() + " refs/heads/foobar");
651 writeTrashFile(".git/HEAD", "ref: refs/heads/foobar\n");
652 BUG_WorkAroundRacyGitIssues("packed-refs");
653 BUG_WorkAroundRacyGitIssues("HEAD");
654
655 ObjectId resolve = db.resolve("HEAD");
656 assertEquals(id1, resolve);
657
658 RefUpdate lockRef = db.updateRef("HEAD");
659 lockRef.setNewObjectId(id2);
660 assertEquals(RefUpdate.Result.FORCED, lockRef.forceUpdate());
661
662 assertTrue(new File(db.getDirectory(), "refs/heads/foobar").exists());
663 assertEquals(id2, db.resolve("refs/heads/foobar"));
664
665
666 RefUpdate lockRef2 = db.updateRef("HEAD");
667 lockRef2.setNewObjectId(id1);
668 assertEquals(RefUpdate.Result.FORCED, lockRef2.forceUpdate());
669
670 assertTrue(new File(db.getDirectory(), "refs/heads/foobar").exists());
671 assertEquals(id1, db.resolve("refs/heads/foobar"));
672 }
673
674 @Test
675 public void test30_stripWorkDir() {
676 File relCwd = new File(".");
677 File absCwd = relCwd.getAbsoluteFile();
678 File absBase = new File(new File(absCwd, "repo"), "workdir");
679 File relBase = new File(new File(relCwd, "repo"), "workdir");
680 assertEquals(absBase.getAbsolutePath(), relBase.getAbsolutePath());
681
682 File relBaseFile = new File(new File(relBase, "other"), "module.c");
683 File absBaseFile = new File(new File(absBase, "other"), "module.c");
684 assertEquals("other/module.c", Repository.stripWorkDir(relBase,
685 relBaseFile));
686 assertEquals("other/module.c", Repository.stripWorkDir(relBase,
687 absBaseFile));
688 assertEquals("other/module.c", Repository.stripWorkDir(absBase,
689 relBaseFile));
690 assertEquals("other/module.c", Repository.stripWorkDir(absBase,
691 absBaseFile));
692
693 File relNonFile = new File(new File(relCwd, "not-repo"), ".gitignore");
694 File absNonFile = new File(new File(absCwd, "not-repo"), ".gitignore");
695 assertEquals("", Repository.stripWorkDir(relBase, relNonFile));
696 assertEquals("", Repository.stripWorkDir(absBase, absNonFile));
697
698 assertEquals("", Repository.stripWorkDir(db.getWorkTree(), db
699 .getWorkTree()));
700
701 File file = new File(new File(db.getWorkTree(), "subdir"), "File.java");
702 assertEquals("subdir/File.java", Repository.stripWorkDir(db
703 .getWorkTree(), file));
704
705 }
706
707 private ObjectId insertEmptyBlob() throws IOException {
708 final ObjectId emptyId;
709 try (ObjectInserter oi = db.newObjectInserter()) {
710 emptyId = oi.insert(Constants.OBJ_BLOB, new byte[] {});
711 oi.flush();
712 }
713 return emptyId;
714 }
715
716 private ObjectId insertTree(TreeFormatter tree) throws IOException {
717 try (ObjectInserter oi = db.newObjectInserter()) {
718 ObjectId id = oi.insert(tree);
719 oi.flush();
720 return id;
721 }
722 }
723
724 private ObjectId insertCommit(CommitBuilder builder)
725 throws IOException, UnsupportedEncodingException {
726 try (ObjectInserter oi = db.newObjectInserter()) {
727 ObjectId id = oi.insert(builder);
728 oi.flush();
729 return id;
730 }
731 }
732
733 private RevCommit parseCommit(AnyObjectId id)
734 throws MissingObjectException, IncorrectObjectTypeException,
735 IOException {
736 try (RevWalk rw = new RevWalk(db)) {
737 return rw.parseCommit(id);
738 }
739 }
740
741 private ObjectId insertTag(TagBuilder tag) throws IOException,
742 UnsupportedEncodingException {
743 try (ObjectInserter oi = db.newObjectInserter()) {
744 ObjectId id = oi.insert(tag);
745 oi.flush();
746 return id;
747 }
748 }
749
750 private RevTag parseTag(AnyObjectId id) throws MissingObjectException,
751 IncorrectObjectTypeException, IOException {
752 try (RevWalk rw = new RevWalk(db)) {
753 return rw.parseTag(id);
754 }
755 }
756
757
758
759
760
761
762
763
764
765
766
767
768
769 private void BUG_WorkAroundRacyGitIssues(String name) throws IOException {
770 File path = new File(db.getDirectory(), name);
771 FS fs = db.getFS();
772 Instant old = fs.lastModifiedInstant(path);
773 long set = 1250379778668L;
774 fs.setLastModified(path.toPath(), Instant.ofEpochMilli(set));
775 assertFalse("time changed", old.equals(fs.lastModifiedInstant(path)));
776 }
777 }