]> git.ipfire.org Git - thirdparty/git.git/commitdiff
hash-ll: merge with "hash.h"
authorPatrick Steinhardt <ps@pks.im>
Fri, 14 Jun 2024 06:50:32 +0000 (08:50 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 14 Jun 2024 17:26:33 +0000 (10:26 -0700)
The "hash-ll.h" header was introduced via d1cbe1e6d8 (hash-ll.h: split
out of hash.h to remove dependency on repository.h, 2023-04-22) to make
explicit the split between hash-related functions that rely on the
global `the_repository`, and those that don't. This split is no longer
necessary now that we we have removed the reliance on `the_repository`.

Merge "hash-ll.h" back into "hash.h". This causes some code units to not
include "repository.h" anymore, which requires us to add some forward
declarations.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
39 files changed:
apply.h
bloom.c
checkout.h
chunk-format.h
commit-graph.h
compat/sha1-chunked.c
convert.h
csum-file.h
diff.h
diffcore.h
dir.h
hash-ll.h [deleted file]
hash.h
hex.h
loose.h
merge-ort.h
object-file-convert.c
object.h
oidmap.h
oidtree.h
packfile.h
protocol-caps.c
read-cache-ll.h
refs/ref-cache.h
reftable/dump.c
reftable/reftable-record.h
reftable/system.h
remote.h
reset.h
resolve-undo.h
serve.c
split-index.h
t/helper/test-hash-speed.c
t/helper/test-sha1.c
t/helper/test-sha256.c
t/unit-tests/lib-oid.h
tree-diff.c
tree-walk.h
xdiff-interface.h

diff --git a/apply.h b/apply.h
index 7cd38b1443c67e448bdc9f004f94a841a12eb747..b9f18ce87d1e0374a04aaaf785592c752dba6058 100644 (file)
--- a/apply.h
+++ b/apply.h
@@ -1,7 +1,7 @@
 #ifndef APPLY_H
 #define APPLY_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "lockfile.h"
 #include "string-list.h"
 #include "strmap.h"
diff --git a/bloom.c b/bloom.c
index e529f7605ca14d3fcb779412fc22e1e20d45ac20..bbf146fc30c7e8ddfa56074a5af2770129e2d57a 100644 (file)
--- a/bloom.c
+++ b/bloom.c
@@ -6,6 +6,7 @@
 #include "commit-graph.h"
 #include "commit.h"
 #include "commit-slab.h"
+#include "repository.h"
 
 define_commit_slab(bloom_filter_slab, struct bloom_filter);
 
index ba15a13fb35be65e8c4b90fb87751f294105176e..55920e7aeb243d586bc523c41157dd41c58f148c 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef CHECKOUT_H
 #define CHECKOUT_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 /*
  * Check if the branch name uniquely matches a branch name on a remote
index 14b76180ef768f6b5c38aa1cda128ab87d2327ae..212a0a6af18356b140feed758eceb89bdd105e14 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef CHUNK_FORMAT_H
 #define CHUNK_FORMAT_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct hashfile;
 struct chunkfile;
index e519cb81cb649dd016fdb5f26dbfd3623ead13e9..6781940195435dc89c0b5d28bd2518e5ee0f1194 100644 (file)
@@ -122,6 +122,8 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
 struct commit_graph *read_commit_graph_one(struct repository *r,
                                           struct object_directory *odb);
 
+struct repo_settings;
+
 /*
  * Callers should initialize the repo_settings with prepare_repo_settings()
  * prior to calling parse_commit_graph().
index a4a6f930d7b14a473d5e47a9a90b84a7557054af..0446f9983f2ca16de3d7bf2549e4d923cba38b2d 100644 (file)
@@ -1,5 +1,5 @@
 #include "git-compat-util.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)
 {
index d925589444b90a11058abe87286df3d5add592f8..0a6e4086b8f93257df513a20a4cc55062d218212 100644 (file)
--- a/convert.h
+++ b/convert.h
@@ -4,7 +4,7 @@
 #ifndef CONVERT_H
 #define CONVERT_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "string-list.h"
 
 struct index_state;
index bc5bec27acbab4a3303f4ea11575b0c1accda806..566e05cbd25a04be9977356e3cfb5a77637bf4c8 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef CSUM_FILE_H
 #define CSUM_FILE_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "write-or-die.h"
 
 struct progress;
diff --git a/diff.h b/diff.h
index 66bd8aeb2936fbe9d6610f7dc1202e31e1450ebb..9901c8ca8c8e49346ee0945271c005385d88d059 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -4,7 +4,7 @@
 #ifndef DIFF_H
 #define DIFF_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "pathspec.h"
 #include "strbuf.h"
 
index 5ffe4ec788f84044df42b13eb847dec1f4e1fd36..1701ed50b9c823ffc5f06b299b92eafc7ea477a3 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef DIFFCORE_H
 #define DIFFCORE_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct diff_options;
 struct mem_pool;
diff --git a/dir.h b/dir.h
index 1398a53fb4e9b1d854cdc3c6e69586f15dfd1e9e..69a76d8bdd30a3c0e5108780a69c55eeca6e5dbe 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -1,7 +1,7 @@
 #ifndef DIR_H
 #define DIR_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "hashmap.h"
 #include "pathspec.h"
 #include "statinfo.h"
diff --git a/hash-ll.h b/hash-ll.h
deleted file mode 100644 (file)
index 3161c77..0000000
--- a/hash-ll.h
+++ /dev/null
@@ -1,364 +0,0 @@
-#ifndef HASH_LL_H
-#define HASH_LL_H
-
-#if defined(SHA1_APPLE)
-#include <CommonCrypto/CommonDigest.h>
-#elif defined(SHA1_OPENSSL)
-#  include <openssl/sha.h>
-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
-#    define SHA1_NEEDS_CLONE_HELPER
-#    include "sha1/openssl.h"
-#  endif
-#elif defined(SHA1_DC)
-#include "sha1dc_git.h"
-#else /* SHA1_BLK */
-#include "block-sha1/sha1.h"
-#endif
-
-#if defined(SHA256_NETTLE)
-#include "sha256/nettle.h"
-#elif defined(SHA256_GCRYPT)
-#define SHA256_NEEDS_CLONE_HELPER
-#include "sha256/gcrypt.h"
-#elif defined(SHA256_OPENSSL)
-#  include <openssl/sha.h>
-#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
-#    define SHA256_NEEDS_CLONE_HELPER
-#    include "sha256/openssl.h"
-#  endif
-#else
-#include "sha256/block/sha256.h"
-#endif
-
-#ifndef platform_SHA_CTX
-/*
- * platform's underlying implementation of SHA-1; could be OpenSSL,
- * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant
- * SHA-1 header may have already defined platform_SHA_CTX for our
- * own implementations like block-sha1, so we list
- * the default for OpenSSL compatible SHA-1 implementations here.
- */
-#define platform_SHA_CTX       SHA_CTX
-#define platform_SHA1_Init     SHA1_Init
-#define platform_SHA1_Update   SHA1_Update
-#define platform_SHA1_Final            SHA1_Final
-#endif
-
-#define git_SHA_CTX            platform_SHA_CTX
-#define git_SHA1_Init          platform_SHA1_Init
-#define git_SHA1_Update                platform_SHA1_Update
-#define git_SHA1_Final         platform_SHA1_Final
-
-#ifdef platform_SHA1_Clone
-#define git_SHA1_Clone platform_SHA1_Clone
-#endif
-
-#ifndef platform_SHA256_CTX
-#define platform_SHA256_CTX    SHA256_CTX
-#define platform_SHA256_Init   SHA256_Init
-#define platform_SHA256_Update SHA256_Update
-#define platform_SHA256_Final  SHA256_Final
-#endif
-
-#define git_SHA256_CTX         platform_SHA256_CTX
-#define git_SHA256_Init                platform_SHA256_Init
-#define git_SHA256_Update      platform_SHA256_Update
-#define git_SHA256_Final       platform_SHA256_Final
-
-#ifdef platform_SHA256_Clone
-#define git_SHA256_Clone       platform_SHA256_Clone
-#endif
-
-#ifdef SHA1_MAX_BLOCK_SIZE
-#include "compat/sha1-chunked.h"
-#undef git_SHA1_Update
-#define git_SHA1_Update                git_SHA1_Update_Chunked
-#endif
-
-#ifndef SHA1_NEEDS_CLONE_HELPER
-static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
-{
-       memcpy(dst, src, sizeof(*dst));
-}
-#endif
-
-#ifndef SHA256_NEEDS_CLONE_HELPER
-static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
-{
-       memcpy(dst, src, sizeof(*dst));
-}
-#endif
-
-/*
- * Note that these constants are suitable for indexing the hash_algos array and
- * comparing against each other, but are otherwise arbitrary, so they should not
- * be exposed to the user or serialized to disk.  To know whether a
- * git_hash_algo struct points to some usable hash function, test the format_id
- * field for being non-zero.  Use the name field for user-visible situations and
- * the format_id field for fixed-length fields on disk.
- */
-/* An unknown hash function. */
-#define GIT_HASH_UNKNOWN 0
-/* SHA-1 */
-#define GIT_HASH_SHA1 1
-/* SHA-256  */
-#define GIT_HASH_SHA256 2
-/* Number of algorithms supported (including unknown). */
-#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
-
-/* "sha1", big-endian */
-#define GIT_SHA1_FORMAT_ID 0x73686131
-
-/* The length in bytes and in hex digits of an object name (SHA-1 value). */
-#define GIT_SHA1_RAWSZ 20
-#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
-/* The block size of SHA-1. */
-#define GIT_SHA1_BLKSZ 64
-
-/* "s256", big-endian */
-#define GIT_SHA256_FORMAT_ID 0x73323536
-
-/* The length in bytes and in hex digits of an object name (SHA-256 value). */
-#define GIT_SHA256_RAWSZ 32
-#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
-/* The block size of SHA-256. */
-#define GIT_SHA256_BLKSZ 64
-
-/* The length in byte and in hex digits of the largest possible hash value. */
-#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
-#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
-/* The largest possible block size for any supported hash. */
-#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
-
-struct object_id {
-       unsigned char hash[GIT_MAX_RAWSZ];
-       int algo;       /* XXX requires 4-byte alignment */
-};
-
-#define GET_OID_QUIETLY           01
-#define GET_OID_COMMIT            02
-#define GET_OID_COMMITTISH        04
-#define GET_OID_TREE             010
-#define GET_OID_TREEISH          020
-#define GET_OID_BLOB             040
-#define GET_OID_FOLLOW_SYMLINKS 0100
-#define GET_OID_RECORD_PATH     0200
-#define GET_OID_ONLY_TO_DIE    04000
-#define GET_OID_REQUIRE_PATH  010000
-#define GET_OID_HASH_ANY      020000
-
-#define GET_OID_DISAMBIGUATORS \
-       (GET_OID_COMMIT | GET_OID_COMMITTISH | \
-       GET_OID_TREE | GET_OID_TREEISH | \
-       GET_OID_BLOB)
-
-enum get_oid_result {
-       FOUND = 0,
-       MISSING_OBJECT = -1, /* The requested object is missing */
-       SHORT_NAME_AMBIGUOUS = -2,
-       /* The following only apply when symlinks are followed */
-       DANGLING_SYMLINK = -4, /*
-                               * The initial symlink is there, but
-                               * (transitively) points to a missing
-                               * in-tree file
-                               */
-       SYMLINK_LOOP = -5,
-       NOT_DIR = -6, /*
-                      * Somewhere along the symlink chain, a path is
-                      * requested which contains a file as a
-                      * non-final element.
-                      */
-};
-
-/* A suitably aligned type for stack allocations of hash contexts. */
-union git_hash_ctx {
-       git_SHA_CTX sha1;
-       git_SHA256_CTX sha256;
-};
-typedef union git_hash_ctx git_hash_ctx;
-
-typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
-typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
-typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
-typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
-typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
-
-struct git_hash_algo {
-       /*
-        * The name of the algorithm, as appears in the config file and in
-        * messages.
-        */
-       const char *name;
-
-       /* A four-byte version identifier, used in pack indices. */
-       uint32_t format_id;
-
-       /* The length of the hash in binary. */
-       size_t rawsz;
-
-       /* The length of the hash in hex characters. */
-       size_t hexsz;
-
-       /* The block size of the hash. */
-       size_t blksz;
-
-       /* The hash initialization function. */
-       git_hash_init_fn init_fn;
-
-       /* The hash context cloning function. */
-       git_hash_clone_fn clone_fn;
-
-       /* The hash update function. */
-       git_hash_update_fn update_fn;
-
-       /* The hash finalization function. */
-       git_hash_final_fn final_fn;
-
-       /* The hash finalization function for object IDs. */
-       git_hash_final_oid_fn final_oid_fn;
-
-       /* The OID of the empty tree. */
-       const struct object_id *empty_tree;
-
-       /* The OID of the empty blob. */
-       const struct object_id *empty_blob;
-
-       /* The all-zeros OID. */
-       const struct object_id *null_oid;
-};
-extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
-
-/*
- * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if
- * the name doesn't match a known algorithm.
- */
-int hash_algo_by_name(const char *name);
-/* Identical, except based on the format ID. */
-int hash_algo_by_id(uint32_t format_id);
-/* Identical, except based on the length. */
-int hash_algo_by_length(int len);
-/* Identical, except for a pointer to struct git_hash_algo. */
-static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
-{
-       return p - hash_algos;
-}
-
-const struct object_id *null_oid(void);
-
-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
-{
-       /*
-        * Teach the compiler that there are only two possibilities of hash size
-        * here, so that it can optimize for this case as much as possible.
-        */
-       if (algop->rawsz == GIT_MAX_RAWSZ)
-               return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
-       return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
-}
-
-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
-{
-       /*
-        * We write this here instead of deferring to hashcmp so that the
-        * compiler can properly inline it and avoid calling memcmp.
-        */
-       if (algop->rawsz == GIT_MAX_RAWSZ)
-               return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
-       return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
-}
-
-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,
-                          const struct git_hash_algo *algop)
-{
-       memcpy(sha_dst, sha_src, algop->rawsz);
-}
-
-static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)
-{
-       memset(hash, 0, algop->rawsz);
-}
-
-static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
-{
-       return memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
-}
-
-static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
-{
-       return !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
-}
-
-static inline void oidcpy(struct object_id *dst, const struct object_id *src)
-{
-       memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
-       dst->algo = src->algo;
-}
-
-static inline void oidread(struct object_id *oid, const unsigned char *hash,
-                          const struct git_hash_algo *algop)
-{
-       memcpy(oid->hash, hash, algop->rawsz);
-       if (algop->rawsz < GIT_MAX_RAWSZ)
-               memset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);
-       oid->algo = hash_algo_by_ptr(algop);
-}
-
-static inline void oidclr(struct object_id *oid,
-                         const struct git_hash_algo *algop)
-{
-       memset(oid->hash, 0, GIT_MAX_RAWSZ);
-       oid->algo = hash_algo_by_ptr(algop);
-}
-
-static inline struct object_id *oiddup(const struct object_id *src)
-{
-       struct object_id *dst = xmalloc(sizeof(struct object_id));
-       oidcpy(dst, src);
-       return dst;
-}
-
-static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)
-{
-       oid->algo = hash_algo_by_ptr(algop);
-}
-
-/*
- * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
- * for use in hash tables. Cryptographic hashes are supposed to have
- * uniform distribution, so in contrast to `memhash()`, this just copies
- * the first `sizeof(int)` bytes without shuffling any bits. Note that
- * the results will be different on big-endian and little-endian
- * platforms, so they should not be stored or transferred over the net.
- */
-static inline unsigned int oidhash(const struct object_id *oid)
-{
-       /*
-        * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on
-        * platforms that don't support unaligned reads.
-        */
-       unsigned int hash;
-       memcpy(&hash, oid->hash, sizeof(hash));
-       return hash;
-}
-
-static inline int is_null_oid(const struct object_id *oid)
-{
-       static const unsigned char null_hash[GIT_MAX_RAWSZ];
-       return !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);
-}
-
-const char *empty_tree_oid_hex(const struct git_hash_algo *algop);
-
-static inline int is_empty_blob_oid(const struct object_id *oid,
-                                   const struct git_hash_algo *algop)
-{
-       return oideq(oid, algop->empty_blob);
-}
-
-static inline int is_empty_tree_oid(const struct object_id *oid,
-                                   const struct git_hash_algo *algop)
-{
-       return oideq(oid, algop->empty_tree);
-}
-
-#endif
diff --git a/hash.h b/hash.h
index cb85d26a2f0d3638997cc2911b63a55dbba75124..72ffbc862e557a542c49e9afe9b7fb709d32b0a1 100644 (file)
--- a/hash.h
+++ b/hash.h
 #ifndef HASH_H
 #define HASH_H
 
