2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Google Inc.
8 * Redistribution and use in source and binary forms, with or
9 * without modification, are permitted provided that the following
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
20 * - Neither the name of the Git Development Community nor the
21 * names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 package org
.spearce
.jgit
.lib
;
42 import java
.nio
.ByteBuffer
;
43 import java
.nio
.charset
.Charset
;
44 import java
.security
.MessageDigest
;
45 import java
.security
.NoSuchAlgorithmException
;
47 import org
.spearce
.jgit
.errors
.CorruptObjectException
;
48 import org
.spearce
.jgit
.util
.MutableInteger
;
50 /** Misc. constants used throughout JGit. */
51 public final class Constants
{
52 /** Hash function used natively by Git for all objects. */
53 private static final String HASH_FUNCTION
= "SHA-1";
55 /** Length of an object hash. */
56 public static final int OBJECT_ID_LENGTH
= 20;
58 /** Special name for the "HEAD" symbolic-ref. */
59 public static final String HEAD
= "HEAD";
62 * Text string that identifies an object as a commit.
64 * Commits connect trees into a string of project histories, where each
65 * commit is an assertion that the best way to continue is to use this other
66 * tree (set of files).
68 public static final String TYPE_COMMIT
= "commit";
71 * Text string that identifies an object as a blob.
73 * Blobs store whole file revisions. They are used for any user file, as
74 * well as for symlinks. Blobs form the bulk of any project's storage space.
76 public static final String TYPE_BLOB
= "blob";
79 * Text string that identifies an object as a tree.
81 * Trees attach object ids (hashes) to names and file modes. The normal use
82 * for a tree is to store a version of a directory and its contents.
84 public static final String TYPE_TREE
= "tree";
87 * Text string that identifies an object as an annotated tag.
89 * Annotated tags store a pointer to any other object, and an additional
90 * message. It is most commonly used to record a stable release of the
93 public static final String TYPE_TAG
= "tag";
95 private static final byte[] ENCODED_TYPE_COMMIT
= encodeASCII(TYPE_COMMIT
);
97 private static final byte[] ENCODED_TYPE_BLOB
= encodeASCII(TYPE_BLOB
);
99 private static final byte[] ENCODED_TYPE_TREE
= encodeASCII(TYPE_TREE
);
101 private static final byte[] ENCODED_TYPE_TAG
= encodeASCII(TYPE_TAG
);
103 /** An unknown or invalid object type code. */
104 public static final int OBJ_BAD
= -1;
107 * In-pack object type: extended types.
109 * This header code is reserved for future expansion. It is currently
110 * undefined/unsupported.
112 public static final int OBJ_EXT
= 0;
115 * In-pack object type: commit.
117 * Indicates the associated object is a commit.
119 * <b>This constant is fixed and is defined by the Git packfile format.</b>
123 public static final int OBJ_COMMIT
= 1;
126 * In-pack object type: tree.
128 * Indicates the associated object is a tree.
130 * <b>This constant is fixed and is defined by the Git packfile format.</b>
134 public static final int OBJ_TREE
= 2;
137 * In-pack object type: blob.
139 * Indicates the associated object is a blob.
141 * <b>This constant is fixed and is defined by the Git packfile format.</b>
145 public static final int OBJ_BLOB
= 3;
148 * In-pack object type: annotated tag.
150 * Indicates the associated object is an annotated tag.
152 * <b>This constant is fixed and is defined by the Git packfile format.</b>
156 public static final int OBJ_TAG
= 4;
158 /** In-pack object type: reserved for future use. */
159 public static final int OBJ_TYPE_5
= 5;
162 * In-pack object type: offset delta
164 * Objects stored with this type actually have a different type which must
165 * be obtained from their delta base object. Delta objects store only the
166 * changes needed to apply to the base object in order to recover the
169 * An offset delta uses a negative offset from the start of this object to
170 * refer to its delta base. The base object must exist in this packfile
171 * (even in the case of a thin pack).
173 * <b>This constant is fixed and is defined by the Git packfile format.</b>
175 public static final int OBJ_OFS_DELTA
= 6;
178 * In-pack object type: reference delta
180 * Objects stored with this type actually have a different type which must
181 * be obtained from their delta base object. Delta objects store only the
182 * changes needed to apply to the base object in order to recover the
185 * A reference delta uses a full object id (hash) to reference the delta
186 * base. The base object is allowed to be omitted from the packfile, but
187 * only in the case of a thin pack being transferred over the network.
189 * <b>This constant is fixed and is defined by the Git packfile format.</b>
191 public static final int OBJ_REF_DELTA
= 7;
194 * Pack file signature that occurs at file header - identifies file as Git
195 * packfile formatted.
197 * <b>This constant is fixed and is defined by the Git packfile format.</b>
199 public static final byte[] PACK_SIGNATURE
= { 'P', 'A', 'C', 'K' };
201 /** Native character encoding for commit messages, file names... */
202 public static final String CHARACTER_ENCODING
= "UTF-8";
204 /** Native character encoding for commit messages, file names... */
205 public static final Charset CHARSET
;
207 /** Default main branch name */
208 public static final String MASTER
= "master";
210 /** Prefix for branch refs */
211 public static final String R_HEADS
= "refs/heads/";
213 /** Prefix for remotes refs */
214 public static final String R_REMOTES
= "refs/remotes/";
216 /** Prefix for tag refs */
217 public static final String R_TAGS
= "refs/tags/";
219 /** Prefix for any ref */
220 public static final String R_REFS
= "refs/";
222 /** Logs folder name */
223 public static final String LOGS
= "logs";
225 /** Info refs folder */
226 public static final String INFO_REFS
= "info/refs";
228 /** Packed refs file */
229 public static final String PACKED_REFS
= "packed-refs";
231 /** The environment variable that contains the system user name */
232 public static final String OS_USER_NAME_KEY
= "user.name";
234 /** The environment variable that contains the author's name */
235 public static final String GIT_AUTHOR_NAME_KEY
= "GIT_AUTHOR_NAME";
237 /** The environment variable that contains the author's email */
238 public static final String GIT_AUTHOR_EMAIL_KEY
= "GIT_AUTHOR_EMAIL";
240 /** The environment variable that contains the commiter's name */
241 public static final String GIT_COMMITTER_NAME_KEY
= "GIT_COMMITTER_NAME";
243 /** The environment variable that contains the commiter's email */
244 public static final String GIT_COMMITTER_EMAIL_KEY
= "GIT_COMMITTER_EMAIL";
246 /** Default value for the user name if no other information is available */
247 public static final String UNKNOWN_USER_DEFAULT
= "unknown-user";
249 /** Beginning of the common "Signed-off-by: " commit message line */
250 public static final String SIGNED_OFF_BY_TAG
= "Signed-off-by: ";
253 * Create a new digest function for objects.
255 * @return a new digest object.
256 * @throws RuntimeException
257 * this Java virtual machine does not support the required hash
258 * function. Very unlikely given that JGit uses a hash function
259 * that is in the Java reference specification.
261 public static MessageDigest
newMessageDigest() {
263 return MessageDigest
.getInstance(HASH_FUNCTION
);
264 } catch (NoSuchAlgorithmException nsae
) {
265 throw new RuntimeException("Required hash function "
266 + HASH_FUNCTION
+ " not available.", nsae
);
271 * Convert an OBJ_* type constant to a TYPE_* type constant.
273 * @param typeCode the type code, from a pack representation.
274 * @return the canonical string name of this type.
276 public static String
typeString(final int typeCode
) {
287 throw new IllegalArgumentException("Bad object type: " + typeCode
);
292 * Convert an OBJ_* type constant to an ASCII encoded string constant.
294 * The ASCII encoded string is often the canonical representation of
295 * the type within a loose object header, or within a tag header.
297 * @param typeCode the type code, from a pack representation.
298 * @return the canonical ASCII encoded name of this type.
300 public static byte[] encodedTypeString(final int typeCode
) {
303 return ENCODED_TYPE_COMMIT
;
305 return ENCODED_TYPE_TREE
;
307 return ENCODED_TYPE_BLOB
;
309 return ENCODED_TYPE_TAG
;
311 throw new IllegalArgumentException("Bad object type: " + typeCode
);
316 * Parse an encoded type string into a type constant.
319 * object id this type string came from; may be null if that is
320 * not known at the time the parse is occurring.
322 * string version of the type code.
324 * character immediately following the type string. Usually ' '
325 * (space) or '\n' (line feed).
327 * position within <code>typeString</code> where the parse
328 * should start. Updated with the new position (just past
329 * <code>endMark</code> when the parse is successful.
330 * @return a type code constant (one of {@link #OBJ_BLOB},
331 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}.
332 * @throws CorruptObjectException
333 * there is no valid type identified by <code>typeString</code>.
335 public static int decodeTypeString(final AnyObjectId id
,
336 final byte[] typeString
, final byte endMark
,
337 final MutableInteger offset
) throws CorruptObjectException
{
339 int position
= offset
.value
;
340 switch (typeString
[position
]) {
342 if (typeString
[position
+ 1] != 'l'
343 || typeString
[position
+ 2] != 'o'
344 || typeString
[position
+ 3] != 'b'
345 || typeString
[position
+ 4] != endMark
)
346 throw new CorruptObjectException(id
, "invalid type");
347 offset
.value
= position
+ 5;
348 return Constants
.OBJ_BLOB
;
351 if (typeString
[position
+ 1] != 'o'
352 || typeString
[position
+ 2] != 'm'
353 || typeString
[position
+ 3] != 'm'
354 || typeString
[position
+ 4] != 'i'
355 || typeString
[position
+ 5] != 't'
356 || typeString
[position
+ 6] != endMark
)
357 throw new CorruptObjectException(id
, "invalid type");
358 offset
.value
= position
+ 7;
359 return Constants
.OBJ_COMMIT
;
362 switch (typeString
[position
+ 1]) {
364 if (typeString
[position
+ 2] != 'g'
365 || typeString
[position
+ 3] != endMark
)
366 throw new CorruptObjectException(id
, "invalid type");
367 offset
.value
= position
+ 4;
368 return Constants
.OBJ_TAG
;
371 if (typeString
[position
+ 2] != 'e'
372 || typeString
[position
+ 3] != 'e'
373 || typeString
[position
+ 4] != endMark
)
374 throw new CorruptObjectException(id
, "invalid type");
375 offset
.value
= position
+ 5;
376 return Constants
.OBJ_TREE
;
379 throw new CorruptObjectException(id
, "invalid type");
383 throw new CorruptObjectException(id
, "invalid type");
385 } catch (ArrayIndexOutOfBoundsException bad
) {
386 throw new CorruptObjectException(id
, "invalid type");
391 * Convert an integer into its decimal representation.
394 * the integer to convert.
395 * @return a decimal representation of the input integer. The returned array
396 * is the smallest array that will hold the value.
398 public static byte[] encodeASCII(final long s
) {
399 return encodeASCII(Long
.toString(s
));
403 * Convert a string to US-ASCII encoding.
406 * the string to convert. Must not contain any characters over
407 * 127 (outside of 7-bit ASCII).
408 * @return a byte array of the same length as the input string, holding the
409 * same characters, in the same order.
410 * @throws IllegalArgumentException
411 * the input string contains one or more characters outside of
412 * the 7-bit ASCII character space.
414 public static byte[] encodeASCII(final String s
) {
415 final byte[] r
= new byte[s
.length()];
416 for (int k
= r
.length
- 1; k
>= 0; k
--) {
417 final char c
= s
.charAt(k
);
419 throw new IllegalArgumentException("Not ASCII string: " + s
);
426 * Convert a string to a byte array in the standard character encoding.
429 * the string to convert. May contain any Unicode characters.
430 * @return a byte array representing the requested string, encoded using the
431 * default character encoding (UTF-8).
432 * @see #CHARACTER_ENCODING
434 public static byte[] encode(final String str
) {
435 final ByteBuffer bb
= Constants
.CHARSET
.encode(str
);
436 final int len
= bb
.limit();
437 if (bb
.hasArray() && bb
.arrayOffset() == 0) {
438 final byte[] arr
= bb
.array();
439 if (arr
.length
== len
)
443 final byte[] arr
= new byte[len
];
449 if (OBJECT_ID_LENGTH
!= newMessageDigest().getDigestLength())
450 throw new LinkageError("Incorrect OBJECT_ID_LENGTH.");
451 CHARSET
= Charset
.forName(CHARACTER_ENCODING
);
454 private Constants() {
455 // Hide the default constructor