usage: allow dying without writing an error message

Sometimes code wants to die in a situation where it already has written
an error message. To use the same error code as `die()` we have to use
`exit(128)`, which is easy to get wrong and leaves magic numbers all
over our codebase.

Teach `die_message_builtin()` to not print any error when passed a
`NULL` pointer as error string. Like this, such users can now call
`die(NULL)` to achieve the same result without any hardcoded error
codes.

Adapt a couple of builtins to use this new pattern to demonstrate that
there is a need for such a helper.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2025-06-03 16:01:18 +02:00
committed by Junio C Hamano
parent c367852d9e
commit 697202b0b1
5 changed files with 13 additions and 11 deletions

View File

@@ -1000,7 +1000,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
if (!patch_format) { if (!patch_format) {
fprintf_ln(stderr, _("Patch format detection failed.")); fprintf_ln(stderr, _("Patch format detection failed."));
exit(128); die(NULL);
} }
if (mkdir(state->dir, 0777) < 0 && errno != EEXIST) if (mkdir(state->dir, 0777) < 0 && errno != EEXIST)
@@ -1178,7 +1178,7 @@ static void NORETURN die_user_resolve(const struct am_state *state)
strbuf_release(&sb); strbuf_release(&sb);
} }
exit(128); die(NULL);
} }
/** /**

View File

@@ -838,7 +838,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
init_tree_desc(&trees[0], &tree->object.oid, init_tree_desc(&trees[0], &tree->object.oid,
tree->buffer, tree->size); tree->buffer, tree->size);
if (parse_tree(new_tree) < 0) if (parse_tree(new_tree) < 0)
exit(128); die(NULL);
tree = new_tree; tree = new_tree;
init_tree_desc(&trees[1], &tree->object.oid, init_tree_desc(&trees[1], &tree->object.oid,
tree->buffer, tree->size); tree->buffer, tree->size);
@@ -913,7 +913,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
work, work,
old_tree); old_tree);
if (ret < 0) if (ret < 0)
exit(128); die(NULL);
ret = reset_tree(new_tree, ret = reset_tree(new_tree,
opts, 0, opts, 0,
writeout_error, new_branch_info); writeout_error, new_branch_info);

View File

@@ -992,7 +992,7 @@ static int update_local_ref(struct ref *ref,
fast_forward = repo_in_merge_bases(the_repository, current, fast_forward = repo_in_merge_bases(the_repository, current,
updated); updated);
if (fast_forward < 0) if (fast_forward < 0)
exit(128); die(NULL);
forced_updates_ms += (getnanotime() - t_before) / 1000000; forced_updates_ms += (getnanotime() - t_before) / 1000000;
} else { } else {
fast_forward = 1; fast_forward = 1;

View File

@@ -303,7 +303,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
char *displaypath; char *displaypath;
if (validate_submodule_path(path) < 0) if (validate_submodule_path(path) < 0)
exit(128); die(NULL);
displaypath = get_submodule_displaypath(path, info->prefix, displaypath = get_submodule_displaypath(path, info->prefix,
info->super_prefix); info->super_prefix);
@@ -643,7 +643,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
}; };
if (validate_submodule_path(path) < 0) if (validate_submodule_path(path) < 0)
exit(128); die(NULL);
if (!submodule_from_path(the_repository, null_oid(the_hash_algo), path)) if (!submodule_from_path(the_repository, null_oid(the_hash_algo), path))
die(_("no submodule mapping found in .gitmodules for path '%s'"), die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -1257,7 +1257,7 @@ static void sync_submodule(const char *path, const char *prefix,
return; return;
if (validate_submodule_path(path) < 0) if (validate_submodule_path(path) < 0)
exit(128); die(NULL);
sub = submodule_from_path(the_repository, null_oid(the_hash_algo), path); sub = submodule_from_path(the_repository, null_oid(the_hash_algo), path);
@@ -1402,7 +1402,7 @@ static void deinit_submodule(const char *path, const char *prefix,
char *sub_git_dir = xstrfmt("%s/.git", path); char *sub_git_dir = xstrfmt("%s/.git", path);
if (validate_submodule_path(path) < 0) if (validate_submodule_path(path) < 0)
exit(128); die(NULL);
sub = submodule_from_path(the_repository, null_oid(the_hash_algo), path); sub = submodule_from_path(the_repository, null_oid(the_hash_algo), path);
@@ -1724,7 +1724,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
char *to_free = NULL; char *to_free = NULL;
if (validate_submodule_path(clone_data_path) < 0) if (validate_submodule_path(clone_data_path) < 0)
exit(128); die(NULL);
if (!is_absolute_path(clone_data->path)) if (!is_absolute_path(clone_data->path))
clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository), clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository),
@@ -3524,7 +3524,7 @@ static int module_add(int argc, const char **argv, const char *prefix,
strip_dir_trailing_slashes(add_data.sm_path); strip_dir_trailing_slashes(add_data.sm_path);
if (validate_submodule_path(add_data.sm_path) < 0) if (validate_submodule_path(add_data.sm_path) < 0)
exit(128); die(NULL);
die_on_index_match(add_data.sm_path, force); die_on_index_match(add_data.sm_path, force);
die_on_repo_without_commits(add_data.sm_path); die_on_repo_without_commits(add_data.sm_path);

View File

@@ -67,6 +67,8 @@ static NORETURN void usage_builtin(const char *err, va_list params)
static void die_message_builtin(const char *err, va_list params) static void die_message_builtin(const char *err, va_list params)
{ {
if (!err)
return;
trace2_cmd_error_va(err, params); trace2_cmd_error_va(err, params);
vreportf(_("fatal: "), err, params); vreportf(_("fatal: "), err, params);
} }