-#include "hash-ll.h"
-#include "repository.h"
+#if defined(SHA1_APPLE)
+#include <CommonCrypto/CommonDigest.h>
+#elif defined(SHA1_OPENSSL)
+#  include <openssl/sha.h>
+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
+#    define SHA1_NEEDS_CLONE_HELPER
+#    include "sha1/openssl.h"
+#  endif
+#elif defined(SHA1_DC)
+#include "sha1dc_git.h"
+#else /* SHA1_BLK */
+#include "block-sha1/sha1.h"
+#endif
+
+#if defined(SHA256_NETTLE)
+#include "sha256/nettle.h"
+#elif defined(SHA256_GCRYPT)
+#define SHA256_NEEDS_CLONE_HELPER
+#include "sha256/gcrypt.h"
+#elif defined(SHA256_OPENSSL)
+#  include <openssl/sha.h>
+#  if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3
+#    define SHA256_NEEDS_CLONE_HELPER
+#    include "sha256/openssl.h"
+#  endif
+#else
+#include "sha256/block/sha256.h"
+#endif
+
+#ifndef platform_SHA_CTX
+/*
+ * platform's underlying implementation of SHA-1; could be OpenSSL,
+ * blk_SHA, Apple CommonCrypto, etc...  Note that the relevant
+ * SHA-1 header may have already defined platform_SHA_CTX for our
+ * own implementations like block-sha1, so we list
+ * the default for OpenSSL compatible SHA-1 implementations here.
+ */
+#define platform_SHA_CTX       SHA_CTX
+#define platform_SHA1_Init     SHA1_Init
+#define platform_SHA1_Update   SHA1_Update
+#define platform_SHA1_Final            SHA1_Final
+#endif
+
+#define git_SHA_CTX            platform_SHA_CTX
+#define git_SHA1_Init          platform_SHA1_Init
+#define git_SHA1_Update                platform_SHA1_Update
+#define git_SHA1_Final         platform_SHA1_Final
+
+#ifdef platform_SHA1_Clone
+#define git_SHA1_Clone platform_SHA1_Clone
+#endif
+
+#ifndef platform_SHA256_CTX
+#define platform_SHA256_CTX    SHA256_CTX
+#define platform_SHA256_Init   SHA256_Init
+#define platform_SHA256_Update SHA256_Update
+#define platform_SHA256_Final  SHA256_Final
+#endif
+
+#define git_SHA256_CTX         platform_SHA256_CTX
+#define git_SHA256_Init                platform_SHA256_Init
+#define git_SHA256_Update      platform_SHA256_Update
+#define git_SHA256_Final       platform_SHA256_Final
+
+#ifdef platform_SHA256_Clone
+#define git_SHA256_Clone       platform_SHA256_Clone
+#endif
+
+#ifdef SHA1_MAX_BLOCK_SIZE
+#include "compat/sha1-chunked.h"
+#undef git_SHA1_Update
+#define git_SHA1_Update                git_SHA1_Update_Chunked
+#endif
+
+#ifndef SHA1_NEEDS_CLONE_HELPER
+static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
+{
+       memcpy(dst, src, sizeof(*dst));
+}
+#endif
+
+#ifndef SHA256_NEEDS_CLONE_HELPER
+static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
+{
+       memcpy(dst, src, sizeof(*dst));
+}
+#endif
+
+/*
+ * Note that these constants are suitable for indexing the hash_algos array and
+ * comparing against each other, but are otherwise arbitrary, so they should not
+ * be exposed to the user or serialized to disk.  To know whether a
+ * git_hash_algo struct points to some usable hash function, test the format_id
+ * field for being non-zero.  Use the name field for user-visible situations and
+ * the format_id field for fixed-length fields on disk.
+ */
+/* An unknown hash function. */
+#define GIT_HASH_UNKNOWN 0
+/* SHA-1 */
+#define GIT_HASH_SHA1 1
+/* SHA-256  */
+#define GIT_HASH_SHA256 2
+/* Number of algorithms supported (including unknown). */
+#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
+
+/* "sha1", big-endian */
+#define GIT_SHA1_FORMAT_ID 0x73686131
+
+/* The length in bytes and in hex digits of an object name (SHA-1 value). */
+#define GIT_SHA1_RAWSZ 20
+#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
+/* The block size of SHA-1. */
+#define GIT_SHA1_BLKSZ 64
+
+/* "s256", big-endian */
+#define GIT_SHA256_FORMAT_ID 0x73323536
+
+/* The length in bytes and in hex digits of an object name (SHA-256 value). */
+#define GIT_SHA256_RAWSZ 32
+#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
+/* The block size of SHA-256. */
+#define GIT_SHA256_BLKSZ 64
+
+/* The length in byte and in hex digits of the largest possible hash value. */
+#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
+#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
+/* The largest possible block size for any supported hash. */
+#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
+
+struct object_id {
+       unsigned char hash[GIT_MAX_RAWSZ];
+       int algo;       /* XXX requires 4-byte alignment */
+};
+
+#define GET_OID_QUIETLY           01
+#define GET_OID_COMMIT            02
+#define GET_OID_COMMITTISH        04
+#define GET_OID_TREE             010
+#define GET_OID_TREEISH          020
+#define GET_OID_BLOB             040
+#define GET_OID_FOLLOW_SYMLINKS 0100
+#define GET_OID_RECORD_PATH     0200
+#define GET_OID_ONLY_TO_DIE    04000
+#define GET_OID_REQUIRE_PATH  010000
+#define GET_OID_HASH_ANY      020000
+
+#define GET_OID_DISAMBIGUATORS \
+       (GET_OID_COMMIT | GET_OID_COMMITTISH | \
+       GET_OID_TREE | GET_OID_TREEISH | \
+       GET_OID_BLOB)
+
+enum get_oid_result {
+       FOUND = 0,
+       MISSING_OBJECT = -1, /* The requested object is missing */
+       SHORT_NAME_AMBIGUOUS = -2,
+       /* The following only apply when symlinks are followed */
+       DANGLING_SYMLINK = -4, /*
+                               * The initial symlink is there, but
+                               * (transitively) points to a missing
+                               * in-tree file
+                               */
+       SYMLINK_LOOP = -5,
+       NOT_DIR = -6, /*
+                      * Somewhere along the symlink chain, a path is
+                      * requested which contains a file as a
+                      * non-final element.
+                      */
+};
 
 #ifdef USE_THE_REPOSITORY_VARIABLE
