2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org
.spearce
.jgit
.lib
;
41 import java
.nio
.charset
.Charset
;
42 import java
.security
.MessageDigest
;
43 import java
.security
.NoSuchAlgorithmException
;
45 import org
.spearce
.jgit
.errors
.CorruptObjectException
;
46 import org
.spearce
.jgit
.util
.MutableInteger
;
48 /** Misc. constants used throughout JGit. */
49 public final class Constants
{
50 /** Hash function used natively by Git for all objects. */
51 private static final String HASH_FUNCTION
= "SHA-1";
53 /** Length of an object hash. */
54 public static final int OBJECT_ID_LENGTH
= 20;
56 /** Special name for the "HEAD" symbolic-ref. */
57 public static final String HEAD
= "HEAD";
60 * Text string that identifies an object as a commit.
62 * Commits connect trees into a string of project histories, where each
63 * commit is an assertion that the best way to continue is to use this other
64 * tree (set of files).
66 public static final String TYPE_COMMIT
= "commit";
69 * Text string that identifies an object as a blob.
71 * Blobs store whole file revisions. They are used for any user file, as
72 * well as for symlinks. Blobs form the bulk of any project's storage space.
74 public static final String TYPE_BLOB
= "blob";
77 * Text string that identifies an object as a tree.
79 * Trees attach object ids (hashes) to names and file modes. The normal use
80 * for a tree is to store a version of a directory and its contents.
82 public static final String TYPE_TREE
= "tree";
85 * Text string that identifies an object as an annotated tag.
87 * Annotated tags store a pointer to any other object, and an additional
88 * message. It is most commonly used to record a stable release of the
91 public static final String TYPE_TAG
= "tag";
93 private static final byte[] ENCODED_TYPE_COMMIT
= encodeASCII(TYPE_COMMIT
);
95 private static final byte[] ENCODED_TYPE_BLOB
= encodeASCII(TYPE_BLOB
);
97 private static final byte[] ENCODED_TYPE_TREE
= encodeASCII(TYPE_TREE
);
99 private static final byte[] ENCODED_TYPE_TAG
= encodeASCII(TYPE_TAG
);
101 /** An unknown or invalid object type code. */
102 public static final int OBJ_BAD
= -1;
105 * In-pack object type: extended types.
107 * This header code is reserved for future expansion. It is currently
108 * undefined/unsupported.
110 public static final int OBJ_EXT
= 0;
113 * In-pack object type: commit.
115 * Indicates the associated object is a commit.
117 * <b>This constant is fixed and is defined by the Git packfile format.</b>
121 public static final int OBJ_COMMIT
= 1;
124 * In-pack object type: tree.
126 * Indicates the associated object is a tree.
128 * <b>This constant is fixed and is defined by the Git packfile format.</b>
132 public static final int OBJ_TREE
= 2;
135 * In-pack object type: blob.
137 * Indicates the associated object is a blob.
139 * <b>This constant is fixed and is defined by the Git packfile format.</b>
143 public static final int OBJ_BLOB
= 3;
146 * In-pack object type: annotated tag.
148 * Indicates the associated object is an annotated tag.
150 * <b>This constant is fixed and is defined by the Git packfile format.</b>
154 public static final int OBJ_TAG
= 4;
156 /** In-pack object type: reserved for future use. */
157 public static final int OBJ_TYPE_5
= 5;
160 * In-pack object type: offset delta
162 * Objects stored with this type actually have a different type which must
163 * be obtained from their delta base object. Delta objects store only the
164 * changes needed to apply to the base object in order to recover the
167 * An offset delta uses a negative offset from the start of this object to
168 * refer to its delta base. The base object must exist in this packfile
169 * (even in the case of a thin pack).
171 * <b>This constant is fixed and is defined by the Git packfile format.</b>
173 public static final int OBJ_OFS_DELTA
= 6;
176 * In-pack object type: reference delta
178 * Objects stored with this type actually have a different type which must
179 * be obtained from their delta base object. Delta objects store only the
180 * changes needed to apply to the base object in order to recover the
183 * A reference delta uses a full object id (hash) to reference the delta
184 * base. The base object is allowed to be omitted from the packfile, but
185 * only in the case of a thin pack being transferred over the network.
187 * <b>This constant is fixed and is defined by the Git packfile format.</b>
189 public static final int OBJ_REF_DELTA
= 7;
191 /** Native character encoding for commit messages, file names... */
192 public static final String CHARACTER_ENCODING
= "UTF-8";
194 /** Native character encoding for commit messages, file names... */
195 public static final Charset CHARSET
;
197 /** Default main branch name */
198 public static final String MASTER
= "master";
200 /** Prefix for branch refs */
201 public static final String HEADS_PREFIX
= "refs/heads";
203 /** Prefix for remotes refs */
204 public static final String REMOTES_PREFIX
= "refs/remotes";
206 /** Prefix for tag refs */
207 public static final String TAGS_PREFIX
= "refs/tags";
210 * Create a new digest function for objects.
212 * @return a new digest object.
213 * @throws RuntimeException
214 * this Java virtual machine does not support the required hash
215 * function. Very unlikely given that JGit uses a hash function
216 * that is in the Java reference specification.
218 public static MessageDigest
newMessageDigest() {
220 return MessageDigest
.getInstance(HASH_FUNCTION
);
221 } catch (NoSuchAlgorithmException nsae
) {
222 throw new RuntimeException("Required hash function "
223 + HASH_FUNCTION
+ " not available.", nsae
);
228 * Convert an OBJ_* type constant to a TYPE_* type constant.
230 * @param typeCode the type code, from a pack representation.
231 * @return the canonical string name of this type.
233 public static String
typeString(final int typeCode
) {
244 throw new IllegalArgumentException("Bad object type: " + typeCode
);
249 * Convert an OBJ_* type constant to an ASCII encoded string constant.
251 * The ASCII encoded string is often the canonical representation of
252 * the type within a loose object header, or within a tag header.
254 * @param typeCode the type code, from a pack representation.
255 * @return the canonical ASCII encoded name of this type.
257 public static byte[] encodedTypeString(final int typeCode
) {
260 return ENCODED_TYPE_COMMIT
;
262 return ENCODED_TYPE_TREE
;
264 return ENCODED_TYPE_BLOB
;
266 return ENCODED_TYPE_TAG
;
268 throw new IllegalArgumentException("Bad object type: " + typeCode
);
273 * Parse an encoded type string into a type constant.
276 * object id this type string came from; may be null if that is
277 * not known at the time the parse is occurring.
279 * string version of the type code.
281 * character immediately following the type string. Usually ' '
282 * (space) or '\n' (line feed).
284 * position within <code>typeString</code> where the parse
285 * should start. Updated with the new position (just past
286 * <code>endMark</code> when the parse is successful.
287 * @return a type code constant (one of {@link #OBJ_BLOB},
288 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}.
289 * @throws CorruptObjectException
290 * there is no valid type identified by <code>typeString</code>.
292 public static int decodeTypeString(final ObjectId id
,
293 final byte[] typeString
, final byte endMark
,
294 final MutableInteger offset
) throws CorruptObjectException
{
296 int position
= offset
.value
;
297 switch (typeString
[position
]) {
299 if (typeString
[position
+ 1] != 'l'
300 || typeString
[position
+ 2] != 'o'
301 || typeString
[position
+ 3] != 'b'
302 || typeString
[position
+ 4] != endMark
)
303 throw new CorruptObjectException(id
, "invalid type");
304 offset
.value
= position
+ 5;
305 return Constants
.OBJ_BLOB
;
308 if (typeString
[position
+ 1] != 'o'
309 || typeString
[position
+ 2] != 'm'
310 || typeString
[position
+ 3] != 'm'
311 || typeString
[position
+ 4] != 'i'
312 || typeString
[position
+ 5] != 't'
313 || typeString
[position
+ 6] != endMark
)
314 throw new CorruptObjectException(id
, "invalid type");
315 offset
.value
= position
+ 7;
316 return Constants
.OBJ_COMMIT
;
319 switch (typeString
[position
+ 1]) {
321 if (typeString
[position
+ 2] != 'g'
322 || typeString
[position
+ 3] != endMark
)
323 throw new CorruptObjectException(id
, "invalid type");
324 offset
.value
= position
+ 4;
325 return Constants
.OBJ_TAG
;
328 if (typeString
[position
+ 2] != 'e'
329 || typeString
[position
+ 3] != 'e'
330 || typeString
[position
+ 4] != endMark
)
331 throw new CorruptObjectException(id
, "invalid type");
332 offset
.value
= position
+ 5;
333 return Constants
.OBJ_TREE
;
336 throw new CorruptObjectException(id
, "invalid type");
340 throw new CorruptObjectException(id
, "invalid type");
342 } catch (ArrayIndexOutOfBoundsException bad
) {
343 throw new CorruptObjectException(id
, "invalid type");
348 * Convert an integer into its decimal representation.
351 * the integer to convert.
352 * @return a decimal representation of the input integer. The returned array
353 * is the smallest array that will hold the value.
355 public static byte[] encodeASCII(final long s
) {
356 return encodeASCII(Long
.toString(s
));
360 * Convert a string to US-ASCII encoding.
363 * the string to convert. Must not contain any characters over
364 * 127 (outside of 7-bit ASCII).
365 * @return a byte array of the same length as the input string, holding the
366 * same characters, in the same order.
367 * @throws IllegalArgumentException
368 * the input string contains one or more characters outside of
369 * the 7-bit ASCII character space.
371 public static byte[] encodeASCII(final String s
) {
372 final byte[] r
= new byte[s
.length()];
373 for (int k
= r
.length
- 1; k
>= 0; k
--) {
374 final char c
= s
.charAt(k
);
376 throw new IllegalArgumentException("Not ASCII string: " + s
);
383 if (OBJECT_ID_LENGTH
!= newMessageDigest().getDigestLength())
384 throw new LinkageError("Incorrect OBJECT_ID_LENGTH.");
385 CHARSET
= Charset
.forName(CHARACTER_ENCODING
);
388 private Constants() {
389 // Hide the default constructor