1 /* 2 * Copyright (C) 2008, Google Inc. 3 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> 4 * Copyright (C) 2006-2017, 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 * Attributes-override-file 277 * 278 * @since 4.2 279 */ 280 public static final String INFO_ATTRIBUTES = "info/attributes"; 281 282 /** 283 * The system property that contains the system user name 284 * 285 * @since 3.6 286 */ 287 public static final String OS_USER_DIR = "user.dir"; 288 289 /** The system property that contains the system user name */ 290 public static final String OS_USER_NAME_KEY = "user.name"; 291 292 /** The environment variable that contains the author's name */ 293 public static final String GIT_AUTHOR_NAME_KEY = "GIT_AUTHOR_NAME"; 294 295 /** The environment variable that contains the author's email */ 296 public static final String GIT_AUTHOR_EMAIL_KEY = "GIT_AUTHOR_EMAIL"; 297 298 /** The environment variable that contains the commiter's name */ 299 public static final String GIT_COMMITTER_NAME_KEY = "GIT_COMMITTER_NAME"; 300 301 /** The environment variable that contains the commiter's email */ 302 public static final String GIT_COMMITTER_EMAIL_KEY = "GIT_COMMITTER_EMAIL"; 303 304 /** 305 * The environment variable that blocks use of the system config file 306 * 307 * @since 3.3 308 */ 309 public static final String GIT_CONFIG_NOSYSTEM_KEY = "GIT_CONFIG_NOSYSTEM"; 310 311 /** 312 * The environment variable that limits how close to the root of the file 313 * systems JGit will traverse when looking for a repository root. 314 */ 315 public static final String GIT_CEILING_DIRECTORIES_KEY = "GIT_CEILING_DIRECTORIES"; 316 317 /** 318 * The environment variable that tells us which directory is the ".git" 319 * directory 320 */ 321 public static final String GIT_DIR_KEY = "GIT_DIR"; 322 323 /** 324 * The environment variable that tells us which directory is the working 325 * directory. 326 */ 327 public static final String GIT_WORK_TREE_KEY = "GIT_WORK_TREE"; 328 329 /** 330 * The environment variable that tells us which file holds the Git index. 331 */ 332 public static final String GIT_INDEX_FILE_KEY = "GIT_INDEX_FILE"; 333 334 /** 335 * The environment variable that tells us where objects are stored 336 */ 337 public static final String GIT_OBJECT_DIRECTORY_KEY = "GIT_OBJECT_DIRECTORY"; 338 339 /** 340 * The environment variable that tells us where to look for objects, besides 341 * the default objects directory. 342 */ 343 public static final String GIT_ALTERNATE_OBJECT_DIRECTORIES_KEY = "GIT_ALTERNATE_OBJECT_DIRECTORIES"; 344 345 /** Default value for the user name if no other information is available */ 346 public static final String UNKNOWN_USER_DEFAULT = "unknown-user"; 347 348 /** Beginning of the common "Signed-off-by: " commit message line */ 349 public static final String SIGNED_OFF_BY_TAG = "Signed-off-by: "; 350 351 /** A gitignore file name */ 352 public static final String GITIGNORE_FILENAME = ".gitignore"; 353 354 /** Default remote name used by clone, push and fetch operations */ 355 public static final String DEFAULT_REMOTE_NAME = "origin"; 356 357 /** Default name for the Git repository directory */ 358 public static final String DOT_GIT = ".git"; 359 360 /** Default name for the Git repository configuration */ 361 public static final String CONFIG = "config"; 362 363 /** A bare repository typically ends with this string */ 364 public static final String DOT_GIT_EXT = ".git"; 365 366 /** 367 * Name of the attributes file 368 * 369 * @since 3.7 370 */ 371 public static final String DOT_GIT_ATTRIBUTES = ".gitattributes"; 372 373 /** 374 * Key for filters in .gitattributes 375 * 376 * @since 4.2 377 */ 378 public static final String ATTR_FILTER = "filter"; 379 380 /** 381 * clean command name, used to call filter driver 382 * 383 * @since 4.2 384 */ 385 public static final String ATTR_FILTER_TYPE_CLEAN = "clean"; 386 387 /** 388 * smudge command name, used to call filter driver 389 * 390 * @since 4.2 391 */ 392 public static final String ATTR_FILTER_TYPE_SMUDGE = "smudge"; 393 394 /** 395 * Builtin filter commands start with this prefix 396 * 397 * @since 4.6 398 */ 399 public static final String BUILTIN_FILTER_PREFIX = "jgit://builtin/"; 400 401 /** Name of the ignore file */ 402 public static final String DOT_GIT_IGNORE = ".gitignore"; 403 404 /** Name of the submodules file */ 405 public static final String DOT_GIT_MODULES = ".gitmodules"; 406 407 /** Name of the .git/shallow file */ 408 public static final String SHALLOW = "shallow"; 409 410 /** 411 * Prefix of the first line in a ".git" file 412 * 413 * @since 3.6 414 */ 415 public static final String GITDIR = "gitdir: "; 416 417 /** 418 * Name of the folder (inside gitDir) where submodules are stored 419 * 420 * @since 3.6 421 */ 422 public static final String MODULES = "modules"; 423 424 /** 425 * Name of the folder (inside gitDir) where the hooks are stored. 426 * 427 * @since 3.7 428 */ 429 public static final String HOOKS = "hooks"; 430 431 /** 432 * Merge attribute. 433 * 434 * @since 4.9 435 */ 436 public static final String ATTR_MERGE = "merge"; //$NON-NLS-1$ 437 438 /** 439 * Binary value for custom merger. 440 * 441 * @since 4.9 442 */ 443 public static final String ATTR_BUILTIN_BINARY_MERGER = "binary"; //$NON-NLS-1$ 444 445 /** 446 * Create a new digest function for objects. 447 * 448 * @return a new digest object. 449 * @throws RuntimeException 450 * this Java virtual machine does not support the required hash 451 * function. Very unlikely given that JGit uses a hash function 452 * that is in the Java reference specification. 453 */ 454 public static MessageDigest newMessageDigest() { 455 try { 456 return MessageDigest.getInstance(HASH_FUNCTION); 457 } catch (NoSuchAlgorithmException nsae) { 458 throw new RuntimeException(MessageFormat.format( 459 JGitText.get().requiredHashFunctionNotAvailable, HASH_FUNCTION), nsae); 460 } 461 } 462 463 /** 464 * Convert an OBJ_* type constant to a TYPE_* type constant. 465 * 466 * @param typeCode the type code, from a pack representation. 467 * @return the canonical string name of this type. 468 */ 469 public static String typeString(final int typeCode) { 470 switch (typeCode) { 471 case OBJ_COMMIT: 472 return TYPE_COMMIT; 473 case OBJ_TREE: 474 return TYPE_TREE; 475 case OBJ_BLOB: 476 return TYPE_BLOB; 477 case OBJ_TAG: 478 return TYPE_TAG; 479 default: 480 throw new IllegalArgumentException(MessageFormat.format( 481 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 482 } 483 } 484 485 /** 486 * Convert an OBJ_* type constant to an ASCII encoded string constant. 487 * <p> 488 * The ASCII encoded string is often the canonical representation of 489 * the type within a loose object header, or within a tag header. 490 * 491 * @param typeCode the type code, from a pack representation. 492 * @return the canonical ASCII encoded name of this type. 493 */ 494 public static byte[] encodedTypeString(final int typeCode) { 495 switch (typeCode) { 496 case OBJ_COMMIT: 497 return ENCODED_TYPE_COMMIT; 498 case OBJ_TREE: 499 return ENCODED_TYPE_TREE; 500 case OBJ_BLOB: 501 return ENCODED_TYPE_BLOB; 502 case OBJ_TAG: 503 return ENCODED_TYPE_TAG; 504 default: 505 throw new IllegalArgumentException(MessageFormat.format( 506 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 507 } 508 } 509 510 /** 511 * Parse an encoded type string into a type constant. 512 * 513 * @param id 514 * object id this type string came from; may be null if that is 515 * not known at the time the parse is occurring. 516 * @param typeString 517 * string version of the type code. 518 * @param endMark 519 * character immediately following the type string. Usually ' ' 520 * (space) or '\n' (line feed). 521 * @param offset 522 * position within <code>typeString</code> where the parse 523 * should start. Updated with the new position (just past 524 * <code>endMark</code> when the parse is successful. 525 * @return a type code constant (one of {@link #OBJ_BLOB}, 526 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}. 527 * @throws CorruptObjectException 528 * there is no valid type identified by <code>typeString</code>. 529 */ 530 public static int decodeTypeString(final AnyObjectId id, 531 final byte[] typeString, final byte endMark, 532 final MutableInteger offset) throws CorruptObjectException { 533 try { 534 int position = offset.value; 535 switch (typeString[position]) { 536 case 'b': 537 if (typeString[position + 1] != 'l' 538 || typeString[position + 2] != 'o' 539 || typeString[position + 3] != 'b' 540 || typeString[position + 4] != endMark) 541 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 542 offset.value = position + 5; 543 return Constants.OBJ_BLOB; 544 545 case 'c': 546 if (typeString[position + 1] != 'o' 547 || typeString[position + 2] != 'm' 548 || typeString[position + 3] != 'm' 549 || typeString[position + 4] != 'i' 550 || typeString[position + 5] != 't' 551 || typeString[position + 6] != endMark) 552 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 553 offset.value = position + 7; 554 return Constants.OBJ_COMMIT; 555 556 case 't': 557 switch (typeString[position + 1]) { 558 case 'a': 559 if (typeString[position + 2] != 'g' 560 || typeString[position + 3] != endMark) 561 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 562 offset.value = position + 4; 563 return Constants.OBJ_TAG; 564 565 case 'r': 566 if (typeString[position + 2] != 'e' 567 || typeString[position + 3] != 'e' 568 || typeString[position + 4] != endMark) 569 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 570 offset.value = position + 5; 571 return Constants.OBJ_TREE; 572 573 default: 574 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 575 } 576 577 default: 578 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 579 } 580 } catch (ArrayIndexOutOfBoundsException bad) { 581 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 582 } 583 } 584 585 /** 586 * Convert an integer into its decimal representation. 587 * 588 * @param s 589 * the integer to convert. 590 * @return a decimal representation of the input integer. The returned array 591 * is the smallest array that will hold the value. 592 */ 593 public static byte[] encodeASCII(final long s) { 594 return encodeASCII(Long.toString(s)); 595 } 596 597 /** 598 * Convert a string to US-ASCII encoding. 599 * 600 * @param s 601 * the string to convert. Must not contain any characters over 602 * 127 (outside of 7-bit ASCII). 603 * @return a byte array of the same length as the input string, holding the 604 * same characters, in the same order. 605 * @throws IllegalArgumentException 606 * the input string contains one or more characters outside of 607 * the 7-bit ASCII character space. 608 */ 609 public static byte[] encodeASCII(final String s) { 610 final byte[] r = new byte[s.length()]; 611 for (int k = r.length - 1; k >= 0; k--) { 612 final char c = s.charAt(k); 613 if (c > 127) 614 throw new IllegalArgumentException(MessageFormat.format(JGitText.get().notASCIIString, s)); 615 r[k] = (byte) c; 616 } 617 return r; 618 } 619 620 /** 621 * Convert a string to a byte array in the standard character encoding. 622 * 623 * @param str 624 * the string to convert. May contain any Unicode characters. 625 * @return a byte array representing the requested string, encoded using the 626 * default character encoding (UTF-8). 627 * @see #CHARACTER_ENCODING 628 */ 629 public static byte[] encode(final String str) { 630 final ByteBuffer bb = Constants.CHARSET.encode(str); 631 final int len = bb.limit(); 632 if (bb.hasArray() && bb.arrayOffset() == 0) { 633 final byte[] arr = bb.array(); 634 if (arr.length == len) 635 return arr; 636 } 637 638 final byte[] arr = new byte[len]; 639 bb.get(arr); 640 return arr; 641 } 642 643 static { 644 if (OBJECT_ID_LENGTH != newMessageDigest().getDigestLength()) 645 throw new LinkageError(JGitText.get().incorrectOBJECT_ID_LENGTH); 646 CHARSET = Charset.forName(CHARACTER_ENCODING); 647 } 648 649 /** name of the file containing the commit msg for a merge commit */ 650 public static final String MERGE_MSG = "MERGE_MSG"; 651 652 /** name of the file containing the IDs of the parents of a merge commit */ 653 public static final String MERGE_HEAD = "MERGE_HEAD"; 654 655 /** name of the file containing the ID of a cherry pick commit in case of conflicts */ 656 public static final String CHERRY_PICK_HEAD = "CHERRY_PICK_HEAD"; 657 658 /** name of the file containing the commit msg for a squash commit */ 659 public static final String SQUASH_MSG = "SQUASH_MSG"; 660 661 /** name of the file containing the ID of a revert commit in case of conflicts */ 662 public static final String REVERT_HEAD = "REVERT_HEAD"; 663 664 /** 665 * name of the ref ORIG_HEAD used by certain commands to store the original 666 * value of HEAD 667 */ 668 public static final String ORIG_HEAD = "ORIG_HEAD"; 669 670 /** 671 * Name of the file in which git commands and hooks store and read the 672 * message prepared for the upcoming commit. 673 * 674 * @since 4.0 675 */ 676 public static final String COMMIT_EDITMSG = "COMMIT_EDITMSG"; 677 678 /** objectid for the empty blob */ 679 public static final ObjectId EMPTY_BLOB_ID = ObjectId 680 .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); 681 682 private Constants() { 683 // Hide the default constructor 684 } 685 }