+# include "repository.h"
 # define the_hash_algo the_repository->hash_algo
 #endif
 
+/* A suitably aligned type for stack allocations of hash contexts. */
+union git_hash_ctx {
+       git_SHA_CTX sha1;
+       git_SHA256_CTX sha256;
+};
+typedef union git_hash_ctx git_hash_ctx;
+
+typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
+typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
+typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
+typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
+typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
+
+struct git_hash_algo {
+       /*
+        * The name of the algorithm, as appears in the config file and in
+        * messages.
+        */
+       const char *name;
+
+       /* A four-byte version identifier, used in pack indices. */
+       uint32_t format_id;
+
+       /* The length of the hash in binary. */
+       size_t rawsz;
+
+       /* The length of the hash in hex characters. */
+       size_t hexsz;
+
+       /* The block size of the hash. */
+       size_t blksz;
+
+       /* The hash initialization function. */
+       git_hash_init_fn init_fn;
+
+       /* The hash context cloning function. */
+       git_hash_clone_fn clone_fn;
+
+       /* The hash update function. */
+       git_hash_update_fn update_fn;
+
+       /* The hash finalization function. */
+       git_hash_final_fn final_fn;
+
+       /* The hash finalization function for object IDs. */
+       git_hash_final_oid_fn final_oid_fn;
+
+       /* The OID of the empty tree. */
+       const struct object_id *empty_tree;
+
+       /* The OID of the empty blob. */
+       const struct object_id *empty_blob;
+
+       /* The all-zeros OID. */
+       const struct object_id *null_oid;
+};
+extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
+
+/*
+ * Return a GIT_HASH_* constant based on the name.  Returns GIT_HASH_UNKNOWN if
+ * the name doesn't match a known algorithm.
+ */
+int hash_algo_by_name(const char *name);
+/* Identical, except based on the format ID. */
+int hash_algo_by_id(uint32_t format_id);
+/* Identical, except based on the length. */
+int hash_algo_by_length(int len);
+/* Identical, except for a pointer to struct git_hash_algo. */
+static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
+{
+       return p - hash_algos;
+}
+
+const struct object_id *null_oid(void);
+
+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
+{
+       /*
+        * Teach the compiler that there are only two possibilities of hash size
+        * here, so that it can optimize for this case as much as possible.
+        */
+       if (algop->rawsz == GIT_MAX_RAWSZ)
+               return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
+       return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
+}
+
+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
+{
+       /*
+        * We write this here instead of deferring to hashcmp so that the
+        * compiler can properly inline it and avoid calling memcmp.
+        */
+       if (algop->rawsz == GIT_MAX_RAWSZ)
+               return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
+       return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
+}
+
+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,
+                          const struct git_hash_algo *algop)
+{
+       memcpy(sha_dst, sha_src, algop->rawsz);
+}
+
+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)
+{
+       memset(hash, 0, algop->rawsz);
+}
+
+static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
+{
+       return memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
+}
+
+static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
+{
+       return !memcmp(oid1->hash, oid2->hash, GIT_MAX_RAWSZ);
+}
+
+static inline void oidcpy(struct object_id *dst, const struct object_id *src)
+{
+       memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
+       dst->algo = src->algo;
+}
+
+static inline void oidread(struct object_id *oid, const unsigned char *hash,
+                          const struct git_hash_algo *algop)
+{
+       memcpy(oid->hash, hash, algop->rawsz);
+       if (algop->rawsz < GIT_MAX_RAWSZ)
+               memset(oid->hash + algop->rawsz, 0, GIT_MAX_RAWSZ - algop->rawsz);
+       oid->algo = hash_algo_by_ptr(algop);
+}
+
+static inline void oidclr(struct object_id *oid,
+                         const struct git_hash_algo *algop)
+{
+       memset(oid->hash, 0, GIT_MAX_RAWSZ);
+       oid->algo = hash_algo_by_ptr(algop);
+}
+
+static inline struct object_id *oiddup(const struct object_id *src)
+{
+       struct object_id *dst = xmalloc(sizeof(struct object_id));
+       oidcpy(dst, src);
+       return dst;
+}
+
+static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)
+{
+       oid->algo = hash_algo_by_ptr(algop);
+}
+
+/*
+ * Converts a cryptographic hash (e.g. SHA-1) into an int-sized hash code
+ * for use in hash tables. Cryptographic hashes are supposed to have
+ * uniform distribution, so in contrast to `memhash()`, this just copies
+ * the first `sizeof(int)` bytes without shuffling any bits. Note that
+ * the results will be different on big-endian and little-endian
+ * platforms, so they should not be stored or transferred over the net.
+ */
+static inline unsigned int oidhash(const struct object_id *oid)
+{
+       /*
+        * Equivalent to 'return *(unsigned int *)oid->hash;', but safe on
+        * platforms that don't support unaligned reads.
+        */
+       unsigned int hash;
+       memcpy(&hash, oid->hash, sizeof(hash));
+       return hash;
+}
+
+static inline int is_null_oid(const struct object_id *oid)
+{
+       static const unsigned char null_hash[GIT_MAX_RAWSZ];
+       return !memcmp(oid->hash, null_hash, GIT_MAX_RAWSZ);
+}
+
+const char *empty_tree_oid_hex(const struct git_hash_algo *algop);
+
+static inline int is_empty_blob_oid(const struct object_id *oid,
+                                   const struct git_hash_algo *algop)
+{
+       return oideq(oid, algop->empty_blob);
+}
+
+static inline int is_empty_tree_oid(const struct object_id *oid,
+                                   const struct git_hash_algo *algop)
+{
+       return oideq(oid, algop->empty_tree);
+}
+
 #endif
