Refactor SHA1 computation
[egit.git] / org.spearce.jgit / tst / org / spearce / jgit / lib / T0003_Basic.java
blobb3bcf1cd1844f6e8316bb9ca7505bc7e40590d84
1 /*
2 * Copyright (C) 2006 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org.spearce.jgit.lib;
19 import java.io.ByteArrayInputStream;
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileReader;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.io.PrintWriter;
27 public class T0003_Basic extends RepositoryTestCase {
28 public void test001_Initalize() {
29 final File gitdir = new File(trash, ".git");
30 final File objects = new File(gitdir, "objects");
31 final File objects_pack = new File(objects, "pack");
32 final File objects_info = new File(objects, "info");
33 final File refs = new File(gitdir, "refs");
34 final File refs_heads = new File(refs, "heads");
35 final File refs_tags = new File(refs, "tags");
36 final File HEAD = new File(gitdir, "HEAD");
38 assertTrue("Exists " + trash, trash.isDirectory());
39 assertTrue("Exists " + objects, objects.isDirectory());
40 assertTrue("Exists " + objects_pack, objects_pack.isDirectory());
41 assertTrue("Exists " + objects_info, objects_info.isDirectory());
42 assertEquals(2, objects.listFiles().length);
43 assertTrue("Exists " + refs, refs.isDirectory());
44 assertTrue("Exists " + refs_heads, refs_heads.isDirectory());
45 assertTrue("Exists " + refs_tags, refs_tags.isDirectory());
46 assertTrue("Exists " + HEAD, HEAD.isFile());
47 assertEquals(23, HEAD.length());
50 public void test002_WriteEmptyTree() throws IOException {
51 // One of our test packs contains the empty tree object. If the pack is
52 // open when we create it we won't write the object file out as a loose
53 // object (as it already exists in the pack).
55 db.closePacks();
57 final Tree t = new Tree(db);
58 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
59 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", t.getId()
60 .toString());
61 final File o = new File(new File(new File(trash_git, "objects"), "4b"),
62 "825dc642cb6eb9a060e54bf8d69288fbee4904");
63 assertTrue("Exists " + o, o.isFile());
64 assertTrue("Read-only " + o, !o.canWrite());
65 assertEquals(9, o.length());
68 public void test002_WriteEmptyTree2() throws IOException {
69 // File shouldn't exist as it is in a test pack.
71 final Tree t = new Tree(db);
72 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
73 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", t.getId()
74 .toString());
75 final File o = new File(new File(new File(trash_git, "objects"), "4b"),
76 "825dc642cb6eb9a060e54bf8d69288fbee4904");
77 assertFalse("Exists " + o, o.isFile());
80 public void test003_WriteShouldBeEmptyTree() throws IOException {
81 final Tree t = new Tree(db);
82 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
83 t.addFile("should-be-empty").setId(emptyId);
84 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
85 assertEquals("7bb943559a305bdd6bdee2cef6e5df2413c3d30a", t.getId()
86 .toString());
88 File o;
89 o = new File(new File(new File(trash_git, "objects"), "7b"),
90 "b943559a305bdd6bdee2cef6e5df2413c3d30a");
91 assertTrue("Exists " + o, o.isFile());
92 assertTrue("Read-only " + o, !o.canWrite());
94 o = new File(new File(new File(trash_git, "objects"), "e6"),
95 "9de29bb2d1d6434b8b29ae775ad8c2e48c5391");
96 assertTrue("Exists " + o, o.isFile());
97 assertTrue("Read-only " + o, !o.canWrite());
100 public void test004_CheckNewConfig() throws IOException {
101 final RepositoryConfig c = db.getConfig();
102 assertNotNull(c);
103 assertEquals("0", c.getString("core", "repositoryformatversion"));
104 assertEquals("0", c.getString("CoRe", "REPOSITORYFoRmAtVeRsIoN"));
105 assertEquals("true", c.getString("core", "filemode"));
106 assertEquals("true", c.getString("cOrE", "fIlEModE"));
107 assertNull(c.getString("notavalue", "reallyNotAValue"));
108 c.load();
111 public void test005_ReadSimpleConfig() throws IOException {
112 final RepositoryConfig c = db.getConfig();
113 assertNotNull(c);
114 c.load();
115 assertEquals("0", c.getString("core", "repositoryformatversion"));
116 assertEquals("0", c.getString("CoRe", "REPOSITORYFoRmAtVeRsIoN"));
117 assertEquals("true", c.getString("core", "filemode"));
118 assertEquals("true", c.getString("cOrE", "fIlEModE"));
119 assertNull(c.getString("notavalue", "reallyNotAValue"));
122 public void test006_ReadUglyConfig() throws IOException {
123 final RepositoryConfig c = db.getConfig();
124 final File cfg = new File(db.getDirectory(), "config");
125 final FileWriter pw = new FileWriter(cfg);
126 final String configStr = " [core];comment\n\tfilemode = yes\n"
127 + "[user]\n"
128 + " email = A U Thor <thor@example.com> # Just an example...\n"
129 + " name = \"A Thor \\\\ \\\"\\t \"\n"
130 + " defaultCheckInComment = a many line\\n\\\ncomment\\n\\\n"
131 + " to test\n";
132 pw.write(configStr);
133 pw.close();
134 c.load();
135 assertEquals("yes", c.getString("core", "filemode"));
136 assertEquals("A U Thor <thor@example.com>", c
137 .getString("user", "email"));
138 assertEquals("A Thor \\ \"\t ", c.getString("user", "name"));
139 assertEquals("a many line\ncomment\n to test", c.getString("user",
140 "defaultCheckInComment"));
141 c.save();
142 final FileReader fr = new FileReader(cfg);
143 final char[] cbuf = new char[configStr.length()];
144 fr.read(cbuf);
145 fr.close();
146 assertEquals(configStr, new String(cbuf));
149 public void test007_Open() throws IOException {
150 final Repository db2 = new Repository(db.getDirectory());
151 assertEquals(db.getDirectory(), db2.getDirectory());
152 assertEquals(db.getObjectsDirectory(), db2.getObjectsDirectory());
153 assertNotSame(db.getConfig(), db2.getConfig());
156 public void test008_FailOnWrongVersion() throws IOException {
157 final File cfg = new File(db.getDirectory(), "config");
158 final FileWriter pw = new FileWriter(cfg);
159 final String badvers = "ihopethisisneveraversion";
160 final String configStr = "[core]\n" + "\trepositoryFormatVersion="
161 + badvers + "\n";
162 pw.write(configStr);
163 pw.close();
165 try {
166 new Repository(db.getDirectory());
167 fail("incorrectly opened a bad repository");
168 } catch (IOException ioe) {
169 assertTrue(ioe.getMessage().indexOf("format") > 0);
170 assertTrue(ioe.getMessage().indexOf(badvers) > 0);
174 public void test009_CreateCommitOldFormat() throws IOException {
175 writeTrashFile(".git/config", "[core]\n" + "legacyHeaders=1\n");
176 db.getConfig().load();
178 final Tree t = new Tree(db);
179 final FileTreeEntry f = t.addFile("i-am-a-file");
180 writeTrashFile(f.getName(), "and this is the data in me\n");
181 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
182 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
183 t.getTreeId());
185 final Commit c = new Commit(db);
186 c.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
187 c.setCommitter(new PersonIdent(jcommitter, 1154236443000L, -4 * 60));
188 c.setMessage("A Commit\n");
189 c.setTree(t);
190 assertEquals(t.getTreeId(), c.getTreeId());
191 c.commit();
192 final ObjectId cmtid = new ObjectId(
193 "803aec4aba175e8ab1d666873c984c0308179099");
194 assertEquals(cmtid, c.getCommitId());
196 // Verify the commit we just wrote is in the correct format.
197 final XInputStream xis = new XInputStream(new FileInputStream(db
198 .toFile(cmtid)));
199 try {
200 assertEquals(0x78, xis.readUInt8());
201 assertEquals(0x9c, xis.readUInt8());
202 assertTrue(0x789c % 31 == 0);
203 } finally {
204 xis.close();
207 // Verify we can read it.
208 final Commit c2 = db.mapCommit(cmtid);
209 assertNotNull(c2);
210 assertEquals(c.getMessage(), c2.getMessage());
211 assertEquals(c.getTreeId(), c2.getTreeId());
212 assertEquals(c.getAuthor(), c2.getAuthor());
213 assertEquals(c.getCommitter(), c2.getCommitter());
216 public void test010_CreateCommitNewFormat() throws IOException {
217 writeTrashFile(".git/config", "[core]\n" + "legacyHeaders=0\n");
218 db.getConfig().load();
220 final Tree t = new Tree(db);
221 final FileTreeEntry f = t.addFile("i-am-a-file");
222 writeTrashFile(f.getName(), "and this is the data in me\n");
223 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
224 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
225 t.getTreeId());
227 final Commit c = new Commit(db);
228 c.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
229 c.setCommitter(new PersonIdent(jcommitter, 1154236443000L, -4 * 60));
230 c.setMessage("A Commit\n");
231 c.setTree(t);
232 assertEquals(t.getTreeId(), c.getTreeId());
233 c.commit();
234 final ObjectId cmtid = new ObjectId(
235 "803aec4aba175e8ab1d666873c984c0308179099");
236 assertEquals(cmtid, c.getCommitId());
238 // Verify the commit we just wrote is in the correct format.
239 final XInputStream xis = new XInputStream(new FileInputStream(db
240 .toFile(cmtid)));
241 try {
242 // 'pack style' commit header: 177 bytes
243 assertEquals(0x91, xis.readUInt8());
244 assertEquals(0x0b, xis.readUInt8());
245 // zlib stream start
246 assertEquals(0x78, xis.readUInt8());
247 assertTrue(((0x78 << 8) | xis.readUInt8()) % 31 == 0);
248 } finally {
249 xis.close();
252 // Verify we can read it.
253 final Commit c2 = db.mapCommit(cmtid);
254 assertNotNull(c2);
255 assertEquals(c.getMessage(), c2.getMessage());
256 assertEquals(c.getTreeId(), c2.getTreeId());
257 assertEquals(c.getAuthor(), c2.getAuthor());
258 assertEquals(c.getCommitter(), c2.getCommitter());
261 public void test011_CreateCommitNewFormatIsDefault() throws IOException {
262 db.getConfig().load();
264 final Tree t = new Tree(db);
265 final FileTreeEntry f = t.addFile("i-am-a-file");
266 writeTrashFile(f.getName(), "and this is the data in me\n");
267 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
268 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
269 t.getTreeId());
271 final Commit c = new Commit(db);
272 c.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
273 c.setCommitter(new PersonIdent(jcommitter, 1154236443000L, -4 * 60));
274 c.setMessage("A Commit\n");
275 c.setTree(t);
276 assertEquals(t.getTreeId(), c.getTreeId());
277 c.commit();
278 final ObjectId cmtid = new ObjectId(
279 "803aec4aba175e8ab1d666873c984c0308179099");
280 assertEquals(cmtid, c.getCommitId());
282 // Verify the commit we just wrote is in the correct format.
283 final XInputStream xis = new XInputStream(new FileInputStream(db
284 .toFile(cmtid)));
285 try {
286 // 'pack style' commit header: 177 bytes
287 assertEquals(0x91, xis.readUInt8());
288 assertEquals(0x0b, xis.readUInt8());
289 // zlib stream start
290 assertEquals(0x78, xis.readUInt8());
291 assertTrue(((0x78 << 8) | xis.readUInt8()) % 31 == 0);
292 } finally {
293 xis.close();
296 // Verify we can read it.
297 final Commit c2 = db.mapCommit(cmtid);
298 assertNotNull(c2);
299 assertEquals(c.getMessage(), c2.getMessage());
300 assertEquals(c.getTreeId(), c2.getTreeId());
301 assertEquals(c.getAuthor(), c2.getAuthor());
302 assertEquals(c.getCommitter(), c2.getCommitter());
305 public void test012_SubtreeExternalSorting() throws IOException {
306 final ObjectId emptyBlob = new ObjectWriter(db).writeBlob(new byte[0]);
307 final Tree t = new Tree(db);
308 final FileTreeEntry e0 = t.addFile("a-");
309 final FileTreeEntry e1 = t.addFile("a-b");
310 final FileTreeEntry e2 = t.addFile("a/b");
311 final FileTreeEntry e3 = t.addFile("a=");
312 final FileTreeEntry e4 = t.addFile("a=b");
314 e0.setId(emptyBlob);
315 e1.setId(emptyBlob);
316 e2.setId(emptyBlob);
317 e3.setId(emptyBlob);
318 e4.setId(emptyBlob);
320 t.accept(new WriteTree(trash, db), TreeEntry.MODIFIED_ONLY);
321 assertEquals(new ObjectId("b47a8f0a4190f7572e11212769090523e23eb1ea"),
322 t.getId());
325 public void test020_createBlobTag() throws IOException {
326 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
327 final Tag t = new Tag(db);
328 t.setObjId(emptyId);
329 t.setType("blob");
330 t.setTag("test020");
331 t.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
332 t.setMessage("test020 tagged\n");
333 t.tag();
334 assertEquals("6759556b09fbb4fd8ae5e315134481cc25d46954", t.getTagId().toString());
336 Tag mapTag = db.mapTag("test020");
337 assertEquals("blob", mapTag.getType());
338 assertEquals("test020 tagged\n", mapTag.getMessage());
339 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());
340 assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag.getObjId().toString());
343 public void test020b_createBlobPlainTag() throws IOException {
344 test020_createBlobTag();
345 Tag t = new Tag(db);
346 t.setTag("test020b");
347 t.setObjId(new ObjectId("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"));
348 t.tag();
350 Tag mapTag = db.mapTag("test020b");
351 assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag.getObjId().toString());
353 // We do not repeat the plain tag test for other object types
356 public void test021_createTreeTag() throws IOException {
357 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
358 final Tree almostEmptyTree = new Tree(db);
359 almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
360 final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
361 final Tag t = new Tag(db);
362 t.setObjId(almostEmptyTreeId);
363 t.setType("tree");
364 t.setTag("test021");
365 t.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
366 t.setMessage("test021 tagged\n");
367 t.tag();
368 assertEquals("b0517bc8dbe2096b419d42424cd7030733f4abe5", t.getTagId().toString());
370 Tag mapTag = db.mapTag("test021");
371 assertEquals("tree", mapTag.getType());
372 assertEquals("test021 tagged\n", mapTag.getMessage());
373 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());
374 assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag.getObjId().toString());
377 public void test022_createCommitTag() throws IOException {
378 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
379 final Tree almostEmptyTree = new Tree(db);
380 almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
381 final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
382 final Commit almostEmptyCommit = new Commit(db);
383 almostEmptyCommit.setAuthor(new PersonIdent(jauthor, 1154236443000L, -2 * 60)); // not exactly the same
384 almostEmptyCommit.setCommitter(new PersonIdent(jauthor, 1154236443000L, -2 * 60));
385 almostEmptyCommit.setMessage("test022\n");
386 almostEmptyCommit.setTreeId(almostEmptyTreeId);
387 ObjectId almostEmptyCommitId = new ObjectWriter(db).writeCommit(almostEmptyCommit);
388 final Tag t = new Tag(db);
389 t.setObjId(almostEmptyCommitId);
390 t.setType("commit");
391 t.setTag("test022");
392 t.setAuthor(new PersonIdent(jauthor, 1154236443000L, -4 * 60));
393 t.setMessage("test022 tagged\n");
394 t.tag();
395 assertEquals("0ce2ebdb36076ef0b38adbe077a07d43b43e3807", t.getTagId().toString());
397 Tag mapTag = db.mapTag("test022");
398 assertEquals("commit", mapTag.getType());
399 assertEquals("test022 tagged\n", mapTag.getMessage());
400 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag.getAuthor());
401 assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag.getObjId().toString());
404 public void test023_createCommitNonAscii() throws IOException {
405 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
406 final Tree almostEmptyTree = new Tree(db);
407 almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
408 final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
409 Commit commit = new Commit(db);
410 commit.setTreeId(almostEmptyTreeId);
411 commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60));
412 commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60));
413 commit.setEncoding("UTF-8");
414 commit.setMessage("\u00dcbergeeks");
415 ObjectId cid = new ObjectWriter(db).writeCommit(commit);
416 assertEquals("4680908112778718f37e686cbebcc912730b3154", cid.toString());
419 public void test024_createCommitNonAscii() throws IOException {
420 final ObjectId emptyId = new ObjectWriter(db).writeBlob(new byte[0]);
421 final Tree almostEmptyTree = new Tree(db);
422 almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId, "empty".getBytes(), false));
423 final ObjectId almostEmptyTreeId = new ObjectWriter(db).writeTree(almostEmptyTree);
424 Commit commit = new Commit(db);
425 commit.setTreeId(almostEmptyTreeId);
426 commit.setAuthor(new PersonIdent("Joe H\u00e4cker","joe@example.com",4294967295000L,60));
427 commit.setCommitter(new PersonIdent("Joe Hacker","joe2@example.com",4294967295000L,60));
428 commit.setEncoding("ISO-8859-1");
429 commit.setMessage("\u00dcbergeeks");
430 ObjectId cid = new ObjectWriter(db).writeCommit(commit);
431 assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.toString());
434 public void test025_packedRefs() throws IOException {
435 test020_createBlobTag();
436 test021_createTreeTag();
437 test022_createCommitTag();
439 if (!new File(db.getDirectory(),"refs/tags/test020").delete()) throw new Error("Cannot delete unpacked tag");
440 if (!new File(db.getDirectory(),"refs/tags/test021").delete()) throw new Error("Cannot delete unpacked tag");
441 if (!new File(db.getDirectory(),"refs/tags/test022").delete()) throw new Error("Cannot delete unpacked tag");
443 // We cannot resolve it now, since we have no ref
444 Tag mapTag20missing = db.mapTag("test020");
445 assertNull(mapTag20missing);
447 // Construct packed refs file
448 PrintWriter w = new PrintWriter(new FileWriter(new File(db.getDirectory(), "packed-refs")));
449 w.println("# packed-refs with: peeled");
450 w.println("6759556b09fbb4fd8ae5e315134481cc25d46954 refs/tags/test020");
451 w.println("^e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
452 w.println("b0517bc8dbe2096b419d42424cd7030733f4abe5 refs/tags/test021");
453 w.println("^417c01c8795a35b8e835113a85a5c0c1c77f67fb");
454 w.println("0ce2ebdb36076ef0b38adbe077a07d43b43e3807 refs/tags/test022");
455 w.println("^b5d3b45a96b340441f5abb9080411705c51cc86c");
456 w.close();
458 Tag mapTag20 = db.mapTag("test020");
459 assertEquals("blob", mapTag20.getType());
460 assertEquals("test020 tagged\n", mapTag20.getMessage());
461 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag20.getAuthor());
462 assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag20.getObjId().toString());
464 Tag mapTag21 = db.mapTag("test021");
465 assertEquals("tree", mapTag21.getType());
466 assertEquals("test021 tagged\n", mapTag21.getMessage());
467 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag21.getAuthor());
468 assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag21.getObjId().toString());
470 Tag mapTag22 = db.mapTag("test022");
471 assertEquals("commit", mapTag22.getType());
472 assertEquals("test022 tagged\n", mapTag22.getMessage());
473 assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag22.getAuthor());
474 assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag22.getObjId().toString());
477 public void test025_computeSha1NoStore() throws IOException {
478 byte[] data = "test025 some data, more than 16 bytes to get good coverage"
479 .getBytes("ISO-8859-1");
480 // TODO: but we do not test legacy header writing
481 final ObjectId id = new ObjectWriter(db).computeBlobSha1(data.length,
482 new ByteArrayInputStream(data));
483 assertEquals("4f561df5ecf0dfbd53a0dc0f37262fef075d9dde", id.toString());