aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-07-21 09:14:25 -0700
committerJunio C Hamano <gitster@pobox.com>2025-07-21 09:14:25 -0700
commita636d395ff0b0ccecb4569c0fc80f7c55f2e5f2e (patch)
treefd758d24e1db2726312822e7f8e5d1ffcdd13444
parent90c0775e972847832ac8dfa6a14bc4c3abacd914 (diff)
parentc79bb70a2e7d9158ec165ea16ad45371cd6e350d (diff)
downloadgit-a636d395ff0b0ccecb4569c0fc80f7c55f2e5f2e.tar.gz
Merge branch 'bc/use-sha256-by-default-in-3.0'
Prepare to flip the default hash function to SHA-256. * bc/use-sha256-by-default-in-3.0: Enable SHA-256 by default in breaking changes mode help: add a build option for default hash t5300: choose the built-in hash outside of a repo t4042: choose the built-in hash outside of a repo t1007: choose the built-in hash outside of a repo t: default to compile-time default hash if not set setup: use the default algorithm to initialize repo format Use legacy hash for legacy formats builtin: use default hash when outside a repository hash: add a constant for the legacy hash algorithm hash: add a constant for the default hash algorithm
-rw-r--r--builtin/apply.c2
-rw-r--r--builtin/diff.c2
-rw-r--r--builtin/hash-object.c2
-rw-r--r--builtin/index-pack.c2
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/patch-id.c2
-rw-r--r--builtin/receive-pack.c2
-rw-r--r--builtin/shortlog.c2
-rw-r--r--builtin/show-index.c2
-rw-r--r--bundle.c4
-rw-r--r--connect.c6
-rw-r--r--fetch-pack.c2
-rw-r--r--hash.h10
-rw-r--r--help.c1
-rw-r--r--pkt-line.c2
-rw-r--r--remote-curl.c2
-rw-r--r--serve.c2
-rw-r--r--setup.c9
-rw-r--r--setup.h2
-rwxr-xr-xt/t1007-hash-object.sh4
-rwxr-xr-xt/t4042-diff-textconv-caching.sh12
-rwxr-xr-xt/t5300-pack-object.sh6
-rw-r--r--t/test-lib-functions.sh5
-rw-r--r--t/test-lib.sh7
-rw-r--r--transport.c2
25 files changed, 62 insertions, 32 deletions
diff --git a/builtin/apply.c b/builtin/apply.c
index a1e20c593d..d642a40251 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -29,7 +29,7 @@ int cmd_apply(int argc,
* cf. https://lore.kernel.org/git/xmqqcypfcmn4.fsf@gitster.g/
*/
if (!the_hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
argc = apply_parse_options(argc, argv,
&state, &force_apply, &options,
diff --git a/builtin/diff.c b/builtin/diff.c
index c6231edce4..eebffe36cc 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -483,7 +483,7 @@ int cmd_diff(int argc,
* configurable via a command line option.
*/
if (nongit)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
init_diff_ui_defaults();
git_config(git_diff_ui_config, NULL);
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index e28f000221..ddf281413a 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -104,7 +104,7 @@ int cmd_hash_object(int argc,
prefix = setup_git_directory_gently(&nongit);
if (nongit && !the_hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
if (vpath && prefix) {
vpath_free = prefix_filename(prefix, vpath);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 19c67a8534..0a5c8a1ac8 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -2035,7 +2035,7 @@ int cmd_index_pack(int argc,
* choice but to guess the object hash.
*/
if (!the_repository->hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
opts.flags &= ~(WRITE_REV | WRITE_REV_VERIFY);
if (rev_index) {
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 01a4d4daa1..df09000b30 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -112,7 +112,7 @@ int cmd_ls_remote(int argc,
* depending on what object hash the remote uses.
*/
if (!the_repository->hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
packet_trace_identity("ls-remote");
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index cdef2ec10a..26f04b0335 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -254,7 +254,7 @@ int cmd_patch_id(int argc,
* the code that computes patch IDs to always use SHA1.
*/
if (!the_hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
generate_id_list(opts ? opts > 1 : config.stable,
opts ? opts == 3 : config.verbatim);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index dd1d1446e7..7974d157eb 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -2203,7 +2203,7 @@ static struct command *read_head_info(struct packet_reader *reader,
use_push_options = 1;
hash = parse_feature_value(feature_list, "object-format", &len, NULL);
if (!hash) {
- hash = hash_algos[GIT_HASH_SHA1].name;
+ hash = hash_algos[GIT_HASH_SHA1_LEGACY].name;
len = strlen(hash);
}
if (xstrncmpz(the_hash_algo->name, hash, len))
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index fe15e11497..60adc5e7a5 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -419,7 +419,7 @@ int cmd_shortlog(int argc,
* git/nongit so that we do not have to do this.
*/
if (nongit && !the_hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
git_config(git_default_config, NULL);
shortlog_init(&log);
diff --git a/builtin/show-index.c b/builtin/show-index.c
index 9d4ecf5e7b..2c3e2940ce 100644
--- a/builtin/show-index.c
+++ b/builtin/show-index.c
@@ -47,7 +47,7 @@ int cmd_show_index(int argc,
* the index file passed in and use that instead.
*/
if (!the_hash_algo)
- repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+ repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT);
hashsz = the_hash_algo->rawsz;
diff --git a/bundle.c b/bundle.c
index 717f056a45..42327f9739 100644
--- a/bundle.c
+++ b/bundle.c
@@ -95,7 +95,7 @@ int read_bundle_header_fd(int fd, struct bundle_header *header,
* by an "object-format=" capability, which is being handled in
* `parse_capability()`.
*/
- header->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ header->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
/* The bundle header ends with an empty line */
while (!strbuf_getwholeline_fd(&buf, fd, '\n') &&
@@ -507,7 +507,7 @@ int create_bundle(struct repository *r, const char *path,
* SHA1.
* 2. @filter is required because we parsed an object filter.
*/
- if (the_hash_algo != &hash_algos[GIT_HASH_SHA1] || revs.filter.choice)
+ if (the_hash_algo != &hash_algos[GIT_HASH_SHA1_LEGACY] || revs.filter.choice)
min_version = 3;
if (argc > 1) {
diff --git a/connect.c b/connect.c
index 3280435331..e77287f426 100644
--- a/connect.c
+++ b/connect.c
@@ -251,7 +251,7 @@ static void process_capabilities(struct packet_reader *reader, size_t *linelen)
reader->hash_algo = &hash_algos[hash_algo];
free(hash_name);
} else {
- reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ reader->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
}
}
@@ -500,7 +500,7 @@ static void send_capabilities(int fd_out, struct packet_reader *reader)
reader->hash_algo = &hash_algos[hash_algo];
packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
} else {
- reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ reader->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
}
if (server_feature_v2("promisor-remote", &promisor_remote_info)) {
char *reply = promisor_remote_reply(promisor_remote_info);
@@ -665,7 +665,7 @@ int server_supports_hash(const char *desired, int *feature_supported)
if (feature_supported)
*feature_supported = !!hash;
if (!hash) {
- hash = hash_algos[GIT_HASH_SHA1].name;
+ hash = hash_algos[GIT_HASH_SHA1_LEGACY].name;
len = strlen(hash);
}
while (hash) {
diff --git a/fetch-pack.c b/fetch-pack.c
index 5e74235fc0..01d3699c4b 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1343,7 +1343,7 @@ static void write_fetch_command_and_capabilities(struct strbuf *req_buf,
die(_("mismatched algorithms: client %s; server %s"),
the_hash_algo->name, hash_name);
packet_buf_write(req_buf, "object-format=%s", the_hash_algo->name);
- } else if (hash_algo_by_ptr(the_hash_algo) != GIT_HASH_SHA1) {
+ } else if (hash_algo_by_ptr(the_hash_algo) != GIT_HASH_SHA1_LEGACY) {
die(_("the server does not support algorithm '%s'"),
the_hash_algo->name);
}
diff --git a/hash.h b/hash.h
index ec594c63a6..fae966b23c 100644
--- a/hash.h
+++ b/hash.h
@@ -175,6 +175,16 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s
/* Number of algorithms supported (including unknown). */
#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
+/* Default hash algorithm if unspecified. */
+#ifdef WITH_BREAKING_CHANGES
+# define GIT_HASH_DEFAULT GIT_HASH_SHA256
+#else
+# define GIT_HASH_DEFAULT GIT_HASH_SHA1
+#endif
+
+/* Legacy hash algorithm. Implied for older data formats which don't specify. */
+#define GIT_HASH_SHA1_LEGACY GIT_HASH_SHA1
+
/* "sha1", big-endian */
#define GIT_SHA1_FORMAT_ID 0x73686131
diff --git a/help.c b/help.c
index 89cd47e3b8..652efebf00 100644
--- a/help.c
+++ b/help.c
@@ -812,6 +812,7 @@ void get_version_info(struct strbuf *buf, int show_build_options)
strbuf_addf(buf, "SHA-256: %s\n", SHA256_BACKEND);
strbuf_addf(buf, "default-ref-format: %s\n",
ref_storage_format_to_name(REF_STORAGE_FORMAT_DEFAULT));
+ strbuf_addf(buf, "default-hash: %s\n", hash_algos[GIT_HASH_DEFAULT].name);
}
}
diff --git a/pkt-line.c b/pkt-line.c
index a5bcbc96fb..fc583feb26 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -617,7 +617,7 @@ void packet_reader_init(struct packet_reader *reader, int fd,
reader->buffer_size = sizeof(packet_buffer);
reader->options = options;
reader->me = "git";
- reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ reader->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
strbuf_init(&reader->scratch, 0);
}
diff --git a/remote-curl.c b/remote-curl.c
index b8bc3a80cf..84f4694780 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -285,7 +285,7 @@ static const struct git_hash_algo *detect_hash_algo(struct discovery *heads)
* back to SHA1, which may or may not be correct.
*/
if (!p)
- return &hash_algos[GIT_HASH_SHA1];
+ return &hash_algos[GIT_HASH_SHA1_LEGACY];
algo = hash_algo_by_length((p - heads->buf) / 2);
if (algo == GIT_HASH_UNKNOWN)
diff --git a/serve.c b/serve.c
index e3ccf1505c..53ecab3b42 100644
--- a/serve.c
+++ b/serve.c
@@ -14,7 +14,7 @@
static int advertise_sid = -1;
static int advertise_object_info = -1;
-static int client_hash_algo = GIT_HASH_SHA1;
+static int client_hash_algo = GIT_HASH_SHA1_LEGACY;
static int always_advertise(struct repository *r UNUSED,
struct strbuf *value UNUSED)
diff --git a/setup.c b/setup.c
index 18661fc048..6f52dab64c 100644
--- a/setup.c
+++ b/setup.c
@@ -836,9 +836,12 @@ static void init_repository_format(struct repository_format *format)
int read_repository_format(struct repository_format *format, const char *path)
{
clear_repository_format(format);
+ format->hash_algo = GIT_HASH_SHA1_LEGACY;
git_config_from_file(check_repo_format, path, format);
- if (format->version == -1)
+ if (format->version == -1) {
clear_repository_format(format);
+ format->hash_algo = GIT_HASH_SHA1_LEGACY;
+ }
return format->version;
}
@@ -2225,11 +2228,11 @@ void initialize_repository_version(int hash_algo,
* version will get adjusted by git-clone(1) once it has learned about
* the remote repository's format.
*/
- if (hash_algo != GIT_HASH_SHA1 ||
+ if (hash_algo != GIT_HASH_SHA1_LEGACY ||
ref_storage_format != REF_STORAGE_FORMAT_FILES)
target_version = GIT_REPO_VERSION_READ;
- if (hash_algo != GIT_HASH_SHA1 && hash_algo != GIT_HASH_UNKNOWN)
+ if (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN)
git_config_set("extensions.objectformat",
hash_algos[hash_algo].name);
else if (reinit)
diff --git a/setup.h b/setup.h
index 18dc3b7368..8522fa8575 100644
--- a/setup.h
+++ b/setup.h
@@ -149,7 +149,7 @@ struct repository_format {
{ \
.version = -1, \
.is_bare = -1, \
- .hash_algo = GIT_HASH_SHA1, \
+ .hash_algo = GIT_HASH_DEFAULT, \
.ref_storage_format = REF_STORAGE_FORMAT_FILES, \
.unknown_extensions = STRING_LIST_INIT_DUP, \
.v1_only_extensions = STRING_LIST_INIT_DUP, \
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index 64658b3ba5..de076293b6 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -252,9 +252,9 @@ test_expect_success '--literally complains about non-standard types' '
test_must_fail git hash-object -t bogus --literally --stdin
'
-test_expect_success '--stdin outside of repository (uses SHA-1)' '
+test_expect_success '--stdin outside of repository (uses default hash)' '
nongit git hash-object --stdin <hello >actual &&
- echo "$(test_oid --hash=sha1 hello)" >expect &&
+ echo "$(test_oid --hash=builtin hello)" >expect &&
test_cmp expect actual
'
diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh
index ff0e73531b..31018ceba2 100755
--- a/t/t4042-diff-textconv-caching.sh
+++ b/t/t4042-diff-textconv-caching.sh
@@ -120,6 +120,14 @@ test_expect_success 'log notes cache and still use cache for -p' '
'
test_expect_success 'caching is silently ignored outside repo' '
+ test_oid_cache <<-\EOM &&
+ oid1 sha1:5626abf
+ oid1 sha256:a4ed1f3
+ oid2 sha1:f719efd
+ oid2 sha256:aa9e7dc
+ EOM
+ oid1=$(test_oid --hash=builtin oid1) &&
+ oid2=$(test_oid --hash=builtin oid2) &&
mkdir -p non-repo &&
echo one >non-repo/one &&
echo two >non-repo/two &&
@@ -129,9 +137,9 @@ test_expect_success 'caching is silently ignored outside repo' '
-c diff.test.textconv="tr a-z A-Z <" \
-c diff.test.cachetextconv=true \
diff --no-index one two >actual &&
- cat >expect <<-\EOF &&
+ cat >expect <<-EOF &&
diff --git a/one b/two
- index 5626abf..f719efd 100644
+ index $oid1..$oid2 100644
--- a/one
+++ b/two
@@ -1 +1 @@
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index ae72158b94..73445782e7 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -525,7 +525,7 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' '
test_path_is_file foo.idx
'
-test_expect_success SHA1 'show-index works OK outside a repository' '
+test_expect_success DEFAULT_HASH_ALGORITHM 'show-index works OK outside a repository' '
nongit git show-index <foo.idx
'
@@ -658,7 +658,7 @@ do
test_commit -C repo initial &&
git -C repo repack -ad &&
git -C repo verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
- if test $hash = sha1
+ if test $hash = $GIT_TEST_BUILTIN_HASH
then
nongit git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx
else
@@ -676,7 +676,7 @@ do
test_commit -C repo initial &&
git -C repo repack -ad &&
git -C repo index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack &&
- if test $hash = sha1
+ if test $hash = $GIT_TEST_BUILTIN_HASH
then
nongit git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack
else
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 6230746cc4..a28de7b19b 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1707,7 +1707,7 @@ test_set_hash () {
# Detect the hash algorithm in use.
test_detect_hash () {
- case "$GIT_TEST_DEFAULT_HASH" in
+ case "${GIT_TEST_DEFAULT_HASH:-$GIT_TEST_BUILTIN_HASH}" in
"sha256")
test_hash_algo=sha256
test_compat_hash_algo=sha1
@@ -1779,6 +1779,9 @@ test_oid () {
--hash=compat)
algo="$test_compat_hash_algo" &&
shift;;
+ --hash=builtin)
+ algo="$GIT_TEST_BUILTIN_HASH" &&
+ shift;;
--hash=*)
algo="${1#--hash=}" &&
shift;;
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 51370a201c..6dc2022ee1 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -536,7 +536,8 @@ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
export EDITOR
-GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}"
+GIT_TEST_BUILTIN_HASH=$("$GIT_BUILD_DIR/git" version --build-options | sed -ne 's/^default-hash: //p')
+GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-$GIT_TEST_BUILTIN_HASH}"
export GIT_DEFAULT_HASH
GIT_DEFAULT_REF_FORMAT="${GIT_TEST_DEFAULT_REF_FORMAT:-files}"
export GIT_DEFAULT_REF_FORMAT
@@ -1908,6 +1909,10 @@ test_lazy_prereq SHA1 '
esac
'
+test_lazy_prereq DEFAULT_HASH_ALGORITHM '
+ test "$GIT_TEST_BUILTIN_HASH" = "$GIT_DEFAULT_HASH"
+'
+
test_lazy_prereq DEFAULT_REPO_FORMAT '
test_have_prereq SHA1,REFFILES
'
diff --git a/transport.c b/transport.c
index 6c2801bcbd..c123ac1e38 100644
--- a/transport.c
+++ b/transport.c
@@ -1243,7 +1243,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
ret->smart_options->receivepack = remote->receivepack;
}
- ret->hash_algo = &hash_algos[GIT_HASH_SHA1];
+ ret->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
return ret;
}