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 Lesser General Public
6 * License, version 2.1, 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 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser 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
;
20 import java
.io
.FileInputStream
;
21 import java
.io
.FileReader
;
22 import java
.io
.FileWriter
;
23 import java
.io
.IOException
;
25 import org
.spearce
.jgit
.lib
.Commit
;
26 import org
.spearce
.jgit
.lib
.FileTreeEntry
;
27 import org
.spearce
.jgit
.lib
.ObjectId
;
28 import org
.spearce
.jgit
.lib
.ObjectWriter
;
29 import org
.spearce
.jgit
.lib
.PersonIdent
;
30 import org
.spearce
.jgit
.lib
.Repository
;
31 import org
.spearce
.jgit
.lib
.RepositoryConfig
;
32 import org
.spearce
.jgit
.lib
.Tree
;
33 import org
.spearce
.jgit
.lib
.TreeEntry
;
34 import org
.spearce
.jgit
.lib
.WriteTree
;
35 import org
.spearce
.jgit
.lib
.XInputStream
;
37 public class T0003_Basic
extends RepositoryTestCase
{
38 public void test001_Initalize() {
39 final File gitdir
= new File(trash
, ".git");
40 final File objects
= new File(gitdir
, "objects");
41 final File objects_pack
= new File(objects
, "pack");
42 final File objects_info
= new File(objects
, "info");
43 final File refs
= new File(gitdir
, "refs");
44 final File refs_heads
= new File(refs
, "heads");
45 final File refs_tags
= new File(refs
, "tags");
46 final File HEAD
= new File(gitdir
, "HEAD");
48 assertTrue("Exists " + trash
, trash
.isDirectory());
49 assertTrue("Exists " + objects
, objects
.isDirectory());
50 assertTrue("Exists " + objects_pack
, objects_pack
.isDirectory());
51 assertTrue("Exists " + objects_info
, objects_info
.isDirectory());
52 assertEquals(2, objects
.listFiles().length
);
53 assertTrue("Exists " + refs
, refs
.isDirectory());
54 assertTrue("Exists " + refs_heads
, refs_heads
.isDirectory());
55 assertTrue("Exists " + refs_tags
, refs_tags
.isDirectory());
56 assertTrue("Exists " + HEAD
, HEAD
.isFile());
57 assertEquals(23, HEAD
.length());
60 public void test002_WriteEmptyTree() throws IOException
{
61 // One of our test packs contains the empty tree object. If the pack is
62 // open when we create it we won't write the object file out as a loose
63 // object (as it already exists in the pack).
67 final Tree t
= new Tree(db
);
68 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
69 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", t
.getId()
71 final File o
= new File(new File(new File(trash_git
, "objects"), "4b"),
72 "825dc642cb6eb9a060e54bf8d69288fbee4904");
73 assertTrue("Exists " + o
, o
.isFile());
74 assertTrue("Read-only " + o
, !o
.canWrite());
75 assertEquals(9, o
.length());
78 public void test002_WriteEmptyTree2() throws IOException
{
79 // File shouldn't exist as it is in a test pack.
81 final Tree t
= new Tree(db
);
82 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
83 assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", t
.getId()
85 final File o
= new File(new File(new File(trash_git
, "objects"), "4b"),
86 "825dc642cb6eb9a060e54bf8d69288fbee4904");
87 assertFalse("Exists " + o
, o
.isFile());
90 public void test003_WriteShouldBeEmptyTree() throws IOException
{
91 final Tree t
= new Tree(db
);
92 final ObjectId emptyId
= new ObjectWriter(db
).writeBlob(new byte[0]);
93 t
.addFile("should-be-empty").setId(emptyId
);
94 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
95 assertEquals("7bb943559a305bdd6bdee2cef6e5df2413c3d30a", t
.getId()
99 o
= new File(new File(new File(trash_git
, "objects"), "7b"),
100 "b943559a305bdd6bdee2cef6e5df2413c3d30a");
101 assertTrue("Exists " + o
, o
.isFile());
102 assertTrue("Read-only " + o
, !o
.canWrite());
104 o
= new File(new File(new File(trash_git
, "objects"), "e6"),
105 "9de29bb2d1d6434b8b29ae775ad8c2e48c5391");
106 assertTrue("Exists " + o
, o
.isFile());
107 assertTrue("Read-only " + o
, !o
.canWrite());
110 public void test004_CheckNewConfig() throws IOException
{
111 final RepositoryConfig c
= db
.getConfig();
113 assertEquals("0", c
.getString("core", "repositoryformatversion"));
114 assertEquals("0", c
.getString("CoRe", "REPOSITORYFoRmAtVeRsIoN"));
115 assertEquals("true", c
.getString("core", "filemode"));
116 assertEquals("true", c
.getString("cOrE", "fIlEModE"));
117 assertNull(c
.getString("notavalue", "reallyNotAValue"));
121 public void test005_ReadSimpleConfig() throws IOException
{
122 final RepositoryConfig c
= db
.getConfig();
125 assertEquals("0", c
.getString("core", "repositoryformatversion"));
126 assertEquals("0", c
.getString("CoRe", "REPOSITORYFoRmAtVeRsIoN"));
127 assertEquals("true", c
.getString("core", "filemode"));
128 assertEquals("true", c
.getString("cOrE", "fIlEModE"));
129 assertNull(c
.getString("notavalue", "reallyNotAValue"));
132 public void test006_ReadUglyConfig() throws IOException
{
133 final RepositoryConfig c
= db
.getConfig();
134 final File cfg
= new File(db
.getDirectory(), "config");
135 final FileWriter pw
= new FileWriter(cfg
);
136 final String configStr
= " [core];comment\n\tfilemode = yes\n"
138 + " email = A U Thor <thor@example.com> # Just an example...\n"
139 + " name = \"A Thor \\\\ \\\"\\t \"\n"
140 + " defaultCheckInComment = a many line\\n\\\ncomment\\n\\\n"
145 assertEquals("yes", c
.getString("core", "filemode"));
146 assertEquals("A U Thor <thor@example.com>", c
147 .getString("user", "email"));
148 assertEquals("A Thor \\ \"\t ", c
.getString("user", "name"));
149 assertEquals("a many line\ncomment\n to test", c
.getString("user",
150 "defaultCheckInComment"));
152 final FileReader fr
= new FileReader(cfg
);
153 final char[] cbuf
= new char[configStr
.length()];
156 assertEquals(configStr
, new String(cbuf
));
159 public void test007_Open() throws IOException
{
160 final Repository db2
= new Repository(db
.getDirectory());
161 assertEquals(db
.getDirectory(), db2
.getDirectory());
162 assertEquals(db
.getObjectsDirectory(), db2
.getObjectsDirectory());
163 assertNotSame(db
.getConfig(), db2
.getConfig());
166 public void test008_FailOnWrongVersion() throws IOException
{
167 final File cfg
= new File(db
.getDirectory(), "config");
168 final FileWriter pw
= new FileWriter(cfg
);
169 final String badvers
= "ihopethisisneveraversion";
170 final String configStr
= "[core]\n" + "\trepositoryFormatVersion="
176 new Repository(db
.getDirectory());
177 fail("incorrectly opened a bad repository");
178 } catch (IOException ioe
) {
179 assertTrue(ioe
.getMessage().indexOf("format") > 0);
180 assertTrue(ioe
.getMessage().indexOf(badvers
) > 0);
184 public void test009_CreateCommitOldFormat() throws IOException
{
185 writeTrashFile(".git/config", "[core]\n" + "legacyHeaders=1\n");
186 db
.getConfig().load();
188 final Tree t
= new Tree(db
);
189 final FileTreeEntry f
= t
.addFile("i-am-a-file");
190 writeTrashFile(f
.getName(), "and this is the data in me\n");
191 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
192 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
195 final Commit c
= new Commit(db
);
196 c
.setAuthor(new PersonIdent(jauthor
, 1154236443000L, -4 * 60));
197 c
.setCommitter(new PersonIdent(jcommitter
, 1154236443000L, -4 * 60));
198 c
.setMessage("A Commit\n");
200 assertEquals(t
.getTreeId(), c
.getTreeId());
202 final ObjectId cmtid
= new ObjectId(
203 "803aec4aba175e8ab1d666873c984c0308179099");
204 assertEquals(cmtid
, c
.getCommitId());
206 // Verify the commit we just wrote is in the correct format.
207 final XInputStream xis
= new XInputStream(new FileInputStream(db
210 assertEquals(0x78, xis
.readUInt8());
211 assertEquals(0x9c, xis
.readUInt8());
212 assertTrue(0x789c % 31 == 0);
217 // Verify we can read it.
218 final Commit c2
= db
.mapCommit(cmtid
);
220 assertEquals(c
.getMessage(), c2
.getMessage());
221 assertEquals(c
.getTreeId(), c2
.getTreeId());
222 assertEquals(c
.getAuthor(), c2
.getAuthor());
223 assertEquals(c
.getCommitter(), c2
.getCommitter());
226 public void test010_CreateCommitNewFormat() throws IOException
{
227 writeTrashFile(".git/config", "[core]\n" + "legacyHeaders=0\n");
228 db
.getConfig().load();
230 final Tree t
= new Tree(db
);
231 final FileTreeEntry f
= t
.addFile("i-am-a-file");
232 writeTrashFile(f
.getName(), "and this is the data in me\n");
233 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
234 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
237 final Commit c
= new Commit(db
);
238 c
.setAuthor(new PersonIdent(jauthor
, 1154236443000L, -4 * 60));
239 c
.setCommitter(new PersonIdent(jcommitter
, 1154236443000L, -4 * 60));
240 c
.setMessage("A Commit\n");
242 assertEquals(t
.getTreeId(), c
.getTreeId());
244 final ObjectId cmtid
= new ObjectId(
245 "803aec4aba175e8ab1d666873c984c0308179099");
246 assertEquals(cmtid
, c
.getCommitId());
248 // Verify the commit we just wrote is in the correct format.
249 final XInputStream xis
= new XInputStream(new FileInputStream(db
252 // 'pack style' commit header: 177 bytes
253 assertEquals(0x91, xis
.readUInt8());
254 assertEquals(0x0b, xis
.readUInt8());
256 assertEquals(0x78, xis
.readUInt8());
257 assertTrue(((0x78 << 8) | xis
.readUInt8()) % 31 == 0);
262 // Verify we can read it.
263 final Commit c2
= db
.mapCommit(cmtid
);
265 assertEquals(c
.getMessage(), c2
.getMessage());
266 assertEquals(c
.getTreeId(), c2
.getTreeId());
267 assertEquals(c
.getAuthor(), c2
.getAuthor());
268 assertEquals(c
.getCommitter(), c2
.getCommitter());
271 public void test011_CreateCommitNewFormatIsDefault() throws IOException
{
272 db
.getConfig().load();
274 final Tree t
= new Tree(db
);
275 final FileTreeEntry f
= t
.addFile("i-am-a-file");
276 writeTrashFile(f
.getName(), "and this is the data in me\n");
277 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
278 assertEquals(new ObjectId("00b1f73724f493096d1ffa0b0f1f1482dbb8c936"),
281 final Commit c
= new Commit(db
);
282 c
.setAuthor(new PersonIdent(jauthor
, 1154236443000L, -4 * 60));
283 c
.setCommitter(new PersonIdent(jcommitter
, 1154236443000L, -4 * 60));
284 c
.setMessage("A Commit\n");
286 assertEquals(t
.getTreeId(), c
.getTreeId());
288 final ObjectId cmtid
= new ObjectId(
289 "803aec4aba175e8ab1d666873c984c0308179099");
290 assertEquals(cmtid
, c
.getCommitId());
292 // Verify the commit we just wrote is in the correct format.
293 final XInputStream xis
= new XInputStream(new FileInputStream(db
296 // 'pack style' commit header: 177 bytes
297 assertEquals(0x91, xis
.readUInt8());
298 assertEquals(0x0b, xis
.readUInt8());
300 assertEquals(0x78, xis
.readUInt8());
301 assertTrue(((0x78 << 8) | xis
.readUInt8()) % 31 == 0);
306 // Verify we can read it.
307 final Commit c2
= db
.mapCommit(cmtid
);
309 assertEquals(c
.getMessage(), c2
.getMessage());
310 assertEquals(c
.getTreeId(), c2
.getTreeId());
311 assertEquals(c
.getAuthor(), c2
.getAuthor());
312 assertEquals(c
.getCommitter(), c2
.getCommitter());
315 public void test012_SubtreeExternalSorting() throws IOException
{
316 final ObjectId emptyBlob
= new ObjectWriter(db
).writeBlob(new byte[0]);
317 final Tree t
= new Tree(db
);
318 final FileTreeEntry e0
= t
.addFile("a-");
319 final FileTreeEntry e1
= t
.addFile("a-b");
320 final FileTreeEntry e2
= t
.addFile("a/b");
321 final FileTreeEntry e3
= t
.addFile("a=");
322 final FileTreeEntry e4
= t
.addFile("a=b");
330 t
.accept(new WriteTree(trash
, db
), TreeEntry
.MODIFIED_ONLY
);
331 assertEquals(new ObjectId("b47a8f0a4190f7572e11212769090523e23eb1ea"),