hash: provide per-algorithm null OIDs

Up until recently, object IDs did not have an algorithm member, only a hash. Consequently, it was possible to share one null (all-zeros) object ID among all hash algorithms. Now that we're going to be handling objects from multiple hash algorithms, it's important to make sure that all object IDs have a correct algorithm field. Introduce a per-algorithm null OID, and add it to struct hash_algo. Introduce a wrapper function as well, and use it everywhere we used to use the null_oid constant. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Apr 26, 2021 at 01:02 UTC 14228447c9ce664a4e9c31ba10344ec5e4ea4ba5
42 files changed +119 -95
archive.c
+3 -1
@@ -275,9 +275,11 @@ int write_archive_entries(struct archiver_args *args,
275 int err;
276 struct strbuf path_in_archive = STRBUF_INIT;
277 struct strbuf content = STRBUF_INIT;
278 - struct object_id fake_oid = null_oid;
278 + struct object_id fake_oid;
279 int i;
280
281 + oidcpy(&fake_oid, null_oid());
282 +
283 if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
284 size_t len = args->baselen;
285
blame.c
+1 -1
@@ -242,7 +242,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,
242 switch (st.st_mode & S_IFMT) {
243 case S_IFREG:
244 if (opt->flags.allow_textconv &&
245 - textconv_object(r, read_from, mode, &null_oid, 0, &buf_ptr, &buf_len))
245 + textconv_object(r, read_from, mode, null_oid(), 0, &buf_ptr, &buf_len))
246 strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
247 else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
248 die_errno("cannot open or read '%s'", read_from);
branch.c
+1 -1
@@ -322,7 +322,7 @@ void create_branch(struct repository *r,
322 transaction = ref_transaction_begin(&err);
323 if (!transaction ||
324 ref_transaction_update(transaction, ref.buf,
325 - &oid, forcing ? NULL : &null_oid,
325 + &oid, forcing ? NULL : null_oid(),
326 0, msg, &err) ||
327 ref_transaction_commit(transaction, &err))
328 die("%s", err.buf);
builtin/checkout.c
+3 -3
@@ -106,8 +106,8 @@ static int post_checkout_hook(struct commit *old_commit, struct commit *new_comm
106 int changed)
107 {
108 return run_hook_le(NULL, "post-checkout",
109 - oid_to_hex(old_commit ? &old_commit->object.oid : &null_oid),
110 - oid_to_hex(new_commit ? &new_commit->object.oid : &null_oid),
109 + oid_to_hex(old_commit ? &old_commit->object.oid : null_oid()),
110 + oid_to_hex(new_commit ? &new_commit->object.oid : null_oid()),
111 changed ? "1" : "0", NULL);
112 /* "new_commit" can be NULL when checking out from the index before
113 a commit exists. */
@@ -638,7 +638,7 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
638 opts.src_index = &the_index;
639 opts.dst_index = &the_index;
640 init_checkout_metadata(&opts.meta, info->refname,
641 - info->commit ? &info->commit->object.oid : &null_oid,
641 + info->commit ? &info->commit->object.oid : null_oid(),
642 NULL);
643 parse_tree(tree);
644 init_tree_desc(&tree_desc, tree->buffer, tree->size);
builtin/clone.c
+1 -1
@@ -820,7 +820,7 @@ static int checkout(int submodule_progress)
820 if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
821 die(_("unable to write new index file"));
822
823 - err |= run_hook_le(NULL, "post-checkout", oid_to_hex(&null_oid),
823 + err |= run_hook_le(NULL, "post-checkout", oid_to_hex(null_oid()),
824 oid_to_hex(&oid), "1", NULL);
825
826 if (!err && (option_recurse_submodules.nr > 0)) {
builtin/describe.c
+1 -1
@@ -502,7 +502,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst)
502 {
503 struct rev_info revs;
504 struct strvec args = STRVEC_INIT;
505 - struct process_commit_data pcd = { null_oid, oid, dst, &revs};
505 + struct process_commit_data pcd = { *null_oid(), oid, dst, &revs};
506
507 strvec_pushl(&args, "internal: The first arg is not parsed",
508 "--objects", "--in-commit-order", "--reverse", "HEAD",
builtin/diff.c
+1 -1
@@ -98,7 +98,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
98
99 stuff_change(&revs->diffopt,
100 blob[0]->mode, canon_mode(st.st_mode),
101 - &blob[0]->item->oid, &null_oid,
101 + &blob[0]->item->oid, null_oid(),
102 1, 0,
103 blob[0]->path ? blob[0]->path : path,
104 path);
builtin/fast-export.c
+5 -5
@@ -870,7 +870,7 @@ static void handle_tag(const char *name, struct tag *tag)
870 p = rewrite_commit((struct commit *)tagged);
871 if (!p) {
872 printf("reset %s\nfrom %s\n\n",
873 - name, oid_to_hex(&null_oid));
873 + name, oid_to_hex(null_oid()));
874 free(buf);
875 return;
876 }
@@ -884,7 +884,7 @@ static void handle_tag(const char *name, struct tag *tag)
884
885 if (tagged->type == OBJ_TAG) {
886 printf("reset %s\nfrom %s\n\n",
887 - name, oid_to_hex(&null_oid));
887 + name, oid_to_hex(null_oid()));
888 }
889 skip_prefix(name, "refs/tags/", &name);
890 printf("tag %s\n", name);
@@ -1016,7 +1016,7 @@ static void handle_tags_and_duplicates(struct string_list *extras)
1016 * it.
1017 */
1018 printf("reset %s\nfrom %s\n\n",
1019 - name, oid_to_hex(&null_oid));
1019 + name, oid_to_hex(null_oid()));
1020 continue;
1021 }
1022
@@ -1035,7 +1035,7 @@ static void handle_tags_and_duplicates(struct string_list *extras)
1035 if (!reference_excluded_commits) {
1036 /* delete the ref */
1037 printf("reset %s\nfrom %s\n\n",
1038 - name, oid_to_hex(&null_oid));
1038 + name, oid_to_hex(null_oid()));
1039 continue;
1040 }
1041 /* set ref to commit using oid, not mark */
@@ -1146,7 +1146,7 @@ static void handle_deletes(void)
1146 continue;
1147
1148 printf("reset %s\nfrom %s\n\n",
1149 - refspec->dst, oid_to_hex(&null_oid));
1149 + refspec->dst, oid_to_hex(null_oid()));
1150 }
1151 }
1152
builtin/grep.c
+1 -1
@@ -421,7 +421,7 @@ static int grep_submodule(struct grep_opt *opt,
421 struct grep_opt subopt;
422 int hit;
423
424 - sub = submodule_from_path(superproject, &null_oid, path);
424 + sub = submodule_from_path(superproject, null_oid(), path);
425
426 if (!is_submodule_active(superproject, path))
427 return 0;
builtin/ls-files.c
+1 -1
@@ -210,7 +210,7 @@ static void show_submodule(struct repository *superproject,
210 {
211 struct repository subrepo;
212 const struct submodule *sub = submodule_from_path(superproject,
213 - &null_oid, path);
213 + null_oid(), path);
214
215 if (repo_submodule_init(&subrepo, superproject, sub))
216 return;
builtin/rebase.c
+2 -2
@@ -485,7 +485,7 @@ static const char * const builtin_rebase_interactive_usage[] = {
485 int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
486 {
487 struct rebase_options opts = REBASE_OPTIONS_INIT;
488 - struct object_id squash_onto = null_oid;
488 + struct object_id squash_onto = *null_oid();
489 enum action command = ACTION_NONE;
490 struct option options[] = {
491 OPT_NEGBIT(0, "ff", &opts.flags, N_("allow fast-forward"),
@@ -1139,7 +1139,7 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
1139
1140 merge_bases = get_merge_bases(onto, head);
1141 if (!merge_bases || merge_bases->next) {
1142 - oidcpy(merge_base, &null_oid);
1142 + oidcpy(merge_base, null_oid());
1143 goto done;
1144 }
1145
builtin/receive-pack.c
+1 -1
@@ -329,7 +329,7 @@ static void write_head_info(void)
329 for_each_alternate_ref(show_one_alternate_ref, &seen);
330 oidset_clear(&seen);
331 if (!sent_capabilities)
332 - show_ref("capabilities^{}", &null_oid);
332 + show_ref("capabilities^{}", null_oid());
333
334 advertise_shallow_grafts(1);
335
builtin/submodule--helper.c
+15 -14
@@ -426,7 +426,8 @@ static int module_list(int argc, const char **argv, const char *prefix)
426 const struct cache_entry *ce = list.entries[i];
427
428 if (ce_stage(ce))
429 - printf("%06o %s U\t", ce->ce_mode, oid_to_hex(&null_oid));
429 + printf("%06o %s U\t", ce->ce_mode,
430 + oid_to_hex(null_oid()));
431 else
432 printf("%06o %s %d\t", ce->ce_mode,
433 oid_to_hex(&ce->oid), ce_stage(ce));
@@ -466,7 +467,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
467
468 displaypath = get_submodule_displaypath(path, info->prefix);
469
469 - sub = submodule_from_path(the_repository, &null_oid, path);
470 + sub = submodule_from_path(the_repository, null_oid(), path);
471
472 if (!sub)
473 die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -623,7 +624,7 @@ static void init_submodule(const char *path, const char *prefix,
624
625 displaypath = get_submodule_displaypath(path, prefix);
626
626 - sub = submodule_from_path(the_repository, &null_oid, path);
627 + sub = submodule_from_path(the_repository, null_oid(), path);
628
629 if (!sub)
630 die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -783,14 +784,14 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
784 struct strbuf buf = STRBUF_INIT;
785 const char *git_dir;
786
786 - if (!submodule_from_path(the_repository, &null_oid, path))
787 + if (!submodule_from_path(the_repository, null_oid(), path))
788 die(_("no submodule mapping found in .gitmodules for path '%s'"),
789 path);
790
791 displaypath = get_submodule_displaypath(path, prefix);
792
793 if ((CE_STAGEMASK & ce_flags) >> CE_STAGESHIFT) {
793 - print_status(flags, 'U', path, &null_oid, displaypath);
794 + print_status(flags, 'U', path, null_oid(), displaypath);
795 goto cleanup;
796 }
797
@@ -916,7 +917,7 @@ static int module_name(int argc, const char **argv, const char *prefix)
917 if (argc != 2)
918 usage(_("git submodule--helper name <path>"));
919
919 - sub = submodule_from_path(the_repository, &null_oid, argv[1]);
920 + sub = submodule_from_path(the_repository, null_oid(), argv[1]);
921
922 if (!sub)
923 die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -1040,7 +1041,7 @@ static void generate_submodule_summary(struct summary_cb *info,
1041 char *errmsg = NULL;
1042 int total_commits = -1;
1043
1043 - if (!info->cached && oideq(&p->oid_dst, &null_oid)) {
1044 + if (!info->cached && oideq(&p->oid_dst, null_oid())) {
1045 if (S_ISGITLINK(p->mod_dst)) {
1046 struct ref_store *refs = get_submodule_ref_store(p->sm_path);
1047 if (refs)
@@ -1177,7 +1178,7 @@ static void prepare_submodule_summary(struct summary_cb *info,
1178
1179 if (info->for_status && p->status != 'A' &&
1180 (sub = submodule_from_path(the_repository,
1180 - &null_oid, p->sm_path))) {
1181 + null_oid(), p->sm_path))) {
1182 char *config_key = NULL;
1183 const char *value;
1184 int ignore_all = 0;
@@ -1373,7 +1374,7 @@ static void sync_submodule(const char *path, const char *prefix,
1374 if (!is_submodule_active(the_repository, path))
1375 return;
1376
1376 - sub = submodule_from_path(the_repository, &null_oid, path);
1377 + sub = submodule_from_path(the_repository, null_oid(), path);
1378
1379 if (sub && sub->url) {
1380 if (starts_with_dot_dot_slash(sub->url) ||
@@ -1525,7 +1526,7 @@ static void deinit_submodule(const char *path, const char *prefix,
1526 struct strbuf sb_config = STRBUF_INIT;
1527 char *sub_git_dir = xstrfmt("%s/.git", path);
1528
1528 - sub = submodule_from_path(the_repository, &null_oid, path);
1529 + sub = submodule_from_path(the_repository, null_oid(), path);
1530
1531 if (!sub || !sub->name)
1532 goto cleanup;
@@ -1925,7 +1926,7 @@ static void determine_submodule_update_strategy(struct repository *r,
1926 const char *update,
1927 struct submodule_update_strategy *out)
1928 {
1928 - const struct submodule *sub = submodule_from_path(r, &null_oid, path);
1929 + const struct submodule *sub = submodule_from_path(r, null_oid(), path);
1930 char *key;
1931 const char *val;
1932
@@ -2077,7 +2078,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
2078 goto cleanup;
2079 }
2080
2080 - sub = submodule_from_path(the_repository, &null_oid, ce->name);
2081 + sub = submodule_from_path(the_repository, null_oid(), ce->name);
2082
2083 if (suc->recursive_prefix)
2084 displaypath = relative_path(suc->recursive_prefix,
@@ -2395,7 +2396,7 @@ static const char *remote_submodule_branch(const char *path)
2396 const char *branch = NULL;
2397 char *key;
2398
2398 - sub = submodule_from_path(the_repository, &null_oid, path);
2399 + sub = submodule_from_path(the_repository, null_oid(), path);
2400 if (!sub)
2401 return NULL;
2402
@@ -2533,7 +2534,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
2534
2535 path = argv[1];
2536
2536 - sub = submodule_from_path(the_repository, &null_oid, path);
2537 + sub = submodule_from_path(the_repository, null_oid(), path);
2538 if (!sub)
2539 BUG("We could get the submodule handle before?");
2540
builtin/unpack-objects.c
+2 -1
@@ -421,7 +421,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
421 * has not been resolved yet.
422 */
423 oidclr(&obj_list[nr].oid);
424 - add_delta_to_list(nr, &null_oid, base_offset, delta_data, delta_size);
424 + add_delta_to_list(nr, null_oid(), base_offset,
425 + delta_data, delta_size);
426 return;
427 }
428 }
builtin/worktree.c
+2 -2
@@ -331,7 +331,7 @@ static int add_worktree(const char *path, const char *refname,
331 */
332 strbuf_reset(&sb);
333 strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
334 - write_file(sb.buf, "%s", oid_to_hex(&null_oid));
334 + write_file(sb.buf, "%s", oid_to_hex(null_oid()));
335 strbuf_reset(&sb);
336 strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
337 write_file(sb.buf, "../..");
@@ -394,7 +394,7 @@ done:
394 cp.argv = NULL;
395 cp.trace2_hook_name = "post-checkout";
396 strvec_pushl(&cp.args, absolute_path(hook),
397 - oid_to_hex(&null_oid),
397 + oid_to_hex(null_oid()),
398 oid_to_hex(&commit->object.oid),
399 "1", NULL);
400 ret = run_command(&cp);
combine-diff.c
+1 -1
@@ -1068,7 +1068,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
1068 &result_size, NULL, NULL);
1069 } else if (textconv) {
1070 struct diff_filespec *df = alloc_filespec(elem->path);
1071 - fill_filespec(df, &null_oid, 0, st.st_mode);
1071 + fill_filespec(df, null_oid(), 0, st.st_mode);
1072 result_size = fill_textconv(opt->repo, textconv, df, &result);
1073 free_filespec(df);
1074 } else if (0 <= (fd = open(elem->path, O_RDONLY))) {
connect.c
+1 -1
@@ -254,7 +254,7 @@ static int process_dummy_ref(const struct packet_reader *reader)
254 return 0;
255 name++;
256
257 - return oideq(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
257 + return oideq(null_oid(), &oid) && !strcmp(name, "capabilities^{}");
258 }
259
260 static void check_no_capabilities(const char *line, int len)
diff-lib.c
+3 -3
@@ -232,7 +232,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
232 ce_intent_to_add(ce)) {
233 newmode = ce_mode_from_stat(ce, st.st_mode);
234 diff_addremove(&revs->diffopt, '+', newmode,
235 - &null_oid, 0, ce->name, 0);
235 + null_oid(), 0, ce->name, 0);
236 continue;
237 }
238
@@ -249,7 +249,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
249 }
250 oldmode = ce->ce_mode;
251 old_oid = &ce->oid;
252 - new_oid = changed ? &null_oid : &ce->oid;
252 + new_oid = changed ? null_oid() : &ce->oid;
253 diff_change(&revs->diffopt, oldmode, newmode,
254 old_oid, new_oid,
255 !is_null_oid(old_oid),
@@ -307,7 +307,7 @@ static int get_stat_data(const struct index_state *istate,
307 0, dirty_submodule);
308 if (changed) {
309 mode = ce_mode_from_stat(ce, st.st_mode);
310 - oid = &null_oid;
310 + oid = null_oid();
311 }
312 }
313
diff-no-index.c
+1 -1
@@ -83,7 +83,7 @@ static struct diff_filespec *noindex_filespec(const char *name, int mode)
83 if (!name)
84 name = "/dev/null";
85 s = alloc_filespec(name);
86 - fill_filespec(s, &null_oid, 0, mode);
86 + fill_filespec(s, null_oid(), 0, mode);
87 if (name == file_from_standard_input)
88 populate_from_stdin(s);
89 return s;
diff.c
+2 -2
@@ -4190,7 +4190,7 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r,
4190 die_errno("readlink(%s)", name);
4191 prep_temp_blob(r->index, name, temp, sb.buf, sb.len,
4192 (one->oid_valid ?
4193 - &one->oid : &null_oid),
4193 + &one->oid : null_oid()),
4194 (one->oid_valid ?
4195 one->mode : S_IFLNK));
4196 strbuf_release(&sb);
@@ -4199,7 +4199,7 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r,
4199 /* we can borrow from the file in the work tree */
4200 temp->name = name;
4201 if (!one->oid_valid)
4202 - oid_to_hex_r(temp->hex, &null_oid);
4202 + oid_to_hex_r(temp->hex, null_oid());
4203 else
4204 oid_to_hex_r(temp->hex, &one->oid);
4205 /* Even though we may sometimes borrow the
dir.c
+1 -1
@@ -3556,7 +3556,7 @@ static void connect_wt_gitdir_in_nested(const char *sub_worktree,
3556 */
3557 i++;
3558
3559 - sub = submodule_from_path(&subrepo, &null_oid, ce->name);
3559 + sub = submodule_from_path(&subrepo, null_oid(), ce->name);
3560 if (!sub || !is_submodule_active(&subrepo, ce->name))
3561 /* .gitmodules broken or inactive sub */
3562 continue;
grep.c
+1 -1
@@ -1494,7 +1494,7 @@ static int fill_textconv_grep(struct repository *r,
1494 fill_filespec(df, gs->identifier, 1, 0100644);
1495 break;
1496 case GREP_SOURCE_FILE:
1497 - fill_filespec(df, &null_oid, 0, 0100644);
1497 + fill_filespec(df, null_oid(), 0, 0100644);
1498 break;
1499 default:
1500 BUG("attempt to textconv something without a path?");
hash.h
+5 -2
@@ -170,6 +170,9 @@ struct git_hash_algo {
170
171 /* The OID of the empty blob. */
172 const struct object_id *empty_blob;
173 +
174 + /* The all-zeros OID. */
175 + const struct object_id *null_oid;
176 };
177 extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
178
@@ -190,7 +193,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
193
194 #define the_hash_algo the_repository->hash_algo
195
193 -extern const struct object_id null_oid;
196 +const struct object_id *null_oid(void);
197
198 static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
199 {
@@ -246,7 +249,7 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi
249
250 static inline int is_null_oid(const struct object_id *oid)
251 {
249 - return oideq(oid, &null_oid);
252 + return oideq(oid, null_oid());
253 }
254
255 static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
log-tree.c
+1 -1
@@ -419,7 +419,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
419 {
420 const char *extra_headers = opt->extra_headers;
421 const char *name = oid_to_hex(opt->zero_commit ?
422 - &null_oid : &commit->object.oid);
422 + null_oid() : &commit->object.oid);
423
424 *need_8bit_cte_p = 0; /* unknown */
425
merge-ort.c
+10 -10
@@ -1291,7 +1291,7 @@ static int handle_content_merge(struct merge_options *opt,
1291 two_way = ((S_IFMT & o->mode) != (S_IFMT & a->mode));
1292
1293 merge_status = merge_3way(opt, path,
1294 - two_way ? &null_oid : &o->oid,
1294 + two_way ? null_oid() : &o->oid,
1295 &a->oid, &b->oid,
1296 pathnames, extra_marker_size,
1297 &result_buf);
@@ -1313,7 +1313,7 @@ static int handle_content_merge(struct merge_options *opt,
1313 } else if (S_ISGITLINK(a->mode)) {
1314 int two_way = ((S_IFMT & o->mode) != (S_IFMT & a->mode));
1315 clean = merge_submodule(opt, pathnames[0],
1316 - two_way ? &null_oid : &o->oid,
1316 + two_way ? null_oid() : &o->oid,
1317 &a->oid, &b->oid, &result->oid);
1318 if (opt->priv->call_depth && two_way && !clean) {
1319 result->mode = o->mode;
@@ -2123,7 +2123,7 @@ static int process_renames(struct merge_options *opt,
2123 if (type_changed) {
2124 /* rename vs. typechange */
2125 /* Mark the original as resolved by removal */
2126 - memcpy(&oldinfo->stages[0].oid, &null_oid,
2126 + memcpy(&oldinfo->stages[0].oid, null_oid(),
2127 sizeof(oldinfo->stages[0].oid));
2128 oldinfo->stages[0].mode = 0;
2129 oldinfo->filemask &= 0x06;
@@ -2762,7 +2762,7 @@ static void process_entry(struct merge_options *opt,
2762 if (ci->filemask & (1 << i))
2763 continue;
2764 ci->stages[i].mode = 0;
2765 - oidcpy(&ci->stages[i].oid, &null_oid);
2765 + oidcpy(&ci->stages[i].oid, null_oid());
2766 }
2767 } else if (ci->df_conflict && ci->merged.result.mode != 0) {
2768 /*
@@ -2808,7 +2808,7 @@ static void process_entry(struct merge_options *opt,
2808 continue;
2809 /* zero out any entries related to directories */
2810 new_ci->stages[i].mode = 0;
2811 - oidcpy(&new_ci->stages[i].oid, &null_oid);
2811 + oidcpy(&new_ci->stages[i].oid, null_oid());
2812 }
2813
2814 /*
@@ -2909,11 +2909,11 @@ static void process_entry(struct merge_options *opt,
2909 new_ci->merged.result.mode = ci->stages[2].mode;
2910 oidcpy(&new_ci->merged.result.oid, &ci->stages[2].oid);
2911 new_ci->stages[1].mode = 0;
2912 - oidcpy(&new_ci->stages[1].oid, &null_oid);
2912 + oidcpy(&new_ci->stages[1].oid, null_oid());
2913 new_ci->filemask = 5;
2914 if ((S_IFMT & b_mode) != (S_IFMT & o_mode)) {
2915 new_ci->stages[0].mode = 0;
2916 - oidcpy(&new_ci->stages[0].oid, &null_oid);
2916 + oidcpy(&new_ci->stages[0].oid, null_oid());
2917 new_ci->filemask = 4;
2918 }
2919
@@ -2921,11 +2921,11 @@ static void process_entry(struct merge_options *opt,
2921 ci->merged.result.mode = ci->stages[1].mode;
2922 oidcpy(&ci->merged.result.oid, &ci->stages[1].oid);
2923 ci->stages[2].mode = 0;
2924 - oidcpy(&ci->stages[2].oid, &null_oid);
2924 + oidcpy(&ci->stages[2].oid, null_oid());
2925 ci->filemask = 3;
2926 if ((S_IFMT & a_mode) != (S_IFMT & o_mode)) {
2927 ci->stages[0].mode = 0;
2928 - oidcpy(&ci->stages[0].oid, &null_oid);
2928 + oidcpy(&ci->stages[0].oid, null_oid());
2929 ci->filemask = 2;
2930 }
2931
@@ -3042,7 +3042,7 @@ static void process_entry(struct merge_options *opt,
3042 /* Deleted on both sides */
3043 ci->merged.is_null = 1;
3044 ci->merged.result.mode = 0;
3045 - oidcpy(&ci->merged.result.oid, &null_oid);
3045 + oidcpy(&ci->merged.result.oid, null_oid());
3046 ci->merged.clean = !ci->path_conflict;
3047 }
3048
merge-recursive.c
+5 -5
@@ -486,7 +486,7 @@ static int get_tree_entry_if_blob(struct repository *r,
486
487 ret = get_tree_entry(r, tree, path, &dfs->oid, &dfs->mode);
488 if (S_ISDIR(dfs->mode)) {
489 - oidcpy(&dfs->oid, &null_oid);
489 + oidcpy(&dfs->oid, null_oid());
490 dfs->mode = 0;
491 }
492 return ret;
@@ -1604,7 +1604,7 @@ static int handle_file_collision(struct merge_options *opt,
1604
1605 /* Store things in diff_filespecs for functions that need it */
1606 null.path = (char *)collide_path;
1607 - oidcpy(&null.oid, &null_oid);
1607 + oidcpy(&null.oid, null_oid());
1608 null.mode = 0;
1609
1610 if (merge_mode_and_contents(opt, &null, a, b, collide_path,
@@ -2789,11 +2789,11 @@ static int process_renames(struct merge_options *opt,
2789 dst_other.mode = ren1->dst_entry->stages[other_stage].mode;
2790 try_merge = 0;
2791
2792 - if (oideq(&src_other.oid, &null_oid) &&
2792 + if (oideq(&src_other.oid, null_oid()) &&
2793 ren1->dir_rename_original_type == 'A') {
2794 setup_rename_conflict_info(RENAME_VIA_DIR,
2795 opt, ren1, NULL);
2796 - } else if (oideq(&src_other.oid, &null_oid)) {
2796 + } else if (oideq(&src_other.oid, null_oid())) {
2797 setup_rename_conflict_info(RENAME_DELETE,
2798 opt, ren1, NULL);
2799 } else if ((dst_other.mode == ren1->pair->two->mode) &&
@@ -2812,7 +2812,7 @@ static int process_renames(struct merge_options *opt,
2812 1, /* update_cache */
2813 0 /* update_wd */))
2814 clean_merge = -1;
2815 - } else if (!oideq(&dst_other.oid, &null_oid)) {
2815 + } else if (!oideq(&dst_other.oid, null_oid())) {
2816 /*
2817 * Probably not a clean merge, but it's
2818 * premature to set clean_merge to 0 here,
notes-merge.c
+1 -1
@@ -600,7 +600,7 @@ int notes_merge(struct notes_merge_options *o,
600 /* Find merge bases */
601 bases = get_merge_bases(local, remote);
602 if (!bases) {
603 - base_oid = &null_oid;
603 + base_oid = null_oid();
604 base_tree_oid = the_hash_algo->empty_tree;
605 if (o->verbosity >= 4)
606 printf("No merge base found; doing history-less merge\n");
notes.c
+1 -1
@@ -1327,7 +1327,7 @@ int copy_note(struct notes_tree *t,
1327 if (note)
1328 return add_note(t, to_obj, note, combine_notes);
1329 else if (existing_note)
1330 - return add_note(t, to_obj, &null_oid, combine_notes);
1330 + return add_note(t, to_obj, null_oid(), combine_notes);
1331
1332 return 0;
1333 }
object-file.c
+16 -1
@@ -55,7 +55,6 @@
55 "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
56 "\x18\x13"
57
58 -const struct object_id null_oid;
58 static const struct object_id empty_tree_oid = {
59 .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
60 .algo = GIT_HASH_SHA1,
@@ -64,6 +63,10 @@ static const struct object_id empty_blob_oid = {
63 .hash = EMPTY_BLOB_SHA1_BIN_LITERAL,
64 .algo = GIT_HASH_SHA1,
65 };
66 +static const struct object_id null_oid_sha1 = {
67 + .hash = {0},
68 + .algo = GIT_HASH_SHA1,
69 +};
70 static const struct object_id empty_tree_oid_sha256 = {
71 .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
72 .algo = GIT_HASH_SHA256,
@@ -72,6 +75,10 @@ static const struct object_id empty_blob_oid_sha256 = {
75 .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
76 .algo = GIT_HASH_SHA256,
77 };
78 +static const struct object_id null_oid_sha256 = {
79 + .hash = {0},
80 + .algo = GIT_HASH_SHA256,
81 +};
82
83 static void git_hash_sha1_init(git_hash_ctx *ctx)
84 {
@@ -172,6 +179,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
179 git_hash_unknown_final_oid,
180 NULL,
181 NULL,
182 + NULL,
183 },
184 {
185 "sha1",
@@ -187,6 +195,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
195 git_hash_sha1_final_oid,
196 &empty_tree_oid,
197 &empty_blob_oid,
198 + &null_oid_sha1,
199 },
200 {
201 "sha256",
@@ -202,9 +211,15 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
211 git_hash_sha256_final_oid,
212 &empty_tree_oid_sha256,
213 &empty_blob_oid_sha256,
214 + &null_oid_sha256,
215 }
216 };
217
218 +const struct object_id *null_oid(void)
219 +{
220 + return the_hash_algo->null_oid;
221 +}
222 +
223 const char *empty_tree_oid_hex(void)
224 {
225 static char buf[GIT_MAX_HEXSZ + 1];
parse-options-cb.c
+1 -1
@@ -140,7 +140,7 @@ int parse_opt_object_id(const struct option *opt, const char *arg, int unset)
140 struct object_id *target = opt->value;
141
142 if (unset) {
143 - *target = null_oid;
143 + oidcpy(target, null_oid());
144 return 0;
145 }
146 if (!arg)
range-diff.c
+1 -1
@@ -445,7 +445,7 @@ static struct diff_filespec *get_filespec(const char *name, const char *p)
445 {
446 struct diff_filespec *spec = alloc_filespec(name);
447
448 - fill_filespec(spec, &null_oid, 0, 0100644);
448 + fill_filespec(spec, null_oid(), 0, 0100644);
449 spec->data = (char *)p;
450 spec->size = strlen(p);
451 spec->should_munmap = 0;
refs.c
+2 -2
@@ -1107,7 +1107,7 @@ int ref_transaction_create(struct ref_transaction *transaction,
1107 if (!new_oid || is_null_oid(new_oid))
1108 BUG("create called without valid new_oid");
1109 return ref_transaction_update(transaction, refname, new_oid,
1110 - &null_oid, flags, msg, err);
1110 + null_oid(), flags, msg, err);
1111 }
1112
1113 int ref_transaction_delete(struct ref_transaction *transaction,
@@ -1119,7 +1119,7 @@ int ref_transaction_delete(struct ref_transaction *transaction,
1119 if (old_oid && is_null_oid(old_oid))
1120 BUG("delete called with old_oid set to zeros");
1121 return ref_transaction_update(transaction, refname,
1122 - &null_oid, old_oid,
1122 + null_oid(), old_oid,
1123 flags, msg, err);
1124 }
1125
refs/debug.c
+1 -1
@@ -243,7 +243,7 @@ static int debug_read_raw_ref(struct ref_store *ref_store, const char *refname,
243 struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
244 int res = 0;
245
246 - oidcpy(oid, &null_oid);
246 + oidcpy(oid, null_oid());
247 res = drefs->refs->be->read_raw_ref(drefs->refs, refname, oid, referent,
248 type);
249
refs/files-backend.c
+1 -1
@@ -1084,7 +1084,7 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r)
1084 ref_transaction_add_update(
1085 transaction, r->name,
1086 REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING,
1087 - &null_oid, &r->oid, NULL);
1087 + null_oid(), &r->oid, NULL);
1088 if (ref_transaction_commit(transaction, &err))
1089 goto cleanup;
1090
reset.c
+1 -1
@@ -128,7 +128,7 @@ reset_head_refs:
128 }
129 if (run_hook)
130 run_hook_le(NULL, "post-checkout",
131 - oid_to_hex(orig ? orig : &null_oid),
131 + oid_to_hex(orig ? orig : null_oid()),
132 oid_to_hex(oid), "1", NULL);
133
134 leave_reset_head:
sequencer.c
+2 -2
@@ -524,7 +524,7 @@ static int fast_forward_to(struct repository *r,
524 if (!transaction ||
525 ref_transaction_update(transaction, "HEAD",
526 to, unborn && !is_rebase_i(opts) ?
527 - &null_oid : from,
527 + null_oid() : from,
528 0, sb.buf, &err) ||
529 ref_transaction_commit(transaction, &err)) {
530 ref_transaction_free(transaction);
@@ -1131,7 +1131,7 @@ int update_head_with_reflog(const struct commit *old_head,
1131 transaction = ref_transaction_begin(err);
1132 if (!transaction ||
1133 ref_transaction_update(transaction, "HEAD", new_head,
1134 - old_head ? &old_head->object.oid : &null_oid,
1134 + old_head ? &old_head->object.oid : null_oid(),
1135 0, sb.buf, err) ||
1136 ref_transaction_commit(transaction, err)) {
1137 ret = -1;
submodule-config.c
+1 -1
@@ -671,7 +671,7 @@ static int gitmodules_cb(const char *var, const char *value, void *data)
671
672 parameter.cache = repo->submodule_cache;
673 parameter.treeish_name = NULL;
674 - parameter.gitmodules_oid = &null_oid;
674 + parameter.gitmodules_oid = null_oid();
675 parameter.overwrite = 1;
676
677 return parse_config(var, value, &parameter);
submodule.c
+14 -12
@@ -113,7 +113,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)
113 if (is_gitmodules_unmerged(the_repository->index))
114 die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
115
116 - submodule = submodule_from_path(the_repository, &null_oid, oldpath);
116 + submodule = submodule_from_path(the_repository, null_oid(), oldpath);
117 if (!submodule || !submodule->name) {
118 warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
119 return -1;
@@ -142,7 +142,7 @@ int remove_path_from_gitmodules(const char *path)
142 if (is_gitmodules_unmerged(the_repository->index))
143 die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
144
145 - submodule = submodule_from_path(the_repository, &null_oid, path);
145 + submodule = submodule_from_path(the_repository, null_oid(), path);
146 if (!submodule || !submodule->name) {
147 warning(_("Could not find section in .gitmodules where path=%s"), path);
148 return -1;
@@ -188,7 +188,8 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
188 const char *path)
189 {
190 const struct submodule *submodule = submodule_from_path(the_repository,
191 - &null_oid, path);
191 + null_oid(),
192 + path);
193 if (submodule) {
194 const char *ignore;
195 char *key;
@@ -244,7 +245,7 @@ int is_submodule_active(struct repository *repo, const char *path)
245 const struct string_list *sl;
246 const struct submodule *module;
247
247 - module = submodule_from_path(repo, &null_oid, path);
248 + module = submodule_from_path(repo, null_oid(), path);
249
250 /* early return if there isn't a path->module mapping */
251 if (!module)
@@ -745,7 +746,7 @@ const struct submodule *submodule_from_ce(const struct cache_entry *ce)
746 if (!should_update_submodules())
747 return NULL;
748
748 - return submodule_from_path(the_repository, &null_oid, ce->name);
749 + return submodule_from_path(the_repository, null_oid(), ce->name);
750 }
751
752 static struct oid_array *submodule_commits(struct string_list *submodules,
@@ -1037,7 +1038,7 @@ int find_unpushed_submodules(struct repository *r,
1038 const struct submodule *submodule;
1039 const char *path = NULL;
1040
1040 - submodule = submodule_from_name(r, &null_oid, name->string);
1041 + submodule = submodule_from_name(r, null_oid(), name->string);
1042 if (submodule)
1043 path = submodule->path;
1044 else
@@ -1224,7 +1225,7 @@ static void calculate_changed_submodule_paths(struct repository *r,
1225 const struct submodule *submodule;
1226 const char *path = NULL;
1227
1227 - submodule = submodule_from_name(r, &null_oid, name->string);
1228 + submodule = submodule_from_name(r, null_oid(), name->string);
1229 if (submodule)
1230 path = submodule->path;
1231 else
@@ -1361,7 +1362,7 @@ static struct fetch_task *fetch_task_create(struct repository *r,
1362 struct fetch_task *task = xmalloc(sizeof(*task));
1363 memset(task, 0, sizeof(*task));
1364
1364 - task->sub = submodule_from_path(r, &null_oid, path);
1365 + task->sub = submodule_from_path(r, null_oid(), path);
1366 if (!task->sub) {
1367 /*
1368 * No entry in .gitmodules? Technically not a submodule,
@@ -1917,7 +1918,7 @@ int submodule_move_head(const char *path,
1918 if (old_head && !is_submodule_populated_gently(path, error_code_ptr))
1919 return 0;
1920
1920 - sub = submodule_from_path(the_repository, &null_oid, path);
1921 + sub = submodule_from_path(the_repository, null_oid(), path);
1922
1923 if (!sub)
1924 BUG("could not get submodule information for '%s'", path);
@@ -2076,7 +2077,7 @@ static void relocate_single_git_dir_into_superproject(const char *path)
2077
2078 real_old_git_dir = real_pathdup(old_git_dir, 1);
2079
2079 - sub = submodule_from_path(the_repository, &null_oid, path);
2080 + sub = submodule_from_path(the_repository, null_oid(), path);
2081 if (!sub)
2082 die(_("could not lookup name for submodule '%s'"), path);
2083
@@ -2135,7 +2136,7 @@ void absorb_git_dir_into_superproject(const char *path,
2136 * superproject did not rewrite the git file links yet,
2137 * fix it now.
2138 */
2138 - sub = submodule_from_path(the_repository, &null_oid, path);
2139 + sub = submodule_from_path(the_repository, null_oid(), path);
2140 if (!sub)
2141 die(_("could not lookup name for submodule '%s'"), path);
2142 connect_work_tree_and_git_dir(path,
@@ -2283,7 +2284,8 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
2284 strbuf_addstr(buf, git_dir);
2285 }
2286 if (!is_git_directory(buf->buf)) {
2286 - sub = submodule_from_path(the_repository, &null_oid, submodule);
2287 + sub = submodule_from_path(the_repository, null_oid(),
2288 + submodule);
2289 if (!sub) {
2290 ret = -1;
2291 goto cleanup;
t/helper/test-submodule-nested-repo-config.c
+1 -1
@@ -18,7 +18,7 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv)
18
19 setup_git_directory();
20
21 - sub = submodule_from_path(the_repository, &null_oid, argv[1]);
21 + sub = submodule_from_path(the_repository, null_oid(), argv[1]);
22 if (repo_submodule_init(&subrepo, the_repository, sub)) {
23 die_usage(argv, "Submodule not found.");
24 }
tree-diff.c
+2 -2
@@ -161,7 +161,7 @@ static struct combine_diff_path *path_appendnew(struct combine_diff_path *last,
161 memcpy(p->path + base->len, path, pathlen);
162 p->path[len] = 0;
163 p->mode = mode;
164 - oidcpy(&p->oid, oid ? oid : &null_oid);
164 + oidcpy(&p->oid, oid ? oid : null_oid());
165
166 return p;
167 }
@@ -243,7 +243,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
243 mode_i = tp[i].entry.mode;
244 }
245 else {
246 - oid_i = &null_oid;
246 + oid_i = null_oid();
247 mode_i = 0;
248 }
249
wt-status.c
+2 -2
@@ -1687,10 +1687,10 @@ void wt_status_get_state(struct repository *r,
1687 if (!sequencer_get_last_command(r, &action)) {
1688 if (action == REPLAY_PICK) {
1689 state->cherry_pick_in_progress = 1;
1690 - oidcpy(&state->cherry_pick_head_oid, &null_oid);
1690 + oidcpy(&state->cherry_pick_head_oid, null_oid());
1691 } else {
1692 state->revert_in_progress = 1;
1693 - oidcpy(&state->revert_head_oid, &null_oid);
1693 + oidcpy(&state->revert_head_oid, null_oid());
1694 }
1695 }
1696 if (get_detached_from)
xdiff-interface.c
+1 -1
@@ -172,7 +172,7 @@ void read_mmblob(mmfile_t *ptr, const struct object_id *oid)
172 unsigned long size;
173 enum object_type type;
174
175 - if (oideq(oid, &null_oid)) {
175 + if (oideq(oid, null_oid())) {
176 ptr->ptr = xstrdup("");
177 ptr->size = 0;
178 return;