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 /** 59 * Misc. constants used throughout JGit. 60 */ 61 @SuppressWarnings("nls") 62 public final class Constants { 63 /** Hash function used natively by Git for all objects. */ 64 private static final String HASH_FUNCTION = "SHA-1"; 65 66 /** 67 * A Git object hash is 160 bits, i.e. 20 bytes. 68 * <p> 69 * Changing this assumption is not going to be as easy as changing this 70 * declaration. 71 */ 72 public static final int OBJECT_ID_LENGTH = 20; 73 74 /** 75 * A Git object can be expressed as a 40 character string of hexadecimal 76 * digits. 77 * 78 * @see #OBJECT_ID_LENGTH 79 */ 80 public static final int OBJECT_ID_STRING_LENGTH = OBJECT_ID_LENGTH * 2; 81 82 /** Special name for the "HEAD" symbolic-ref. */ 83 public static final String HEAD = "HEAD"; 84 85 /** Special name for the "FETCH_HEAD" symbolic-ref. */ 86 public static final String FETCH_HEAD = "FETCH_HEAD"; 87 88 /** 89 * Text string that identifies an object as a commit. 90 * <p> 91 * Commits connect trees into a string of project histories, where each 92 * commit is an assertion that the best way to continue is to use this other 93 * tree (set of files). 94 */ 95 public static final String TYPE_COMMIT = "commit"; 96 97 /** 98 * Text string that identifies an object as a blob. 99 * <p> 100 * Blobs store whole file revisions. They are used for any user file, as 101 * well as for symlinks. Blobs form the bulk of any project's storage space. 102 */ 103 public static final String TYPE_BLOB = "blob"; 104 105 /** 106 * Text string that identifies an object as a tree. 107 * <p> 108 * Trees attach object ids (hashes) to names and file modes. The normal use 109 * for a tree is to store a version of a directory and its contents. 110 */ 111 public static final String TYPE_TREE = "tree"; 112 113 /** 114 * Text string that identifies an object as an annotated tag. 115 * <p> 116 * Annotated tags store a pointer to any other object, and an additional 117 * message. It is most commonly used to record a stable release of the 118 * project. 119 */ 120 public static final String TYPE_TAG = "tag"; 121 122 private static final byte[] ENCODED_TYPE_COMMIT = encodeASCII(TYPE_COMMIT); 123 124 private static final byte[] ENCODED_TYPE_BLOB = encodeASCII(TYPE_BLOB); 125 126 private static final byte[] ENCODED_TYPE_TREE = encodeASCII(TYPE_TREE); 127 128 private static final byte[] ENCODED_TYPE_TAG = encodeASCII(TYPE_TAG); 129 130 /** An unknown or invalid object type code. */ 131 public static final int OBJ_BAD = -1; 132 133 /** 134 * In-pack object type: extended types. 135 * <p> 136 * This header code is reserved for future expansion. It is currently 137 * undefined/unsupported. 138 */ 139 public static final int OBJ_EXT = 0; 140 141 /** 142 * In-pack object type: commit. 143 * <p> 144 * Indicates the associated object is a commit. 145 * <p> 146 * <b>This constant is fixed and is defined by the Git packfile format.</b> 147 * 148 * @see #TYPE_COMMIT 149 */ 150 public static final int OBJ_COMMIT = 1; 151 152 /** 153 * In-pack object type: tree. 154 * <p> 155 * Indicates the associated object is a tree. 156 * <p> 157 * <b>This constant is fixed and is defined by the Git packfile format.</b> 158 * 159 * @see #TYPE_BLOB 160 */ 161 public static final int OBJ_TREE = 2; 162 163 /** 164 * In-pack object type: blob. 165 * <p> 166 * Indicates the associated object is a blob. 167 * <p> 168 * <b>This constant is fixed and is defined by the Git packfile format.</b> 169 * 170 * @see #TYPE_BLOB 171 */ 172 public static final int OBJ_BLOB = 3; 173 174 /** 175 * In-pack object type: annotated tag. 176 * <p> 177 * Indicates the associated object is an annotated tag. 178 * <p> 179 * <b>This constant is fixed and is defined by the Git packfile format.</b> 180 * 181 * @see #TYPE_TAG 182 */ 183 public static final int OBJ_TAG = 4; 184 185 /** In-pack object type: reserved for future use. */ 186 public static final int OBJ_TYPE_5 = 5; 187 188 /** 189 * In-pack object type: offset delta 190 * <p> 191 * Objects stored with this type actually have a different type which must 192 * be obtained from their delta base object. Delta objects store only the 193 * changes needed to apply to the base object in order to recover the 194 * original object. 195 * <p> 196 * An offset delta uses a negative offset from the start of this object to 197 * refer to its delta base. The base object must exist in this packfile 198 * (even in the case of a thin pack). 199 * <p> 200 * <b>This constant is fixed and is defined by the Git packfile format.</b> 201 */ 202 public static final int OBJ_OFS_DELTA = 6; 203 204 /** 205 * In-pack object type: reference delta 206 * <p> 207 * Objects stored with this type actually have a different type which must 208 * be obtained from their delta base object. Delta objects store only the 209 * changes needed to apply to the base object in order to recover the 210 * original object. 211 * <p> 212 * A reference delta uses a full object id (hash) to reference the delta 213 * base. The base object is allowed to be omitted from the packfile, but 214 * only in the case of a thin pack being transferred over the network. 215 * <p> 216 * <b>This constant is fixed and is defined by the Git packfile format.</b> 217 */ 218 public static final int OBJ_REF_DELTA = 7; 219 220 /** 221 * Pack file signature that occurs at file header - identifies file as Git 222 * packfile formatted. 223 * <p> 224 * <b>This constant is fixed and is defined by the Git packfile format.</b> 225 */ 226 public static final byte[] PACK_SIGNATURE = { 'P', 'A', 'C', 'K' }; 227 228 /** Native character encoding for commit messages, file names... */ 229 public static final String CHARACTER_ENCODING = "UTF-8"; 230 231 /** Native character encoding for commit messages, file names... */ 232 public static final Charset CHARSET; 233 234 /** Default main branch name */ 235 public static final String MASTER = "master"; 236 237 /** Default stash branch name */ 238 public static final String STASH = "stash"; 239 240 /** Prefix for branch refs */ 241 public static final String R_HEADS = "refs/heads/"; 242 243 /** Prefix for remotes refs */ 244 public static final String R_REMOTES = "refs/remotes/"; 245 246 /** Prefix for tag refs */ 247 public static final String R_TAGS = "refs/tags/"; 248 249 /** Prefix for notes refs */ 250 public static final String R_NOTES = "refs/notes/"; 251 252 /** Standard notes ref */ 253 public static final String R_NOTES_COMMITS = R_NOTES + "commits"; 254 255 /** Prefix for any ref */ 256 public static final String R_REFS = "refs/"; 257 258 /** Standard stash ref */ 259 public static final String R_STASH = R_REFS + STASH; 260 261 /** Logs folder name */ 262 public static final String LOGS = "logs"; 263 264 /** Info refs folder */ 265 public static final String INFO_REFS = "info/refs"; 266 267 /** Packed refs file */ 268 public static final String PACKED_REFS = "packed-refs"; 269 270 /** 271 * Excludes-file 272 * 273 * @since 3.0 274 */ 275 public static final String INFO_EXCLUDE = "info/exclude"; 276 277 /** 278 * Attributes-override-file 279 * 280 * @since 4.2 281 */ 282 public static final String INFO_ATTRIBUTES = "info/attributes"; 283 284 /** 285 * The system property that contains the system user name 286 * 287 * @since 3.6 288 */ 289 public static final String OS_USER_DIR = "user.dir"; 290 291 /** The system property that contains the system user name */ 292 public static final String OS_USER_NAME_KEY = "user.name"; 293 294 /** The environment variable that contains the author's name */ 295 public static final String GIT_AUTHOR_NAME_KEY = "GIT_AUTHOR_NAME"; 296 297 /** The environment variable that contains the author's email */ 298 public static final String GIT_AUTHOR_EMAIL_KEY = "GIT_AUTHOR_EMAIL"; 299 300 /** The environment variable that contains the commiter's name */ 301 public static final String GIT_COMMITTER_NAME_KEY = "GIT_COMMITTER_NAME"; 302 303 /** The environment variable that contains the commiter's email */ 304 public static final String GIT_COMMITTER_EMAIL_KEY = "GIT_COMMITTER_EMAIL"; 305 306 /** 307 * The environment variable that blocks use of the system config file 308 * 309 * @since 3.3 310 */ 311 public static final String GIT_CONFIG_NOSYSTEM_KEY = "GIT_CONFIG_NOSYSTEM"; 312 313 /** 314 * The environment variable that limits how close to the root of the file 315 * systems JGit will traverse when looking for a repository root. 316 */ 317 public static final String GIT_CEILING_DIRECTORIES_KEY = "GIT_CEILING_DIRECTORIES"; 318 319 /** 320 * The environment variable that tells us which directory is the ".git" 321 * directory 322 */ 323 public static final String GIT_DIR_KEY = "GIT_DIR"; 324 325 /** 326 * The environment variable that tells us which directory is the working 327 * directory. 328 */ 329 public static final String GIT_WORK_TREE_KEY = "GIT_WORK_TREE"; 330 331 /** 332 * The environment variable that tells us which file holds the Git index. 333 */ 334 public static final String GIT_INDEX_FILE_KEY = "GIT_INDEX_FILE"; 335 336 /** 337 * The environment variable that tells us where objects are stored 338 */ 339 public static final String GIT_OBJECT_DIRECTORY_KEY = "GIT_OBJECT_DIRECTORY"; 340 341 /** 342 * The environment variable that tells us where to look for objects, besides 343 * the default objects directory. 344 */ 345 public static final String GIT_ALTERNATE_OBJECT_DIRECTORIES_KEY = "GIT_ALTERNATE_OBJECT_DIRECTORIES"; 346 347 /** Default value for the user name if no other information is available */ 348 public static final String UNKNOWN_USER_DEFAULT = "unknown-user"; 349 350 /** Beginning of the common "Signed-off-by: " commit message line */ 351 public static final String SIGNED_OFF_BY_TAG = "Signed-off-by: "; 352 353 /** A gitignore file name */ 354 public static final String GITIGNORE_FILENAME = ".gitignore"; 355 356 /** Default remote name used by clone, push and fetch operations */ 357 public static final String DEFAULT_REMOTE_NAME = "origin"; 358 359 /** Default name for the Git repository directory */ 360 public static final String DOT_GIT = ".git"; 361 362 /** Default name for the Git repository configuration */ 363 public static final String CONFIG = "config"; 364 365 /** A bare repository typically ends with this string */ 366 public static final String DOT_GIT_EXT = ".git"; 367 368 /** 369 * Name of the attributes file 370 * 371 * @since 3.7 372 */ 373 public static final String DOT_GIT_ATTRIBUTES = ".gitattributes"; 374 375 /** 376 * Key for filters in .gitattributes 377 * 378 * @since 4.2 379 */ 380 public static final String ATTR_FILTER = "filter"; 381 382 /** 383 * clean command name, used to call filter driver 384 * 385 * @since 4.2 386 */ 387 public static final String ATTR_FILTER_TYPE_CLEAN = "clean"; 388 389 /** 390 * smudge command name, used to call filter driver 391 * 392 * @since 4.2 393 */ 394 public static final String ATTR_FILTER_TYPE_SMUDGE = "smudge"; 395 396 /** 397 * Builtin filter commands start with this prefix 398 * 399 * @since 4.6 400 */ 401 public static final String BUILTIN_FILTER_PREFIX = "jgit://builtin/"; 402 403 /** Name of the ignore file */ 404 public static final String DOT_GIT_IGNORE = ".gitignore"; 405 406 /** Name of the submodules file */ 407 public static final String DOT_GIT_MODULES = ".gitmodules"; 408 409 /** Name of the .git/shallow file */ 410 public static final String SHALLOW = "shallow"; 411 412 /** 413 * Prefix of the first line in a ".git" file 414 * 415 * @since 3.6 416 */ 417 public static final String GITDIR = "gitdir: "; 418 419 /** 420 * Name of the folder (inside gitDir) where submodules are stored 421 * 422 * @since 3.6 423 */ 424 public static final String MODULES = "modules"; 425 426 /** 427 * Name of the folder (inside gitDir) where the hooks are stored. 428 * 429 * @since 3.7 430 */ 431 public static final String HOOKS = "hooks"; 432 433 /** 434 * Merge attribute. 435 * 436 * @since 4.9 437 */ 438 public static final String ATTR_MERGE = "merge"; //$NON-NLS-1$ 439 440 /** 441 * Diff attribute. 442 * 443 * @since 4.11 444 */ 445 public static final String ATTR_DIFF = "diff"; //$NON-NLS-1$ 446 447 /** 448 * Binary value for custom merger. 449 * 450 * @since 4.9 451 */ 452 public static final String ATTR_BUILTIN_BINARY_MERGER = "binary"; //$NON-NLS-1$ 453 454 /** 455 * Create a new digest function for objects. 456 * 457 * @return a new digest object. 458 * @throws java.lang.RuntimeException 459 * this Java virtual machine does not support the required hash 460 * function. Very unlikely given that JGit uses a hash function 461 * that is in the Java reference specification. 462 */ 463 public static MessageDigest newMessageDigest() { 464 try { 465 return MessageDigest.getInstance(HASH_FUNCTION); 466 } catch (NoSuchAlgorithmException nsae) { 467 throw new RuntimeException(MessageFormat.format( 468 JGitText.get().requiredHashFunctionNotAvailable, HASH_FUNCTION), nsae); 469 } 470 } 471 472 /** 473 * Convert an OBJ_* type constant to a TYPE_* type constant. 474 * 475 * @param typeCode the type code, from a pack representation. 476 * @return the canonical string name of this type. 477 */ 478 public static String typeString(final int typeCode) { 479 switch (typeCode) { 480 case OBJ_COMMIT: 481 return TYPE_COMMIT; 482 case OBJ_TREE: 483 return TYPE_TREE; 484 case OBJ_BLOB: 485 return TYPE_BLOB; 486 case OBJ_TAG: 487 return TYPE_TAG; 488 default: 489 throw new IllegalArgumentException(MessageFormat.format( 490 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 491 } 492 } 493 494 /** 495 * Convert an OBJ_* type constant to an ASCII encoded string constant. 496 * <p> 497 * The ASCII encoded string is often the canonical representation of 498 * the type within a loose object header, or within a tag header. 499 * 500 * @param typeCode the type code, from a pack representation. 501 * @return the canonical ASCII encoded name of this type. 502 */ 503 public static byte[] encodedTypeString(final int typeCode) { 504 switch (typeCode) { 505 case OBJ_COMMIT: 506 return ENCODED_TYPE_COMMIT; 507 case OBJ_TREE: 508 return ENCODED_TYPE_TREE; 509 case OBJ_BLOB: 510 return ENCODED_TYPE_BLOB; 511 case OBJ_TAG: 512 return ENCODED_TYPE_TAG; 513 default: 514 throw new IllegalArgumentException(MessageFormat.format( 515 JGitText.get().badObjectType, Integer.valueOf(typeCode))); 516 } 517 } 518 519 /** 520 * Parse an encoded type string into a type constant. 521 * 522 * @param id 523 * object id this type string came from; may be null if that is 524 * not known at the time the parse is occurring. 525 * @param typeString 526 * string version of the type code. 527 * @param endMark 528 * character immediately following the type string. Usually ' ' 529 * (space) or '\n' (line feed). 530 * @param offset 531 * position within <code>typeString</code> where the parse 532 * should start. Updated with the new position (just past 533 * <code>endMark</code> when the parse is successful. 534 * @return a type code constant (one of {@link #OBJ_BLOB}, 535 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}. 536 * @throws org.eclipse.jgit.errors.CorruptObjectException 537 * there is no valid type identified by <code>typeString</code>. 538 */ 539 public static int decodeTypeString(final AnyObjectId id, 540 final byte[] typeString, final byte endMark, 541 final MutableInteger offset) throws CorruptObjectException { 542 try { 543 int position = offset.value; 544 switch (typeString[position]) { 545 case 'b': 546 if (typeString[position + 1] != 'l' 547 || typeString[position + 2] != 'o' 548 || typeString[position + 3] != 'b' 549 || typeString[position + 4] != endMark) 550 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 551 offset.value = position + 5; 552 return Constants.OBJ_BLOB; 553 554 case 'c': 555 if (typeString[position + 1] != 'o' 556 || typeString[position + 2] != 'm' 557 || typeString[position + 3] != 'm' 558 || typeString[position + 4] != 'i' 559 || typeString[position + 5] != 't' 560 || typeString[position + 6] != endMark) 561 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 562 offset.value = position + 7; 563 return Constants.OBJ_COMMIT; 564 565 case 't': 566 switch (typeString[position + 1]) { 567 case 'a': 568 if (typeString[position + 2] != 'g' 569 || typeString[position + 3] != endMark) 570 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 571 offset.value = position + 4; 572 return Constants.OBJ_TAG; 573 574 case 'r': 575 if (typeString[position + 2] != 'e' 576 || typeString[position + 3] != 'e' 577 || typeString[position + 4] != endMark) 578 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 579 offset.value = position + 5; 580 return Constants.OBJ_TREE; 581 582 default: 583 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 584 } 585 586 default: 587 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 588 } 589 } catch (ArrayIndexOutOfBoundsException bad) { 590 throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType); 591 } 592 } 593 594 /** 595 * Convert an integer into its decimal representation. 596 * 597 * @param s 598 * the integer to convert. 599 * @return a decimal representation of the input integer. The returned array 600 * is the smallest array that will hold the value. 601 */ 602 public static byte[] encodeASCII(final long s) { 603 return encodeASCII(Long.toString(s)); 604 } 605 606 /** 607 * Convert a string to US-ASCII encoding. 608 * 609 * @param s 610 * the string to convert. Must not contain any characters over 611 * 127 (outside of 7-bit ASCII). 612 * @return a byte array of the same length as the input string, holding the 613 * same characters, in the same order. 614 * @throws java.lang.IllegalArgumentException 615 * the input string contains one or more characters outside of 616 * the 7-bit ASCII character space. 617 */ 618 public static byte[] encodeASCII(final String s) { 619 final byte[] r = new byte[s.length()]; 620 for (int k = r.length - 1; k >= 0; k--) { 621 final char c = s.charAt(k); 622 if (c > 127) 623 throw new IllegalArgumentException(MessageFormat.format(JGitText.get().notASCIIString, s)); 624 r[k] = (byte) c; 625 } 626 return r; 627 } 628 629 /** 630 * Convert a string to a byte array in the standard character encoding. 631 * 632 * @param str 633 * the string to convert. May contain any Unicode characters. 634 * @return a byte array representing the requested string, encoded using the 635 * default character encoding (UTF-8). 636 * @see #CHARACTER_ENCODING 637 */ 638 public static byte[] encode(final String str) { 639 final ByteBuffer bb = Constants.CHARSET.encode(str); 640 final int len = bb.limit(); 641 if (bb.hasArray() && bb.arrayOffset() == 0) { 642 final byte[] arr = bb.array(); 643 if (arr.length == len) 644 return arr; 645 } 646 647 final byte[] arr = new byte[len]; 648 bb.get(arr); 649 return arr; 650 } 651 652 static { 653 if (OBJECT_ID_LENGTH != newMessageDigest().getDigestLength()) 654 throw new LinkageError(JGitText.get().incorrectOBJECT_ID_LENGTH); 655 CHARSET = Charset.forName(CHARACTER_ENCODING); 656 } 657 658 /** name of the file containing the commit msg for a merge commit */ 659 public static final String MERGE_MSG = "MERGE_MSG"; 660 661 /** name of the file containing the IDs of the parents of a merge commit */ 662 public static final String MERGE_HEAD = "MERGE_HEAD"; 663 664 /** name of the file containing the ID of a cherry pick commit in case of conflicts */ 665 public static final String CHERRY_PICK_HEAD = "CHERRY_PICK_HEAD"; 666 667 /** name of the file containing the commit msg for a squash commit */ 668 public static final String SQUASH_MSG = "SQUASH_MSG"; 669 670 /** name of the file containing the ID of a revert commit in case of conflicts */ 671 public static final String REVERT_HEAD = "REVERT_HEAD"; 672 673 /** 674 * name of the ref ORIG_HEAD used by certain commands to store the original 675 * value of HEAD 676 */ 677 public static final String ORIG_HEAD = "ORIG_HEAD"; 678 679 /** 680 * Name of the file in which git commands and hooks store and read the 681 * message prepared for the upcoming commit. 682 * 683 * @since 4.0 684 */ 685 public static final String COMMIT_EDITMSG = "COMMIT_EDITMSG"; 686 687 /** objectid for the empty blob */ 688 public static final ObjectId EMPTY_BLOB_ID = ObjectId 689 .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); 690 691 private Constants() { 692 // Hide the default constructor 693 } 694 }