v3 refines v2 a bit more:

- fix configure typo (and stray words in commit message)
- use repo_set_hash_algo() instead of reassigning the_hash_algo
- compare hash algos by format_id
- catch NULL hash algo, report nicely and suggest GIT_HASH_FIXUP

The last point makes me much happier about keeping this workaround
around until we are confident we can live without it. Interdiff

diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 1144458140..2c75f28b41 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -331,21 +331,24 @@ static const char *open_pack_file(const char *pack_name)
 
 static void prepare_hash_algo(uint32_t pack_version)
 {
+       int pack_algo_id;
        const struct git_hash_algo *pack_algo;
 
        switch (pack_version) {
        case 2:
        case 3:
-               pack_algo = &hash_algos[GIT_HASH_SHA1];
+               pack_algo_id = GIT_HASH_SHA1;
                break;
        default:
-               die("BUG: how to determine hash algo for new version?");
+               die("BUG: how to determine hash algo for version %d?",
+                   pack_version);
        }
 
-       if (!the_hash_algo)     /* running without repo */
-               the_hash_algo = pack_algo;
+       if (!repo_has_valid_hash_algo(the_repository)) /* running without repo 
*/
+               repo_set_hash_algo(the_repository, pack_algo_id);
 
-       if (the_hash_algo != pack_algo)
+       pack_algo = &hash_algos[pack_algo_id];
+       if (the_hash_algo->format_id != pack_algo->format_id)
                die(_("incompatible hash algorithm, "
                      "configured for %s but the pack file needs %s"),
                    the_hash_algo->name, pack_algo->name);
diff --git a/cache.h b/cache.h
index 6b97138264..55b31e9756 100644
--- a/cache.h
+++ b/cache.h
@@ -53,7 +53,7 @@ struct object_id {
        unsigned char hash[GIT_MAX_RAWSZ];
 };
 
-#define the_hash_algo the_repository->hash_algo
+#define the_hash_algo repo_get_hash_algo(the_repository)
 
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
 #define DTYPE(de)      ((de)->d_type)
diff --git a/diff.c b/diff.c
index f5755425b6..5f28d84b87 100644
--- a/diff.c
+++ b/diff.c
@@ -3997,15 +3997,15 @@ static void run_diff(struct diff_filepair *p, struct 
diff_options *o)
 
        /*
         * NEEDSWORK: When running in no-index mode (and no repo is
-        * found, thus no hash algo conifugred), fall back to SHA-1
+        * found, thus no hash algo configured), fall back to SHA-1
         * hashing (which is used by diff_fill_oid_info below) to
         * avoid regression in diff output.
         *
         * In future, perhaps we can allow the user to specify their
         * hash algorithm from command line in this mode.
         */
-       if (o->flags.no_index && !the_hash_algo)
-               the_hash_algo = &hash_algos[GIT_HASH_SHA1];
+       if (o->flags.no_index && !repo_has_valid_hash_algo(the_repository))
+               repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
 
        diff_fill_oid_info(one);
        diff_fill_oid_info(two);
diff --git a/repository.h b/repository.h
index 0329e40c7f..40bd49611f 100644
--- a/repository.h
+++ b/repository.h
@@ -107,4 +107,20 @@ extern void repo_clear(struct repository *repo);
  */
 extern int repo_read_index(struct repository *repo);
 
+static inline const struct git_hash_algo *repo_get_hash_algo(
+       const struct repository *repo)
+{
+       if (!repo->hash_algo)
+               die("BUG: hash_algo is not initialized!\n%s",
+                   _("You can work around this by setting environment"
+                     " variable GIT_HASH_FIXUP=1.\n"
+                     "Please report this to git@vger.kernel.org"));
+       return repo->hash_algo;
+}
+
+static inline int repo_has_valid_hash_algo(const struct repository *repo)
+{
+       return repo->hash_algo != NULL;
+}
+
 #endif /* REPOSITORY_H */

Nguyễn Thái Ngọc Duy (6):
  setup.c: initialize the_repository correctly in all cases
  sha1_file.c: keep a good name for "unknown" hash_algos[UNKNOWN]
  cache.h: make the_hash_algo read-only
  index-pack: check (and optionally set) hash algo based on input file
  diff.c: initialize hash algo when running in --no-index mode
  Revert "repository: pre-initialize hash algo pointer"

 builtin/index-pack.c             | 29 ++++++++++++++++++++++++++++-
 builtin/init-db.c                |  3 ++-
 cache.h                          |  5 +++--
 common-main.c                    | 10 ++++++++++
 diff.c                           | 12 ++++++++++++
 path.c                           |  2 +-
 repository.c                     |  2 +-
 repository.h                     | 16 ++++++++++++++++
 setup.c                          |  5 ++++-
 sha1_file.c                      |  2 +-
 t/helper/test-dump-split-index.c |  2 ++
 11 files changed, 80 insertions(+), 8 deletions(-)

-- 
2.16.1.435.g8f24da2e1a

Reply via email to