1 /* 2 * Copyright (C) 2008, Google Inc. 3 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> 4 * Copyright (C) 2006-2012, Shawn O. Pearce <spearce@spearce.org> 5 * and other copyright owners as documented in the project's IP log. 6 * 7 * This program and the accompanying materials are made available 8 * under the terms of the Eclipse Distribution License v1.0 which 9 * accompanies this distribution, is reproduced below, and is 10 * available at http://www.eclipse.org/org/documents/edl-v10.php 11 * 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or 15 * without modification, are permitted provided that the following 16 * conditions are met: 17 * 18 * - Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * - Neither the name of the Eclipse Foundation, Inc. nor the 27 * names of its contributors may be used to endorse or promote 28 * products derived from this software without specific prior 29 * written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 32 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 33 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 34 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 36 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 40 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 43 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 */ 45 46 package org.eclipse.jgit.lib; 47 48 import java.nio.ByteBuffer; 49 import java.nio.charset.Charset; 50 import java.security.MessageDigest; 51 import java.security.NoSuchAlgorithmException; 52 import java.text.MessageFormat; 53 54 import org.eclipse.jgit.errors.CorruptObjectException; 55 import org.eclipse.jgit.internal.JGitText; 56 import org.eclipse.jgit.util.MutableInteger; 57 58 /** Misc. constants used throughout JGit. */ 59 @SuppressWarnings("nls") 60 public final class Constants { 61 /** Hash function used natively by Git for all objects. */ 62 private static final String HASH_FUNCTION = "SHA-1"; 63 64 /** 65 * A Git object hash is 160 bits, i.e. 20 bytes. 66 * <p> 67 * Changing this assumption is not going to be as easy as changing this 68 * declaration. 69 */ 70 public static final int OBJECT_ID_LENGTH = 20; 71 72 /** 73 * A Git object can be expressed as a 40 character string of hexadecimal 74 * digits. 75 * 76 * @see #OBJECT_ID_LENGTH 77 */ 78 public static final int OBJECT_ID_STRING_LENGTH = OBJECT_ID_LENGTH * 2; 79 80 /** Special name for the "HEAD" symbolic-ref. */ 81 public static final String HEAD = "HEAD"; 82 83 /** Special name for the "FETCH_HEAD" symbolic-ref. */ 84 public static final String FETCH_HEAD = "FETCH_HEAD"; 85 86 /** 87 * Text string that identifies an object as a commit. 88 * <p> 89 * Commits connect trees into a string of project histories, where each 90 * commit is an assertion that the best way to continue is to use this other 91 * tree (set of files). 92 */ 93 public static final String TYPE_COMMIT = "commit"; 94 95 /** 96 * Text string that identifies an object as a blob. 97 * <p> 98 * Blobs store whole file revisions. They are used for any user file, as 99 * well as for symlinks. Blobs form the bulk of any project's storage space. 100 */ 101 public static final String TYPE_BLOB = "blob"; 102 103 /** 104 * Text string that identifies an object as a tree. 105 * <p> 106 * Trees attach object ids (hashes) to names and file modes. The normal use 107 * for a tree is to store a version of a directory and its contents. 108 */ 109 public static final String TYPE_TREE = "tree"; 110 111 /** 112 * Text string that identifies an object as an annotated tag. 113 * <p> 114 * Annotated tags store a pointer to any other object, and an additional 115 * message. It is most commonly used to record a stable release of the 116 * project. 117 */ 118 public static final String TYPE_TAG = "tag"; 119 120 private static final byte[] ENCODED_TYPE_COMMIT = encodeASCII(TYPE_COMMIT); 121 122 private static final byte[] ENCODED_TYPE_BLOB = encodeASCII(TYPE_BLOB); 123 124 private static final byte[] ENCODED_TYPE_TREE = encodeASCII(TYPE_TREE); 125 126 private static final byte[] ENCODED_TYPE_TAG = encodeASCII(TYPE_TAG); 127 128 /** An unknown or invalid object type code. */ 129 public static final int OBJ_BAD = -1; 130 131 /** 132 * In-pack object type: extended types. 133 * <p> 134 * This header code is reserved for future expansion. It is currently 135 * undefined/unsupported. 136 */ 137 public static final int OBJ_EXT = 0; 138 139 /** 140 * In-pack object type: commit. 141 * <p> 142 * Indicates the associated object is a commit. 143 * <p> 144 * <b>This constant is fixed and is defined by the Git packfile format.</b> 145 * 146 * @see #TYPE_COMMIT 147 */ 148 public static final int OBJ_COMMIT = 1; 149 150 /** 151 * In-pack object type: tree. 152 * <p> 153 * Indicates the associated object is a tree. 154 * <p> 155 * <b>This constant is fixed and is defined by the Git packfile format.</b> 156 * 157 * @see #TYPE_BLOB 158 */ 159 public static final int OBJ_TREE = 2; 160 161 /** 162 * In-pack object type: blob. 163 * <p> 164 * Indicates the associated object is a blob. 165 * <p> 166 * <b>This constant is fixed and is defined by the Git packfile format.</b> 167 * 168 * @see #TYPE_BLOB 169 */ 170 public static final int OBJ_BLOB = 3; 171 172 /** 173 * In-pack object type: annotated tag. 174 * <p> 175 * Indicates the associated object is an annotated tag. 176 * <p> 177 * <b>This constant is fixed and is defined by the Git packfile format.</b> 178 * 179 * @see #TYPE_TAG 180 */ 181 public static final int OBJ_TAG = 4; 182 183 /** In-pack object type: reserved for future use. */ 184 public static final int OBJ_TYPE_5 = 5; 185 186 /** 187 * In-pack object type: offset delta 188 * <p> 189 * Objects stored with this type actually have a different type which must 190 * be obtained from their delta base object. Delta objects store only the 191 * changes needed to apply to the base object in order to recover the 192 * original object. 193 * <p> 194 * An offset delta uses a negative offset from the start of this object to 195 * refer to its delta base. The base object must exist in this packfile 196 * (even in the case of a thin pack). 197 * <p> 198 * <b>This constant is fixed and is defined by the Git packfile format.</b> 199 */ 200 public static final int OBJ_OFS_DELTA = 6; 201 202 /** 203 * In-pack object type: reference delta 204 * <p> 205 * Objects stored with this type actually have a different type which must 206 * be obtained from their delta base object. Delta objects store only the 207 * changes needed to apply to the base object in order to recover the 208 * original object. 209 * <p> 210 * A reference delta uses a full object id (hash) to reference the delta 211 * base. The base object is allowed to be omitted from the packfile, but 212 * only in the case of a thin pack being transferred over the network. 213 * <p> 214 * <b>This constant is fixed and is defined by the Git packfile format.</b> 215 */ 216 public static final int OBJ_REF_DELTA = 7; 217 218 /** 219 * Pack file signature that occurs at file header - identifies file as Git 220 * packfile formatted. 221 * <p> 222 * <b>This constant is fixed and is defined by the Git packfile format.</b> 223 */ 224 public static final byte[] PACK_SIGNATURE = { 'P', 'A', 'C', 'K' }; 225 226 /** Native character encoding for commit messages, file names... */ 227 public static final String CHARACTER_ENCODING = "UTF-8"; 228 229 /** Native character encoding for commit messages, file names... */ 230 public static final Charset CHARSET; 231 232 /** Default main branch name */ 233 public static final String MASTER = "master"; 234 235 /** Default stash branch name */ 236 public static final String STASH = "stash"; 237 238 /** Prefix for branch refs */ 239 public static final String R_HEADS = "refs/heads/"; 240 241 /** Prefix for remotes refs */ 242 public static final String R_REMOTES = "refs/remotes/"; 243 244 /** Prefix for tag refs */ 245 public static final String R_TAGS = "refs/tags/"; 246 247 /** Prefix for notes refs */ 248 public static final String R_NOTES = "refs/notes/"; 249 250 /** Standard notes ref */ 251 public static final String R_NOTES_COMMITS = R_NOTES + "commits"; 252 253 /** Prefix for any ref */ 254 public static final String R_REFS = "refs/"; 255 256 /** Standard stash ref */ 257 public static final String R_STASH = R_REFS + STASH; 258 259 /** Logs folder name */ 260 public static final String LOGS = "logs"; 261 262 /** Info refs folder */ 263 public static final String INFO_REFS = "info/refs"; 264 265 /** Packed refs file */ 266 public static final String PACKED_REFS = "packed-refs"; 267 268 /** 269 * Excludes-file 270 * 271 * @since 3.0 272 */ 273 public static final String INFO_EXCLUDE = "info/exclude"; 274 275 /** 276 * The system property that contains the system user name 277 * 278 * @since 3.6 279 */ 280 public static final String OS_USER_DIR = "user.dir"; 281 282 /** The system property that contains the system user name */ 283 public static final String OS_USER_NAME_KEY = "user.name"; 284 285 /** The environment variable that contains the author's name */ 286 public static final String GIT_AUTHOR_NAME_KEY = "GIT_AUTHOR_NAME"; 287 288 /** The environment variable that contains the author's email */ 289 public static final String GIT_AUTHOR_EMAIL_KEY = "GIT_AUTHOR_EMAIL"; 290 291 /** The environment variable that contains the commiter's name */ 292 public static final String GIT_COMMITTER_NAME_KEY = "GIT_COMMITTER_NAME"; 293 294 /** The environment variable that contains the commiter's email */ 295 public static final String GIT_COMMITTER_EMAIL_KEY = "GIT_COMMITTER_EMAIL"; 296 297 /** 298 * The environment variable that blocks use of the system config file 299 * 300 * @since 3.3 301 */ 302 public static final String GIT_CONFIG_NOSYSTEM_KEY = "GIT_CONFIG_NOSYSTEM"; 303 304 /** 305 * The environment variable that limits how close to the root of the file 306 * systems JGit will traverse when looking for a repository root. 307 */ 308 public static final String GIT_CEILING_DIRECTORIES_KEY = "GIT_CEILING_DIRECTORIES"; 309 310 /** 311 * The environment variable that tells us which directory is the ".git" 312 * directory 313 */ 314 public static final String GIT_DIR_KEY = "GIT_DIR"; 315 316 /** 317 * The environment variable that tells us which directory is the working 318 * directory. 319 */ 320 public static final String GIT_WORK_TREE_KEY = "GIT_WORK_TREE"; 321 322 /** 323 * The environment variable that tells us which file holds the Git index. 324 */ 325 public static final String GIT_INDEX_FILE_KEY = "GIT_INDEX_FILE"; 326 327 /** 328 * The environment variable that tells us where objects are stored 329 */ 330 public static final String GIT_OBJECT_DIRECTORY_KEY = "GIT_OBJECT_DIRECTORY"; 331 332 /** 333 * The environment variable that tells us where to look for objects, besides 334 * the default objects directory. 335 */ 336 public static final String GIT_ALTERNATE_OBJECT_DIRECTORIES_KEY = "GIT_ALTERNATE_OBJECT_DIRECTORIES"; 337 338 /** Default value for the user name if no other information is available */ 339 public static final String UNKNOWN_USER_DEFAULT = "unknown-user"; 340 341 /** Beginning of the common "Signed-off-by: " commit message line */ 342 public static final String SIGNED_OFF_BY_TAG = "Signed-off-by: "; 343 344 /** A gitignore file name */ 345 public static final String GITIGNORE_FILENAME = ".gitignore"; 346 347 /** Default remote name used by clone, push and fetch operations */ 348 public static final String DEFAULT_REMOTE_NAME = "origin"; 349 350 /** Default name for the Git repository directory */ 351 public static final String DOT_GIT = ".git"; 352 353 /** Default name for the Git repository configuration */ 354 public static final String CONFIG = "config"; 355 356 /** A bare repository typically ends with this string */ 357 public static final String DOT_GIT_EXT = ".git"; 358 359 /** 360 * Name of the attributes file 361 * 362 * @since 3.7 363 */ 364 public static final String DOT_GIT_ATTRIBUTES = ".gitattributes"; 365 366 /** Name of the ignore file */ 367 public static final String DOT_GIT_IGNORE = ".gitignore"; 368 369 /** Name of the submodules file */ 370 public static final String DOT_GIT_MODULES = ".gitmodules"; 371 372 /** Name of the .git/shallow file */ 373 public static final String SHALLOW = "shallow"; 374 375 /** 376 * Prefix of the first line in a ".git" file 377 * 378 * @since 3.6 379 */ 380 public static final String GITDIR = "gitdir: "; 381 382 /** 383 * Name of the folder (inside gitDir) where submodules are stored 384 * 385 * @since 3.6 386 */ 387 public static final String MODULES = "modules"; 388 389 /** 390 * Name of the folder (inside gitDir) where the hooks are stored. 391 * 392 * @since 3.7 393 */ 394 public static final String HOOKS = "hooks"; 395 396 /** 397 * Create a new digest function for objects. 398 * 399 * @return a new digest object. 400 * @throws RuntimeException 401 * this Java virtual machine does not support the required hash 402 * function. Very unlikely given that JGit uses a hash function 403 * that is in the Java reference specification. 404 */ 405 public static MessageDigest newMessageDigest() { 406 try { 407 return MessageDigest.getInstance(HASH_FUNCTION); 408 } catch (NoSuchAlgorithmException nsae) { 409 throw new RuntimeException(MessageFormat.format( 410 JGitText.get().requiredHashFunctionNotAvailable, HASH_FUNCTION), nsae); 411 } 412 } 413 414 /** 415 * Convert an OBJ_* type constant to a TYPE_* type constant. 416 * 417 * @param typeCode the type code, from a pack representation. 418 * @return the canonical string name of this type. 419 */ 420 public static String typeString(final int typeCode) { 421 switch (typeCode) { 422 case OBJ_COMMIT: 423 return TYPE_COMMIT; 424 case OBJ_TREE: 425 return TYPE_TREE; 426 case OBJ_BLOB: 427 return TYPE_BLOB; 428 case OBJ_TAG: 429 return TYPE_TAG; 430 default: 431 throw new IllegalArgumentException(MessageFormat.format( 432 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 433 } 434 } 435 436 /** 437 * Convert an OBJ_* type constant to an ASCII encoded string constant. 438 * <p> 439 * The ASCII encoded string is often the canonical representation of 440 * the type within a loose object header, or within a tag header. 441 * 442 * @param typeCode the type code, from a pack representation. 443 * @return the canonical ASCII encoded name of this type. 444 */ 445 public static byte[] encodedTypeString(final int typeCode) { 446 switch (typeCode) { 447 case OBJ_COMMIT: 448 return ENCODED_TYPE_COMMIT; 449 case OBJ_TREE: 450 return ENCODED_TYPE_TREE; 451 case OBJ_BLOB: 452 return ENCODED_TYPE_BLOB; 453 case OBJ_TAG: 454 return ENCODED_TYPE_TAG; 455 default: 456 throw new IllegalArgumentException(MessageFormat.format( 457 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 458 } 459 } 460 461 /** 462 * Parse an encoded type string into a type constant. 463 * 464 * @param id 465 * object id this type string came from; may be null if that is 466 * not known at the time the parse is occurring. 467 * @param typeString 468 * string version of the type code. 469 * @param endMark 470 * character immediately following the type string. Usually ' ' 471 * (space) or '\n' (line feed). 472 * @param offset 473 * position within <code>typeString</code> where the parse 474 * should start. Updated with the new position (just past 475 * <code>endMark</code> when the parse is successful. 476 * @return a type code constant (one of {@link #OBJ_BLOB}, 477 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}. 478 * @throws CorruptObjectException 479 * there is no valid type identified by <code>typeString</code>. 480 */ 481 public static int decodeTypeString(final AnyObjectId id, 482 final byte[] typeString, final byte endMark, 483 final MutableInteger offset) throws CorruptObjectException { 484 try { 485 int position = offset.value; 486 switch (typeString[position]) { 487 case 'b': 488 if (typeString[position + 1] != 'l' 489 || typeString[position + 2] != 'o' 490 || typeString[position + 3] != 'b' 491 || typeString[position + 4] != endMark) 492 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 493 offset.value = position + 5; 494 return Constants.OBJ_BLOB; 495 496 case 'c': 497 if (typeString[position + 1] != 'o' 498 || typeString[position + 2] != 'm' 499 || typeString[position + 3] != 'm' 500 || typeString[position + 4] != 'i' 501 || typeString[position + 5] != 't' 502 || typeString[position + 6] != endMark) 503 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 504 offset.value = position + 7; 505 return Constants.OBJ_COMMIT; 506 507 case 't': 508 switch (typeString[position + 1]) { 509 case 'a': 510 if (typeString[position + 2] != 'g' 511 || typeString[position + 3] != endMark) 512 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 513 offset.value = position + 4; 514 return Constants.OBJ_TAG; 515 516 case 'r': 517 if (typeString[position + 2] != 'e' 518 || typeString[position + 3] != 'e' 519 || typeString[position + 4] != endMark) 520 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 521 offset.value = position + 5; 522 return Constants.OBJ_TREE; 523 524 default: 525 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 526 } 527 528 default: 529 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 530 } 531 } catch (ArrayIndexOutOfBoundsException bad) { 532 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 533 } 534 } 535 536 /** 537 * Convert an integer into its decimal representation. 538 * 539 * @param s 540 * the integer to convert. 541 * @return a decimal representation of the input integer. The returned array 542 * is the smallest array that will hold the value. 543 */ 544 public static byte[] encodeASCII(final long s) { 545 return encodeASCII(Long.toString(s)); 546 } 547 548 /** 549 * Convert a string to US-ASCII encoding. 550 * 551 * @param s 552 * the string to convert. Must not contain any characters over 553 * 127 (outside of 7-bit ASCII). 554 * @return a byte array of the same length as the input string, holding the 555 * same characters, in the same order. 556 * @throws IllegalArgumentException 557 * the input string contains one or more characters outside of 558 * the 7-bit ASCII character space. 559 */ 560 public static byte[] encodeASCII(final String s) { 561 final byte[] r = new byte[s.length()]; 562 for (int k = r.length - 1; k >= 0; k--) { 563 final char c = s.charAt(k); 564 if (c > 127) 565 throw new IllegalArgumentException(MessageFormat.format(JGitText.get().notASCIIString, s)); 566 r[k] = (byte) c; 567 } 568 return r; 569 } 570 571 /** 572 * Convert a string to a byte array in the standard character encoding. 573 * 574 * @param str 575 * the string to convert. May contain any Unicode characters. 576 * @return a byte array representing the requested string, encoded using the 577 * default character encoding (UTF-8). 578 * @see #CHARACTER_ENCODING 579 */ 580 public static byte[] encode(final String str) { 581 final ByteBuffer bb = Constants.CHARSET.encode(str); 582 final int len = bb.limit(); 583 if (bb.hasArray() && bb.arrayOffset() == 0) { 584 final byte[] arr = bb.array(); 585 if (arr.length == len) 586 return arr; 587 } 588 589 final byte[] arr = new byte[len]; 590 bb.get(arr); 591 return arr; 592 } 593 594 static { 595 if (OBJECT_ID_LENGTH != newMessageDigest().getDigestLength()) 596 throw new LinkageError(JGitText.get().incorrectOBJECT_ID_LENGTH); 597 CHARSET = Charset.forName(CHARACTER_ENCODING); 598 } 599 600 /** name of the file containing the commit msg for a merge commit */ 601 public static final String MERGE_MSG = "MERGE_MSG"; 602 603 /** name of the file containing the IDs of the parents of a merge commit */ 604 public static final String MERGE_HEAD = "MERGE_HEAD"; 605 606 /** name of the file containing the ID of a cherry pick commit in case of conflicts */ 607 public static final String CHERRY_PICK_HEAD = "CHERRY_PICK_HEAD"; 608 609 /** name of the file containing the commit msg for a squash commit */ 610 public static final String SQUASH_MSG = "SQUASH_MSG"; 611 612 /** name of the file containing the ID of a revert commit in case of conflicts */ 613 public static final String REVERT_HEAD = "REVERT_HEAD"; 614 615 /** 616 * name of the ref ORIG_HEAD used by certain commands to store the original 617 * value of HEAD 618 */ 619 public static final String ORIG_HEAD = "ORIG_HEAD"; 620 621 /** 622 * Name of the file in which git commands and hooks store and read the 623 * message prepared for the upcoming commit. 624 * 625 * @since 4.0 626 */ 627 public static final String COMMIT_EDITMSG = "COMMIT_EDITMSG"; 628 629 /** objectid for the empty blob */ 630 public static final ObjectId EMPTY_BLOB_ID = ObjectId 631 .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); 632 633 private Constants() { 634 // Hide the default constructor 635 } 636 }