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