diff --git a/hex.h b/hex.h
index e0b83f776f1a8cc62ab1694be4faf579051396b4..9809667f33fb30f65716fe60f759564c219a0e3f 100644 (file)
--- a/hex.h
+++ b/hex.h
@@ -1,7 +1,7 @@
 #ifndef HEX_H
 #define HEX_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "hex-ll.h"
 
 /*
diff --git a/loose.h b/loose.h
index 2c2957072c5f04326bdb8ccadf03b13d6d52d198..28512306e5fec7e57cdab949e8444264c31eab75 100644 (file)
--- a/loose.h
+++ b/loose.h
@@ -3,6 +3,8 @@
 
 #include "khash.h"
 
+struct repository;
+
 struct loose_object_map {
        kh_oid_map_t *to_compat;
        kh_oid_map_t *to_storage;
index ce56ec1a7802c5eac51d404e03220b83e52ebe1c..a994c9a5fcdb040b3ecb80db0489a50c1394ac75 100644 (file)
@@ -2,7 +2,7 @@
 #define MERGE_ORT_H
 
 #include "merge-recursive.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 struct commit;
 struct tree;
index 958f61f094ac23d0f57de3cfe6b5dd6af9475ac0..3887d6d57b7965074702829403b36518ab7022e6 100644 (file)
@@ -5,7 +5,7 @@
 #include "strbuf.h"
 #include "hex.h"
 #include "repository.h"
-#include "hash-ll.h"
+#include "hash.h"
 #include "hash.h"
 #include "object.h"
 #include "loose.h"
index 73b4ec3904be459e6e88d9974f7f68a79e18d3b9..9fa42d51d9109946673fa687af1db552268b44bd 100644 (file)
--- a/object.h
+++ b/object.h
@@ -1,7 +1,7 @@
 #ifndef OBJECT_H
 #define OBJECT_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct buffer_slab;
 struct repository;
index 05c673eb7c1163d912dd7e54466ae9931be5426b..fad412827af6884f6b3a95742f446949a36a7d1b 100644 (file)
--- a/oidmap.h
+++ b/oidmap.h
@@ -1,7 +1,7 @@
 #ifndef OIDMAP_H
 #define OIDMAP_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "hashmap.h"
 
 /*
index 55c83513fdd5f3823a3b3a430ce814094deed5ba..77898f510a12272ae2302805896eaf9eecb5ce7d 100644 (file)
--- a/oidtree.h
+++ b/oidtree.h
@@ -2,7 +2,7 @@
 #define OIDTREE_H
 
 #include "cbtree.h"
-#include "hash-ll.h"
+#include "hash.h"
 #include "mem-pool.h"
 
 struct oidtree {
index 28c8fd3e39a23ae997a66a11dfd0d5d281dbc28f..eb18ec15dbf3bc347bc6511c3f669af2cce61842 100644 (file)
@@ -101,6 +101,8 @@ int close_pack_fd(struct packed_git *p);
 
 uint32_t get_pack_fanout(struct packed_git *p, uint32_t value);
 
+struct raw_object_store;
+
 unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
 void close_pack_windows(struct packed_git *);
 void close_pack(struct packed_git *);
index 75f4cbb0a70951a85c8e5a4dba853f027ee7cf4b..fe8d1d5c6384ba3e1424fa7a372239952b6c539d 100644 (file)
@@ -3,7 +3,7 @@
 #include "gettext.h"
 #include "hex.h"
 #include "pkt-line.h"
-#include "hash-ll.h"
+#include "hash.h"
 #include "hex.h"
 #include "object.h"
 #include "object-store-ll.h"
index 09414afd0472ed79a4a7f082278328c1446f5e8a..e0e39607ef3231ffe77ea8c5512dd0672ef52969 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef READ_CACHE_LL_H
 #define READ_CACHE_LL_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "hashmap.h"
 #include "statinfo.h"
 
index 95c76e27c833112743b82a0b62f9a5423fb52259..31ebe24f6cf09a10c85cd48d6d1ee849d1f83233 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef REFS_REF_CACHE_H
 #define REFS_REF_CACHE_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct ref_dir;
 struct ref_store;
index 41abbb8ecf888d1b4240c7a1c76d00209b19cc77..dd65d9e8bb72a6cf6eaac08a5b3b2315f59881cc 100644 (file)
@@ -7,7 +7,7 @@ https://developers.google.com/open-source/licenses/bsd
 */
 
 #include "git-compat-util.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 #include "reftable-blocksource.h"
 #include "reftable-error.h"
