Branch
Hash :
b43567d6
Author :
Date :
2022-07-13T22:25:11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_git_oid_h__
#define INCLUDE_git_oid_h__
#include "common.h"
#include "types.h"
#include "experimental.h"
/**
* @file git2/oid.h
* @brief Git object id routines
* @defgroup git_oid Git object id routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/** The type of object id. */
typedef enum {
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_OID_SHA1 = 1, /**< SHA1 */
GIT_OID_SHA256 = 2 /**< SHA256 */
#else
GIT_OID_SHA1 = 1 /**< SHA1 */
#endif
} git_oid_t;
/*
* SHA1 is currently the only supported object ID type.
*/
/** SHA1 is currently libgit2's default oid type. */
#define GIT_OID_DEFAULT GIT_OID_SHA1
/** Size (in bytes) of a raw/binary sha1 oid */
#define GIT_OID_SHA1_SIZE 20
/** Size (in bytes) of a hex formatted sha1 oid */
#define GIT_OID_SHA1_HEXSIZE (GIT_OID_SHA1_SIZE * 2)
/**
* The binary representation of the null sha1 object ID.
*/
#ifndef GIT_EXPERIMENTAL_SHA256
# define GIT_OID_SHA1_ZERO { { 0 } }
#else
# define GIT_OID_SHA1_ZERO { GIT_OID_SHA1, { 0 } }
#endif
/**
* The string representation of the null sha1 object ID.
*/
#define GIT_OID_SHA1_HEXZERO "0000000000000000000000000000000000000000"
/*
* Experimental SHA256 support is a breaking change to the API.
* This exists for application compatibility testing.
*/
#ifdef GIT_EXPERIMENTAL_SHA256
/** Size (in bytes) of a raw/binary sha256 oid */
# define GIT_OID_SHA256_SIZE 32
/** Size (in bytes) of a hex formatted sha256 oid */
# define GIT_OID_SHA256_HEXSIZE (GIT_OID_SHA256_SIZE * 2)
/**
* The binary representation of the null sha256 object ID.
*/
# define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } }
/**
* The string representation of the null sha256 object ID.
*/
# define GIT_OID_SHA256_HEXZERO "0000000000000000000000000000000000000000000000000000000000000000"
#endif
/* Maximum possible object ID size in raw / hex string format. */
#ifndef GIT_EXPERIMENTAL_SHA256
# define GIT_OID_MAX_SIZE GIT_OID_SHA1_SIZE
# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA1_HEXSIZE
#else
# define GIT_OID_MAX_SIZE GIT_OID_SHA256_SIZE
# define GIT_OID_MAX_HEXSIZE GIT_OID_SHA256_HEXSIZE
#endif
/** Minimum length (in number of hex characters,
* i.e. packets of 4 bits) of an oid prefix */
#define GIT_OID_MINPREFIXLEN 4
/** Unique identity of any object (commit, tree, blob, tag). */
typedef struct git_oid {
#ifdef GIT_EXPERIMENTAL_SHA256
/** type of object id */
unsigned char type;
#endif
/** raw binary formatted id */
unsigned char id[GIT_OID_MAX_SIZE];
} git_oid;
/**
* Parse a hex formatted object id into a git_oid.
*
* The appropriate number of bytes for the given object ID type will
* be read from the string - 40 bytes for SHA1, 64 bytes for SHA256.
* The given string need not be NUL terminated.
*
* @param out oid structure the result is written into.
* @param str input hex string; must be pointing at the start of
* the hex sequence and have at least the number of bytes
* needed for an oid encoded in hex (40 bytes for sha1,
* 256 bytes for sha256).
* @param type the type of object id
* @return 0 or an error code
*/
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str, git_oid_t type);
#else
GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str);
#endif
/**
* Parse a hex formatted NUL-terminated string into a git_oid.
*
* @param out oid structure the result is written into.
* @param str input hex string; must be null-terminated.
* @param type the type of object id
* @return 0 or an error code
*/
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str, git_oid_t type);
#else
GIT_EXTERN(int) git_oid_fromstrp(git_oid *out, const char *str);
#endif
/**
* Parse N characters of a hex formatted object id into a git_oid.
*
* If N is odd, the last byte's high nibble will be read in and the
* low nibble set to zero.
*
* @param out oid structure the result is written into.
* @param str input hex string of at least size `length`
* @param length length of the input string
* @param type the type of object id
* @return 0 or an error code
*/
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length, git_oid_t type);
#else
GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length);
#endif
/**
* Copy an already raw oid into a git_oid structure.
*
* @param out oid structure the result is written into.
* @param raw the raw input bytes to be copied.
* @return 0 on success or error code
*/
#ifdef GIT_EXPERIMENTAL_SHA256
GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw, git_oid_t type);
#else
GIT_EXTERN(int) git_oid_fromraw(git_oid *out, const unsigned char *raw);
#endif
/**
* Format a git_oid into a hex string.
*
* @param out output hex string; must be pointing at the start of
* the hex sequence and have at least the number of bytes
* needed for an oid encoded in hex (40 bytes for SHA1,
* 64 bytes for SHA256). Only the oid digits are written;
* a '\\0' terminator must be added by the caller if it is
* required.
* @param id oid structure to format.
* @return 0 on success or error code
*/
GIT_EXTERN(int) git_oid_fmt(char *out, const git_oid *id);
/**
* Format a git_oid into a partial hex string.
*
* @param out output hex string; you say how many bytes to write.
* If the number of bytes is > GIT_OID_SHA1_HEXSIZE, extra bytes
* will be zeroed; if not, a '\0' terminator is NOT added.
* @param n number of characters to write into out string
* @param id oid structure to format.
* @return 0 on success or error code
*/
GIT_EXTERN(int) git_oid_nfmt(char *out, size_t n, const git_oid *id);
/**
* Format a git_oid into a loose-object path string.
*
* The resulting string is "aa/...", where "aa" is the first two
* hex digits of the oid and "..." is the remaining 38 digits.
*
* @param out output hex string; must be pointing at the start of
* the hex sequence and have at least the number of bytes
* needed for an oid encoded in hex (41 bytes for SHA1,
* 65 bytes for SHA256). Only the oid digits are written;
* a '\\0' terminator must be added by the caller if it
* is required.
* @param id oid structure to format.
* @return 0 on success, non-zero callback return value, or error code
*/
GIT_EXTERN(int) git_oid_pathfmt(char *out, const git_oid *id);
/**
* Format a git_oid into a statically allocated c-string.
*
* The c-string is owned by the library and should not be freed
* by the user. If libgit2 is built with thread support, the string
* will be stored in TLS (i.e. one buffer per thread) to allow for
* concurrent calls of the function.
*
* @param oid The oid structure to format
* @return the c-string
*/
GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
/**
* Format a git_oid into a buffer as a hex format c-string.
*
* If the buffer is smaller than the size of a hex-formatted oid string
* plus an additional byte (GIT_OID_SHA_HEXSIZE + 1 for SHA1 or
* GIT_OID_SHA256_HEXSIZE + 1 for SHA256), then the resulting
* oid c-string will be truncated to n-1 characters (but will still be
* NUL-byte terminated).
*
* If there are any input parameter errors (out == NULL, n == 0, oid ==
* NULL), then a pointer to an empty string is returned, so that the
* return value can always be printed.
*
* @param out the buffer into which the oid string is output.
* @param n the size of the out buffer.
* @param id the oid structure to format.
* @return the out buffer pointer, assuming no input parameter
* errors, otherwise a pointer to an empty string.
*/
GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *id);
/**
* Copy an oid from one structure to another.
*
* @param out oid structure the result is written into.
* @param src oid structure to copy from.
* @return 0 on success or error code
*/
GIT_EXTERN(int) git_oid_cpy(git_oid *out, const git_oid *src);
/**
* Compare two oid structures.
*
* @param a first oid structure.
* @param b second oid structure.
* @return <0, 0, >0 if a < b, a == b, a > b.
*/
GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
/**
* Compare two oid structures for equality
*
* @param a first oid structure.
* @param b second oid structure.
* @return true if equal, false otherwise
*/
GIT_EXTERN(int) git_oid_equal(const git_oid *a, const git_oid *b);
/**
* Compare the first 'len' hexadecimal characters (packets of 4 bits)
* of two oid structures.
*
* @param a first oid structure.
* @param b second oid structure.
* @param len the number of hex chars to compare
* @return 0 in case of a match
*/
GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len);
/**
* Check if an oid equals an hex formatted object id.
*
* @param id oid structure.
* @param str input hex string of an object id.
* @return 0 in case of a match, -1 otherwise.
*/
GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str);
/**
* Compare an oid to an hex formatted object id.
*
* @param id oid structure.
* @param str input hex string of an object id.
* @return -1 if str is not valid, <0 if id sorts before str,
* 0 if id matches str, >0 if id sorts after str.
*/
GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str);
/**
* Check is an oid is all zeros.
*
* @return 1 if all zeros, 0 otherwise.
*/
GIT_EXTERN(int) git_oid_is_zero(const git_oid *id);
/**
* OID Shortener object
*/
typedef struct git_oid_shorten git_oid_shorten;
/**
* Create a new OID shortener.
*
* The OID shortener is used to process a list of OIDs
* in text form and return the shortest length that would
* uniquely identify all of them.
*
* E.g. look at the result of `git log --abbrev`.
*
* @param min_length The minimal length for all identifiers,
* which will be used even if shorter OIDs would still
* be unique.
* @return a `git_oid_shorten` instance, NULL if OOM
*/
GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
/**
* Add a new OID to set of shortened OIDs and calculate
* the minimal length to uniquely identify all the OIDs in
* the set.
*
* The OID is expected to be a 40-char hexadecimal string.
* The OID is owned by the user and will not be modified
* or freed.
*
* For performance reasons, there is a hard-limit of how many
* OIDs can be added to a single set (around ~32000, assuming
* a mostly randomized distribution), which should be enough
* for any kind of program, and keeps the algorithm fast and
* memory-efficient.
*
* Attempting to add more than those OIDs will result in a
* GIT_ERROR_INVALID error
*
* @param os a `git_oid_shorten` instance
* @param text_id an OID in text form
* @return the minimal length to uniquely identify all OIDs
* added so far to the set; or an error code (<0) if an
* error occurs.
*/
GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_id);
/**
* Free an OID shortener instance
*
* @param os a `git_oid_shorten` instance
*/
GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os);
/** @} */
GIT_END_DECL
#endif