index 2a2943cd134cebf1e6b9713613ba228d49576281..ff486eb1f756b16182ee8186a884880e9855091a 100644 (file)
@@ -9,7 +9,7 @@ https://developers.google.com/open-source/licenses/bsd
 #ifndef REFTABLE_RECORD_H
 #define REFTABLE_RECORD_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include <stdint.h>
 
 /*
index 5d8b6dede50414b750f39778c6070731b096d218..d0cabd5d171363d4d993c054e7a9b9bc60826279 100644 (file)
@@ -15,7 +15,7 @@ https://developers.google.com/open-source/licenses/bsd
 #include "lockfile.h"
 #include "strbuf.h"
 #include "tempfile.h"
-#include "hash-ll.h" /* hash ID, sizes.*/
+#include "hash.h" /* hash ID, sizes.*/
 #include "dir.h" /* remove_dir_recursively, for tests.*/
 
 int hash_size(uint32_t id);
index e8c6655e4282ba3200c495e2262e611197903ee9..7d04e1be1be9f29acf640c4c751cb234d82419c7 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -1,7 +1,7 @@
 #ifndef REMOTE_H
 #define REMOTE_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "hashmap.h"
 #include "refspec.h"
 
diff --git a/reset.h b/reset.h
index 10708d8ddc0040f86b5b1f400bfb14d932dffe8e..a28f81829d859dc3dfd3817d6449ab7eb195b0d3 100644 (file)
--- a/reset.h
+++ b/reset.h
@@ -1,7 +1,7 @@
 #ifndef RESET_H
 #define RESET_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "repository.h"
 
 #define GIT_REFLOG_ACTION_ENVIRONMENT "GIT_REFLOG_ACTION"
index f3f8462751bfd2e7fb2ab38b2632f059b8f07013..89a32272620f2b9e93102039204c72c7886306b3 100644 (file)
@@ -6,7 +6,7 @@ struct index_state;
 struct pathspec;
 struct string_list;
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct resolve_undo_info {
        unsigned int mode[3];
diff --git a/serve.c b/serve.c
index 33608ea4d5b8c8be76c38a326847c36791c29d33..884cd84ca8a0ea146ec1f82bc3584a7a297e7275 100644 (file)
--- a/serve.c
+++ b/serve.c
@@ -3,7 +3,7 @@
 #include "git-compat-util.h"
 #include "repository.h"
 #include "config.h"
-#include "hash-ll.h"
+#include "hash.h"
 #include "pkt-line.h"
 #include "version.h"
 #include "ls-refs.h"
index 15a29cd08c96be6eeff23f609ec7c8d9533175b1..1a153f47ba348fb3e8c5bdcae9b279cef352f475 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SPLIT_INDEX_H
 #define SPLIT_INDEX_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct index_state;
 struct strbuf;
index b235da594f749b1a6b680d0b674c5bb822b1b978..7de822af5168d12cfd1146f7ab8eacc02273f570 100644 (file)
@@ -1,5 +1,5 @@
 #include "test-tool.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 #define NUM_SECONDS 3
 
index dcb7f6c0032b556959c6635db3c89fd49e8790d0..e60d000c0393cbbb48e43193399f54d2186463f1 100644 (file)
@@ -1,5 +1,5 @@
 #include "test-tool.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 int cmd__sha1(int ac, const char **av)
 {
index 08cf14900140d37733e5afcad7c9fdc97c3b7eae..2fb20438f3c382d56f16299afece2787d59c9d01 100644 (file)
@@ -1,5 +1,5 @@
 #include "test-tool.h"
-#include "hash-ll.h"
+#include "hash.h"
 
 int cmd__sha256(int ac, const char **av)
 {
index bfde6391901c64959c0ca2357730665d65ad3103..8d2acca76891e4753e88164a049622f866e3f69d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef LIB_OID_H
 #define LIB_OID_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 /*
  * Convert arbitrary hex string to object_id.
index 46107772d178f9b3706f288e6055a34a040db00c..9252481df3677c59c05c1896e960438dc0281baf 100644 (file)
@@ -8,6 +8,7 @@
 #include "tree.h"
 #include "tree-walk.h"
 #include "environment.h"
+#include "repository.h"
 
 /*
  * Some mode bits are also used internally for computations.
index 0b1067fbc51affd9ff98ed44fcaad043f9870a22..aaea689f9ae600e9dcb6c5f7694c881b9b6fac00 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef TREE_WALK_H
 #define TREE_WALK_H
 
-#include "hash-ll.h"
+#include "hash.h"
 
 struct index_state;
 struct repository;
index 38537169b729528daffb42dc33a2be9cd62b7b7c..1ed430b622adf7bb25df454cc4388c5c7016817d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef XDIFF_INTERFACE_H
 #define XDIFF_INTERFACE_H
 
-#include "hash-ll.h"
+#include "hash.h"
 #include "xdiff/xdiff.h"
 
 /*