* [PATCH v1] environment: migrate encoding settings to repo-settings
@ 2026-02-28 4:07 Tian Yuchen
2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Tian Yuchen @ 2026-02-28 4:07 UTC (permalink / raw)
To: git; +Cc: gitster, karthik.188
Global variables 'git_commit_encoding' and 'git_log_output_encoding'
hinder the ongoing libification effort by binding functions to a
single global state.
Move both variables into 'struct repo_settings' to enable lazy loading.
They are migrated together in this patch because the log encoding
directly falls back to the commit encoding.
Update callers to use the new 'repo_get_commit_output_encoding()' and
'repo_get_log_output_encoding()' apis. Functions now accept 'struct
repository' to bubble up dependency where possible. For callers in the
'builtin/' directory, and for core library functions that do not yet
receive a repository context, 'the_repository' is used as a fallback.
Additionally, in 'revision.c', ensure 'prepare_repo_settings()' is
triggered before CLI overrides, for example, '--encoding', to prevent
lazy-loading from mistakenly overwriting command-line choice later.
All tests passed, no memory leak.
Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
---
This patch serves as a proof of concept for migration workflow preposed
in my GSoC 2026 proposal, regarding global state libification.
The patch has been verified against the full test suite and compiled with
'SANITIZE=address,undefined' to ensure clean memory ownership.
Any thought on whether this patch meets the project's standards would be
deeply appreciated.
Regards, Yuchen
builtin/am.c | 4 ++--
builtin/blame.c | 2 +-
builtin/commit.c | 6 +++---
builtin/log.c | 2 +-
builtin/mailinfo.c | 2 +-
builtin/rev-list.c | 2 +-
builtin/shortlog.c | 2 +-
bundle.c | 2 +-
commit.c | 6 +++---
environment.c | 37 +++++++++++--------------------------
environment.h | 7 ++-----
log-tree.c | 4 ++--
pretty.c | 2 +-
remote-curl.c | 3 ++-
replay.c | 2 +-
repo-settings.c | 7 +++++++
repo-settings.h | 3 +++
revision.c | 11 ++++++-----
sequencer.c | 16 ++++++++--------
submodule.c | 2 +-
20 files changed, 58 insertions(+), 64 deletions(-)
diff --git a/builtin/am.c b/builtin/am.c
index e0c767e223..96b8c00007 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail)
setup_mailinfo(the_repository, &mi);
if (state->utf8)
- mi.metainfo_charset = get_commit_output_encoding();
+ mi.metainfo_charset = repo_get_commit_output_encoding(the_repository);
else
mi.metainfo_charset = NULL;
@@ -1355,7 +1355,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit)
struct ident_split id;
buffer = repo_logmsg_reencode(the_repository, commit, NULL,
- get_commit_output_encoding());
+ repo_get_commit_output_encoding(the_repository));
ident_line = find_commit_header(buffer, "author", &ident_len);
if (!ident_line)
diff --git a/builtin/blame.c b/builtin/blame.c
index eac2fe7320..cc82182c51 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -202,7 +202,7 @@ static void get_commit_info(struct commit *commit, struct commit_info *ret)
const char *subject, *encoding;
const char *message;
- encoding = get_log_output_encoding();
+ encoding = repo_get_log_output_encoding(the_repository);
message = repo_logmsg_reencode(the_repository, commit, NULL, encoding);
get_ac_line(message, "\nauthor ",
&ret->author, &ret->author_mail,
diff --git a/builtin/commit.c b/builtin/commit.c
index 9e3a09d532..2bbdd4c4c3 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -794,7 +794,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
c = lookup_commit_reference_by_name(squash_message);
if (!c)
die(_("could not lookup commit '%s'"), squash_message);
- ctx.output_encoding = get_commit_output_encoding();
+ ctx.output_encoding = repo_get_commit_output_encoding(the_repository);
repo_format_commit_message(the_repository, c,
"squash! %s\n\n", &sb,
&ctx);
@@ -829,7 +829,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
commit = lookup_commit_reference_by_name(fixup_commit);
if (!commit)
die(_("could not lookup commit '%s'"), fixup_commit);
- ctx.output_encoding = get_commit_output_encoding();
+ ctx.output_encoding = repo_get_commit_output_encoding(the_repository);
fmt = xstrfmt("%s! %%s\n\n", fixup_prefix);
repo_format_commit_message(the_repository, commit, fmt, &sb,
&ctx);
@@ -1235,7 +1235,7 @@ static const char *read_commit_message(const char *name)
commit = lookup_commit_reference_by_name(name);
if (!commit)
die(_("could not lookup commit '%s'"), name);
- out_enc = get_commit_output_encoding();
+ out_enc = repo_get_commit_output_encoding(the_repository);
return repo_logmsg_reencode(the_repository, commit, NULL, out_enc);
}
diff --git a/builtin/log.c b/builtin/log.c
index 8ab6d3a943..1c9ec09098 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -568,7 +568,7 @@ static void show_tagger(const char *buf, struct rev_info *rev)
pp.fmt = rev->commit_format;
pp.date_mode = rev->date_mode;
- pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
+ pp_user_info(&pp, "Tagger", &out, buf, repo_get_log_output_encoding(the_repository));
fprintf(rev->diffopt.file, "%s", out.buf);
strbuf_release(&out);
}
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index 8de7ba7de1..eab4e05850 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -93,7 +93,7 @@ int cmd_mailinfo(int argc,
switch (meta_charset.policy) {
case CHARSET_DEFAULT:
- mi.metainfo_charset = get_commit_output_encoding();
+ mi.metainfo_charset = repo_get_commit_output_encoding(the_repository);
break;
case CHARSET_NO_REENCODE:
mi.metainfo_charset = NULL;
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index ddea8aa251..3c6a2914d8 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -304,7 +304,7 @@ static void show_commit(struct commit *commit, void *data)
ctx.date_mode = revs->date_mode;
ctx.date_mode_explicit = revs->date_mode_explicit;
ctx.fmt = revs->commit_format;
- ctx.output_encoding = get_log_output_encoding();
+ ctx.output_encoding = repo_get_log_output_encoding(the_repository);
ctx.color = revs->diffopt.use_color;
ctx.rev = revs;
pretty_print_commit(&ctx, commit, &buf);
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index d80bf1a7d0..ce9f20de2f 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -248,7 +248,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
ctx.fmt = CMIT_FMT_USERFORMAT;
ctx.abbrev = log->abbrev;
ctx.date_mode = log->date_mode;
- ctx.output_encoding = get_log_output_encoding();
+ ctx.output_encoding = repo_get_log_output_encoding(the_repository);
if (!log->summary) {
if (log->user_format)
diff --git a/bundle.c b/bundle.c
index 42327f9739..7914a57b43 100644
--- a/bundle.c
+++ b/bundle.c
@@ -461,7 +461,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data)
write_or_die(bpi->fd, buf.buf, buf.len);
ctx.fmt = CMIT_FMT_ONELINE;
- ctx.output_encoding = get_log_output_encoding();
+ ctx.output_encoding = repo_get_log_output_encoding(the_repository);
strbuf_reset(&buf);
pretty_print_commit(&ctx, commit, &buf);
strbuf_trim(&buf);
diff --git a/commit.c b/commit.c
index d16ae73345..d558db52dc 100644
--- a/commit.c
+++ b/commit.c
@@ -1673,7 +1673,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
size_t i;
/* Not having i18n.commitencoding is the same as having utf-8 */
- encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
+ encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository));
strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */
strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree));
@@ -1694,7 +1694,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
committer = git_committer_info(IDENT_STRICT);
strbuf_addf(buffer, "committer %s\n", committer);
if (!encoding_is_utf8)
- strbuf_addf(buffer, "encoding %s\n", git_commit_encoding);
+ strbuf_addf(buffer, "encoding %s\n", repo_get_commit_output_encoding(the_repository));
while (extra) {
add_extra_header(buffer, extra);
@@ -1723,7 +1723,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
size_t i, nparents;
/* Not having i18n.commitencoding is the same as having utf-8 */
- encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
+ encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository));
odb_assert_oid_type(the_repository->objects, tree, OBJ_TREE);
diff --git a/environment.c b/environment.c
index 0026eb2274..9c2a26c3c1 100644
--- a/environment.c
+++ b/environment.c
@@ -50,8 +50,6 @@ int ignore_case;
int assume_unchanged;
int is_bare_repository_cfg = -1; /* unspecified */
int warn_on_object_refname_ambiguity = 1;
-char *git_commit_encoding;
-char *git_log_output_encoding;
char *apply_default_whitespace;
char *apply_default_ignorewhitespace;
char *git_attributes_file;
@@ -197,15 +195,21 @@ const char *strip_namespace(const char *namespaced_ref)
return NULL;
}
-const char *get_log_output_encoding(void)
+const char *repo_get_log_output_encoding(struct repository *r)
{
- return git_log_output_encoding ? git_log_output_encoding
- : get_commit_output_encoding();
+ prepare_repo_settings(r);
+
+ return r->settings.log_output_encoding ?
+ r->settings.log_output_encoding :
+ repo_get_commit_output_encoding(r);
}
-const char *get_commit_output_encoding(void)
+const char *repo_get_commit_output_encoding(struct repository *r)
{
- return git_commit_encoding ? git_commit_encoding : "UTF-8";
+ prepare_repo_settings(r);
+
+ return r->settings.commit_encoding ?
+ r->settings.commit_encoding : "UTF-8";
}
int use_optional_locks(void)
@@ -566,22 +570,6 @@ static int git_default_sparse_config(const char *var, const char *value)
return 0;
}
-static int git_default_i18n_config(const char *var, const char *value)
-{
- if (!strcmp(var, "i18n.commitencoding")) {
- FREE_AND_NULL(git_commit_encoding);
- return git_config_string(&git_commit_encoding, var, value);
- }
-
- if (!strcmp(var, "i18n.logoutputencoding")) {
- FREE_AND_NULL(git_log_output_encoding);
- return git_config_string(&git_log_output_encoding, var, value);
- }
-
- /* Add other config variables here and to Documentation/config.adoc. */
- return 0;
-}
-
static int git_default_branch_config(const char *var, const char *value)
{
if (!strcmp(var, "branch.autosetupmerge")) {
@@ -688,9 +676,6 @@ int git_default_config(const char *var, const char *value,
starts_with(var, "committer."))
return git_ident_config(var, value, ctx, cb);
- if (starts_with(var, "i18n."))
- return git_default_i18n_config(var, value);
-
if (starts_with(var, "branch."))
return git_default_branch_config(var, value);
diff --git a/environment.h b/environment.h
index 27f657af04..eba8d5786c 100644
--- a/environment.h
+++ b/environment.h
@@ -193,11 +193,8 @@ extern enum object_creation_mode object_creation_mode;
extern int grafts_keep_true_parents;
-const char *get_log_output_encoding(void);
-const char *get_commit_output_encoding(void);
-
-extern char *git_commit_encoding;
-extern char *git_log_output_encoding;
+const char *repo_get_log_output_encoding(struct repository *r);
+const char *repo_get_commit_output_encoding(struct repository *r);
extern char *editor_program;
extern char *askpass_program;
diff --git a/log-tree.c b/log-tree.c
index 7e048701d0..aea3cbf7c6 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -859,7 +859,7 @@ void show_log(struct rev_info *opt)
raw = (opt->commit_format == CMIT_FMT_USERFORMAT);
format_display_notes(&commit->object.oid, ¬ebuf,
- get_log_output_encoding(), raw);
+ repo_get_log_output_encoding(the_repository), raw);
ctx.notes_message = strbuf_detach(¬ebuf, NULL);
}
@@ -879,7 +879,7 @@ void show_log(struct rev_info *opt)
ctx.mailmap = opt->mailmap;
ctx.color = opt->diffopt.use_color;
ctx.expand_tabs_in_log = opt->expand_tabs_in_log;
- ctx.output_encoding = get_log_output_encoding();
+ ctx.output_encoding = repo_get_log_output_encoding(the_repository);
ctx.rev = opt;
if (opt->from_ident.mail_begin && opt->from_ident.name_begin)
ctx.from_ident = &opt->from_ident;
diff --git a/pretty.c b/pretty.c
index e0646bbc5d..e939d0ff3b 100644
--- a/pretty.c
+++ b/pretty.c
@@ -2298,7 +2298,7 @@ void pretty_print_commit(struct pretty_print_context *pp,
return;
}
- encoding = get_log_output_encoding();
+ encoding = repo_get_log_output_encoding(the_repository);
msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL,
encoding);
diff --git a/remote-curl.c b/remote-curl.c
index 92e40bb682..cd7e5e701a 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -379,7 +379,8 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset,
if (strcmp(type->buf, "text/plain"))
return -1;
if (charset->len)
- strbuf_reencode(msg, charset->buf, get_log_output_encoding());
+ strbuf_reencode(msg, charset->buf,
+ repo_get_log_output_encoding(the_repository));
strbuf_trim(msg);
if (!msg->len)
diff --git a/replay.c b/replay.c
index f97d652f33..45d539f8fc 100644
--- a/replay.c
+++ b/replay.c
@@ -56,7 +56,7 @@ static struct commit *create_commit(struct repository *repo,
char *sign_commit = NULL; /* FIXME: cli users might want to sign again */
struct commit_extra_header *extra = NULL;
struct strbuf msg = STRBUF_INIT;
- const char *out_enc = get_commit_output_encoding();
+ const char *out_enc = repo_get_commit_output_encoding(repo);
const char *message = repo_logmsg_reencode(repo, based_on,
NULL, out_enc);
const char *orig_message = NULL;
diff --git a/repo-settings.c b/repo-settings.c
index 208e09ff17..de3b4c6ef1 100644
--- a/repo-settings.c
+++ b/repo-settings.c
@@ -32,6 +32,7 @@ void prepare_repo_settings(struct repository *r)
int experimental;
int value;
const char *strval;
+ char *alloc_strval;
int manyfiles;
int read_changed_paths;
unsigned long ulongval;
@@ -154,6 +155,12 @@ void prepare_repo_settings(struct repository *r)
if (!repo_config_get_ulong(r, "core.packedgitlimit", &ulongval))
r->settings.packed_git_limit = ulongval;
+
+ if (!repo_config_get_string(r, "i18n.commitencoding", &alloc_strval))
+ r->settings.commit_encoding = alloc_strval;
+
+ if (!repo_config_get_string(r, "i18n.logoutputencoding", &alloc_strval))
+ r->settings.log_output_encoding = alloc_strval;
}
void repo_settings_clear(struct repository *r)
diff --git a/repo-settings.h b/repo-settings.h
index cad9c3f0cc..9a6b91a3a9 100644
--- a/repo-settings.h
+++ b/repo-settings.h
@@ -70,6 +70,9 @@ struct repo_settings {
int max_allowed_tree_depth;
char *hooks_path;
+
+ char *commit_encoding;
+ char *log_output_encoding;
};
#define REPO_SETTINGS_INIT { \
.shared_repository = -1, \
diff --git a/revision.c b/revision.c
index 29972c3a19..961ecd1d6c 100644
--- a/revision.c
+++ b/revision.c
@@ -2675,11 +2675,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
} else if (!strcmp(arg, "--invert-grep")) {
revs->grep_filter.no_body_match = 1;
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
- free(git_log_output_encoding);
+ prepare_repo_settings(revs->repo);
+ free(revs->repo->settings.log_output_encoding);
if (strcmp(optarg, "none"))
- git_log_output_encoding = xstrdup(optarg);
+ revs->repo->settings.log_output_encoding = xstrdup(optarg);
else
- git_log_output_encoding = xstrdup("");
+ revs->repo->settings.log_output_encoding = xstrdup("");
return argcount;
} else if (!strcmp(arg, "--reverse")) {
revs->reverse ^= 1;
@@ -3129,7 +3130,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
diff_setup_done(&revs->diffopt);
- if (!is_encoding_utf8(get_log_output_encoding()))
+ if (!is_encoding_utf8(repo_get_log_output_encoding(the_repository)))
revs->grep_filter.ignore_locale = 1;
compile_grep_patterns(&revs->grep_filter);
@@ -4063,7 +4064,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
* so we will not end up with a buffer that has two different encodings
* in it.
*/
- encoding = get_log_output_encoding();
+ encoding = repo_get_log_output_encoding(the_repository);
message = repo_logmsg_reencode(the_repository, commit, NULL, encoding);
/* Copy the commit to temporary if we are using "fake" headers */
diff --git a/sequencer.c b/sequencer.c
index a3eb39bb25..612f47fd12 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -486,7 +486,7 @@ static int get_message(struct commit *commit, struct commit_message *out)
int subject_len;
out->message = repo_logmsg_reencode(the_repository, commit, NULL,
- get_commit_output_encoding());
+ repo_get_commit_output_encoding(the_repository));
abbrev = short_commit_name(the_repository, commit);
subject_len = find_commit_subject(out->message, &subject);
@@ -1539,7 +1539,7 @@ static int try_to_commit(struct repository *r,
if (flags & AMEND_MSG) {
const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };
- const char *out_enc = get_commit_output_encoding();
+ const char *out_enc = repo_get_commit_output_encoding(r);
const char *message = repo_logmsg_reencode(r, current_head,
NULL, out_enc);
@@ -2054,7 +2054,7 @@ static int update_squash_messages(struct repository *r,
struct strbuf buf = STRBUF_INIT;
int res = 0;
const char *message, *body;
- const char *encoding = get_commit_output_encoding();
+ const char *encoding = repo_get_commit_output_encoding(r);
if (!is_fixup(command))
BUG("not a FIXUP or SQUASH %d", command);
@@ -3344,7 +3344,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list,
if (prepare_revs(opts))
return -1;
- encoding = get_log_output_encoding();
+ encoding = repo_get_log_output_encoding(the_repository);
while ((commit = get_revision(opts->revs))) {
struct todo_item *item = append_new_todo(todo_list);
@@ -3730,7 +3730,7 @@ static int make_patch(struct repository *r,
}
if (!file_exists(rebase_path_message())) {
- const char *encoding = get_commit_output_encoding();
+ const char *encoding = repo_get_commit_output_encoding(r);
const char *commit_buffer = repo_logmsg_reencode(r,
commit, NULL,
encoding);
@@ -4187,7 +4187,7 @@ static int do_merge(struct repository *r,
}
if (commit) {
- const char *encoding = get_commit_output_encoding();
+ const char *encoding = repo_get_commit_output_encoding(r);
const char *message = repo_logmsg_reencode(r, commit, NULL,
encoding);
const char *body;
@@ -5311,7 +5311,7 @@ static int commit_staged_changes(struct repository *r,
struct commit *commit;
const char *msg;
const char *path = rebase_path_squash_msg();
- const char *encoding = get_commit_output_encoding();
+ const char *encoding = repo_get_commit_output_encoding(r);
if (parse_head(r, &commit)) {
ret = error(_("could not parse HEAD"));
@@ -6092,7 +6092,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out,
get_commit_format(format, &revs);
free(format);
pp.fmt = revs.commit_format;
- pp.output_encoding = get_log_output_encoding();
+ pp.output_encoding = repo_get_log_output_encoding(r);
setup_revisions_from_strvec(argv, &revs, NULL);
if (argv->nr > 1) {
diff --git a/submodule.c b/submodule.c
index 508938e4da..59f5c79d7f 100644
--- a/submodule.c
+++ b/submodule.c
@@ -479,7 +479,7 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info *
while ((commit = get_revision(rev))) {
struct pretty_print_context ctx = {0};
ctx.date_mode = rev->date_mode;
- ctx.output_encoding = get_log_output_encoding();
+ ctx.output_encoding = repo_get_log_output_encoding(r);
strbuf_setlen(&sb, 0);
repo_format_commit_message(r, commit, format, &sb,
&ctx);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 0/3] migrate encoding settings and bubble up repository 2026-02-28 4:07 [PATCH v1] environment: migrate encoding settings to repo-settings Tian Yuchen @ 2026-02-28 19:01 ` Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 1/3] environment: migrate encoding settings to repo-settings Tian Yuchen ` (2 more replies) 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen 2 siblings, 3 replies; 13+ messages in thread From: Tian Yuchen @ 2026-02-28 19:01 UTC (permalink / raw) To: git; +Cc: karthik.188, gitster Hi everyone, As part of the ongoing libification effort and my GSoC 2026 proposal, this series migrates commit and log encoding settings into 'struct repo_settings' and bubbles up the 'struct repository *' dependency. Previously, 'git_commit_encoding' and 'git_log_output_encoding' were global, where core APIs implicitly rely on 'the_repository'. This series resolves this in three steps: - Patch 1: Moves encoding configs into 'repo_settings' using lazy -loading, safely handling CLI overrides in 'revision.c'. - Patch 2: Updates 'commit_tree()' and related APIs in 'commit.c' to accept a repository context, passing it down the call chain. - Patch 3: Updates 'pretty_print_commit()' and 'pp_commit_easy()'. We leverage existing contextual pointers ('diffopt->repo' and 'revs->repo') to pass the repository downwards. To maintain a clean boundary, leaf callers in 'builtin/' and top-level components (e.g., 'bundle.c') fall back to 'the_repository'. (Though series passes the full test suite and is verified with 'S ANITIZE=address,undefined', I'm quite certain I must have inadvertently left out some parts. Therefore, this patch series is currently more of a self-archival exercise than a final submission. For example, I might have left out some of the exsiting contextual pointers in patch 2. Will check in the following days.) Regards, Yuchen Tian Yuchen (3): environment: migrate encoding settings to repo-settings commit: pass 'struct repository' to commit creation APIs pretty: pass 'struct repository' to pretty_print_commit() builtin/am.c | 6 +++--- builtin/blame.c | 2 +- builtin/checkout.c | 4 ++-- builtin/commit-tree.c | 2 +- builtin/commit.c | 8 ++++---- builtin/history.c | 2 +- builtin/log.c | 4 ++-- builtin/mailinfo.c | 2 +- builtin/merge.c | 6 +++--- builtin/rebase.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 4 ++-- builtin/shortlog.c | 4 ++-- builtin/show-branch.c | 2 +- builtin/stash.c | 12 ++++++------ bundle.c | 4 ++-- commit.c | 31 +++++++++++++++++-------------- commit.h | 6 ++++-- diff.c | 2 +- environment.c | 37 +++++++++++-------------------------- environment.h | 7 ++----- log-tree.c | 6 +++--- notes-cache.c | 4 ++-- notes-cache.h | 2 +- notes-utils.c | 2 +- pretty.c | 13 +++++++------ pretty.h | 4 ++-- range-diff.c | 10 +++++----- remote-curl.c | 3 ++- replay.c | 4 ++-- repo-settings.c | 7 +++++++ repo-settings.h | 3 +++ revision.c | 11 ++++++----- sequencer.c | 36 ++++++++++++++++++------------------ submodule.c | 2 +- 35 files changed, 128 insertions(+), 128 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/3] environment: migrate encoding settings to repo-settings 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen @ 2026-02-28 19:01 ` Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 2/3] commit: pass 'struct repository' to commit creation APIs Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 3/3] pretty: pass 'struct repository' to pretty_print_commit() Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-02-28 19:01 UTC (permalink / raw) To: git; +Cc: karthik.188, gitster Global variables 'git_commit_encoding' and 'git_log_output_encoding' hinder the ongoing libification effort by binding functions to a single global state. Move both variables into 'struct repo_settings' to enable lazy loading. They are migrated together in this patch because the log encoding directly falls back to the commit encoding. Update callers to use the new 'repo_get_commit_output_encoding()' and 'repo_get_log_output_encoding()' apis. Functions now accept 'struct repository' to bubble up dependency where possible. For callers in the 'builtin/' directory, and for core library functions that do not yet receive a repository context, 'the_repository' is used as a fallback. Additionally, in 'revision.c', ensure 'prepare_repo_settings()' is triggered before CLI overrides, for example, '--encoding', to prevent lazy-loading from mistakenly overwriting command-line choice later. All tests passed, no memory leak. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 4 ++-- builtin/blame.c | 2 +- builtin/commit.c | 6 +++--- builtin/log.c | 2 +- builtin/mailinfo.c | 2 +- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- bundle.c | 2 +- commit.c | 6 +++--- environment.c | 37 +++++++++++-------------------------- environment.h | 7 ++----- log-tree.c | 4 ++-- pretty.c | 2 +- remote-curl.c | 3 ++- replay.c | 2 +- repo-settings.c | 7 +++++++ repo-settings.h | 3 +++ revision.c | 11 ++++++----- sequencer.c | 16 ++++++++-------- submodule.c | 2 +- 20 files changed, 58 insertions(+), 64 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index e0c767e223..96b8c00007 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail) setup_mailinfo(the_repository, &mi); if (state->utf8) - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = repo_get_commit_output_encoding(the_repository); else mi.metainfo_charset = NULL; @@ -1355,7 +1355,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit) struct ident_split id; buffer = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + repo_get_commit_output_encoding(the_repository)); ident_line = find_commit_header(buffer, "author", &ident_len); if (!ident_line) diff --git a/builtin/blame.c b/builtin/blame.c index eac2fe7320..cc82182c51 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -202,7 +202,7 @@ static void get_commit_info(struct commit *commit, struct commit_info *ret) const char *subject, *encoding; const char *message; - encoding = get_log_output_encoding(); + encoding = repo_get_log_output_encoding(the_repository); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); get_ac_line(message, "\nauthor ", &ret->author, &ret->author_mail, diff --git a/builtin/commit.c b/builtin/commit.c index 9e3a09d532..2bbdd4c4c3 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -794,7 +794,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, c = lookup_commit_reference_by_name(squash_message); if (!c) die(_("could not lookup commit '%s'"), squash_message); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = repo_get_commit_output_encoding(the_repository); repo_format_commit_message(the_repository, c, "squash! %s\n\n", &sb, &ctx); @@ -829,7 +829,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, commit = lookup_commit_reference_by_name(fixup_commit); if (!commit) die(_("could not lookup commit '%s'"), fixup_commit); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = repo_get_commit_output_encoding(the_repository); fmt = xstrfmt("%s! %%s\n\n", fixup_prefix); repo_format_commit_message(the_repository, commit, fmt, &sb, &ctx); @@ -1235,7 +1235,7 @@ static const char *read_commit_message(const char *name) commit = lookup_commit_reference_by_name(name); if (!commit) die(_("could not lookup commit '%s'"), name); - out_enc = get_commit_output_encoding(); + out_enc = repo_get_commit_output_encoding(the_repository); return repo_logmsg_reencode(the_repository, commit, NULL, out_enc); } diff --git a/builtin/log.c b/builtin/log.c index 8ab6d3a943..1c9ec09098 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -568,7 +568,7 @@ static void show_tagger(const char *buf, struct rev_info *rev) pp.fmt = rev->commit_format; pp.date_mode = rev->date_mode; - pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding()); + pp_user_info(&pp, "Tagger", &out, buf, repo_get_log_output_encoding(the_repository)); fprintf(rev->diffopt.file, "%s", out.buf); strbuf_release(&out); } diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 8de7ba7de1..eab4e05850 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -93,7 +93,7 @@ int cmd_mailinfo(int argc, switch (meta_charset.policy) { case CHARSET_DEFAULT: - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = repo_get_commit_output_encoding(the_repository); break; case CHARSET_NO_REENCODE: mi.metainfo_charset = NULL; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index ddea8aa251..3c6a2914d8 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -304,7 +304,7 @@ static void show_commit(struct commit *commit, void *data) ctx.date_mode = revs->date_mode; ctx.date_mode_explicit = revs->date_mode_explicit; ctx.fmt = revs->commit_format; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = repo_get_log_output_encoding(the_repository); ctx.color = revs->diffopt.use_color; ctx.rev = revs; pretty_print_commit(&ctx, commit, &buf); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index d80bf1a7d0..ce9f20de2f 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -248,7 +248,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) ctx.fmt = CMIT_FMT_USERFORMAT; ctx.abbrev = log->abbrev; ctx.date_mode = log->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = repo_get_log_output_encoding(the_repository); if (!log->summary) { if (log->user_format) diff --git a/bundle.c b/bundle.c index 42327f9739..7914a57b43 100644 --- a/bundle.c +++ b/bundle.c @@ -461,7 +461,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) write_or_die(bpi->fd, buf.buf, buf.len); ctx.fmt = CMIT_FMT_ONELINE; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = repo_get_log_output_encoding(the_repository); strbuf_reset(&buf); pretty_print_commit(&ctx, commit, &buf); strbuf_trim(&buf); diff --git a/commit.c b/commit.c index d16ae73345..d558db52dc 100644 --- a/commit.c +++ b/commit.c @@ -1673,7 +1673,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg size_t i; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository)); strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */ strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree)); @@ -1694,7 +1694,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg committer = git_committer_info(IDENT_STRICT); strbuf_addf(buffer, "committer %s\n", committer); if (!encoding_is_utf8) - strbuf_addf(buffer, "encoding %s\n", git_commit_encoding); + strbuf_addf(buffer, "encoding %s\n", repo_get_commit_output_encoding(the_repository)); while (extra) { add_extra_header(buffer, extra); @@ -1723,7 +1723,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, size_t i, nparents; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository)); odb_assert_oid_type(the_repository->objects, tree, OBJ_TREE); diff --git a/environment.c b/environment.c index 0026eb2274..9c2a26c3c1 100644 --- a/environment.c +++ b/environment.c @@ -50,8 +50,6 @@ int ignore_case; int assume_unchanged; int is_bare_repository_cfg = -1; /* unspecified */ int warn_on_object_refname_ambiguity = 1; -char *git_commit_encoding; -char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; char *git_attributes_file; @@ -197,15 +195,21 @@ const char *strip_namespace(const char *namespaced_ref) return NULL; } -const char *get_log_output_encoding(void) +const char *repo_get_log_output_encoding(struct repository *r) { - return git_log_output_encoding ? git_log_output_encoding - : get_commit_output_encoding(); + prepare_repo_settings(r); + + return r->settings.log_output_encoding ? + r->settings.log_output_encoding : + repo_get_commit_output_encoding(r); } -const char *get_commit_output_encoding(void) +const char *repo_get_commit_output_encoding(struct repository *r) { - return git_commit_encoding ? git_commit_encoding : "UTF-8"; + prepare_repo_settings(r); + + return r->settings.commit_encoding ? + r->settings.commit_encoding : "UTF-8"; } int use_optional_locks(void) @@ -566,22 +570,6 @@ static int git_default_sparse_config(const char *var, const char *value) return 0; } -static int git_default_i18n_config(const char *var, const char *value) -{ - if (!strcmp(var, "i18n.commitencoding")) { - FREE_AND_NULL(git_commit_encoding); - return git_config_string(&git_commit_encoding, var, value); - } - - if (!strcmp(var, "i18n.logoutputencoding")) { - FREE_AND_NULL(git_log_output_encoding); - return git_config_string(&git_log_output_encoding, var, value); - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - static int git_default_branch_config(const char *var, const char *value) { if (!strcmp(var, "branch.autosetupmerge")) { @@ -688,9 +676,6 @@ int git_default_config(const char *var, const char *value, starts_with(var, "committer.")) return git_ident_config(var, value, ctx, cb); - if (starts_with(var, "i18n.")) - return git_default_i18n_config(var, value); - if (starts_with(var, "branch.")) return git_default_branch_config(var, value); diff --git a/environment.h b/environment.h index 27f657af04..eba8d5786c 100644 --- a/environment.h +++ b/environment.h @@ -193,11 +193,8 @@ extern enum object_creation_mode object_creation_mode; extern int grafts_keep_true_parents; -const char *get_log_output_encoding(void); -const char *get_commit_output_encoding(void); - -extern char *git_commit_encoding; -extern char *git_log_output_encoding; +const char *repo_get_log_output_encoding(struct repository *r); +const char *repo_get_commit_output_encoding(struct repository *r); extern char *editor_program; extern char *askpass_program; diff --git a/log-tree.c b/log-tree.c index 7e048701d0..aea3cbf7c6 100644 --- a/log-tree.c +++ b/log-tree.c @@ -859,7 +859,7 @@ void show_log(struct rev_info *opt) raw = (opt->commit_format == CMIT_FMT_USERFORMAT); format_display_notes(&commit->object.oid, ¬ebuf, - get_log_output_encoding(), raw); + repo_get_log_output_encoding(the_repository), raw); ctx.notes_message = strbuf_detach(¬ebuf, NULL); } @@ -879,7 +879,7 @@ void show_log(struct rev_info *opt) ctx.mailmap = opt->mailmap; ctx.color = opt->diffopt.use_color; ctx.expand_tabs_in_log = opt->expand_tabs_in_log; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = repo_get_log_output_encoding(the_repository); ctx.rev = opt; if (opt->from_ident.mail_begin && opt->from_ident.name_begin) ctx.from_ident = &opt->from_ident; diff --git a/pretty.c b/pretty.c index e0646bbc5d..e939d0ff3b 100644 --- a/pretty.c +++ b/pretty.c @@ -2298,7 +2298,7 @@ void pretty_print_commit(struct pretty_print_context *pp, return; } - encoding = get_log_output_encoding(); + encoding = repo_get_log_output_encoding(the_repository); msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL, encoding); diff --git a/remote-curl.c b/remote-curl.c index 92e40bb682..cd7e5e701a 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -379,7 +379,8 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset, if (strcmp(type->buf, "text/plain")) return -1; if (charset->len) - strbuf_reencode(msg, charset->buf, get_log_output_encoding()); + strbuf_reencode(msg, charset->buf, + repo_get_log_output_encoding(the_repository)); strbuf_trim(msg); if (!msg->len) diff --git a/replay.c b/replay.c index f97d652f33..45d539f8fc 100644 --- a/replay.c +++ b/replay.c @@ -56,7 +56,7 @@ static struct commit *create_commit(struct repository *repo, char *sign_commit = NULL; /* FIXME: cli users might want to sign again */ struct commit_extra_header *extra = NULL; struct strbuf msg = STRBUF_INIT; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = repo_get_commit_output_encoding(repo); const char *message = repo_logmsg_reencode(repo, based_on, NULL, out_enc); const char *orig_message = NULL; diff --git a/repo-settings.c b/repo-settings.c index 208e09ff17..de3b4c6ef1 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -32,6 +32,7 @@ void prepare_repo_settings(struct repository *r) int experimental; int value; const char *strval; + char *alloc_strval; int manyfiles; int read_changed_paths; unsigned long ulongval; @@ -154,6 +155,12 @@ void prepare_repo_settings(struct repository *r) if (!repo_config_get_ulong(r, "core.packedgitlimit", &ulongval)) r->settings.packed_git_limit = ulongval; + + if (!repo_config_get_string(r, "i18n.commitencoding", &alloc_strval)) + r->settings.commit_encoding = alloc_strval; + + if (!repo_config_get_string(r, "i18n.logoutputencoding", &alloc_strval)) + r->settings.log_output_encoding = alloc_strval; } void repo_settings_clear(struct repository *r) diff --git a/repo-settings.h b/repo-settings.h index cad9c3f0cc..9a6b91a3a9 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -70,6 +70,9 @@ struct repo_settings { int max_allowed_tree_depth; char *hooks_path; + + char *commit_encoding; + char *log_output_encoding; }; #define REPO_SETTINGS_INIT { \ .shared_repository = -1, \ diff --git a/revision.c b/revision.c index 29972c3a19..961ecd1d6c 100644 --- a/revision.c +++ b/revision.c @@ -2675,11 +2675,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--invert-grep")) { revs->grep_filter.no_body_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { - free(git_log_output_encoding); + prepare_repo_settings(revs->repo); + free(revs->repo->settings.log_output_encoding); if (strcmp(optarg, "none")) - git_log_output_encoding = xstrdup(optarg); + revs->repo->settings.log_output_encoding = xstrdup(optarg); else - git_log_output_encoding = xstrdup(""); + revs->repo->settings.log_output_encoding = xstrdup(""); return argcount; } else if (!strcmp(arg, "--reverse")) { revs->reverse ^= 1; @@ -3129,7 +3130,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s diff_setup_done(&revs->diffopt); - if (!is_encoding_utf8(get_log_output_encoding())) + if (!is_encoding_utf8(repo_get_log_output_encoding(the_repository))) revs->grep_filter.ignore_locale = 1; compile_grep_patterns(&revs->grep_filter); @@ -4063,7 +4064,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) * so we will not end up with a buffer that has two different encodings * in it. */ - encoding = get_log_output_encoding(); + encoding = repo_get_log_output_encoding(the_repository); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); /* Copy the commit to temporary if we are using "fake" headers */ diff --git a/sequencer.c b/sequencer.c index a3eb39bb25..612f47fd12 100644 --- a/sequencer.c +++ b/sequencer.c @@ -486,7 +486,7 @@ static int get_message(struct commit *commit, struct commit_message *out) int subject_len; out->message = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + repo_get_commit_output_encoding(the_repository)); abbrev = short_commit_name(the_repository, commit); subject_len = find_commit_subject(out->message, &subject); @@ -1539,7 +1539,7 @@ static int try_to_commit(struct repository *r, if (flags & AMEND_MSG) { const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL }; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = repo_get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, current_head, NULL, out_enc); @@ -2054,7 +2054,7 @@ static int update_squash_messages(struct repository *r, struct strbuf buf = STRBUF_INIT; int res = 0; const char *message, *body; - const char *encoding = get_commit_output_encoding(); + const char *encoding = repo_get_commit_output_encoding(r); if (!is_fixup(command)) BUG("not a FIXUP or SQUASH %d", command); @@ -3344,7 +3344,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list, if (prepare_revs(opts)) return -1; - encoding = get_log_output_encoding(); + encoding = repo_get_log_output_encoding(the_repository); while ((commit = get_revision(opts->revs))) { struct todo_item *item = append_new_todo(todo_list); @@ -3730,7 +3730,7 @@ static int make_patch(struct repository *r, } if (!file_exists(rebase_path_message())) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = repo_get_commit_output_encoding(r); const char *commit_buffer = repo_logmsg_reencode(r, commit, NULL, encoding); @@ -4187,7 +4187,7 @@ static int do_merge(struct repository *r, } if (commit) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = repo_get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, commit, NULL, encoding); const char *body; @@ -5311,7 +5311,7 @@ static int commit_staged_changes(struct repository *r, struct commit *commit; const char *msg; const char *path = rebase_path_squash_msg(); - const char *encoding = get_commit_output_encoding(); + const char *encoding = repo_get_commit_output_encoding(r); if (parse_head(r, &commit)) { ret = error(_("could not parse HEAD")); @@ -6092,7 +6092,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, get_commit_format(format, &revs); free(format); pp.fmt = revs.commit_format; - pp.output_encoding = get_log_output_encoding(); + pp.output_encoding = repo_get_log_output_encoding(r); setup_revisions_from_strvec(argv, &revs, NULL); if (argv->nr > 1) { diff --git a/submodule.c b/submodule.c index 508938e4da..59f5c79d7f 100644 --- a/submodule.c +++ b/submodule.c @@ -479,7 +479,7 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info * while ((commit = get_revision(rev))) { struct pretty_print_context ctx = {0}; ctx.date_mode = rev->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = repo_get_log_output_encoding(r); strbuf_setlen(&sb, 0); repo_format_commit_message(r, commit, format, &sb, &ctx); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/3] commit: pass 'struct repository' to commit creation APIs 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 1/3] environment: migrate encoding settings to repo-settings Tian Yuchen @ 2026-02-28 19:02 ` Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 3/3] pretty: pass 'struct repository' to pretty_print_commit() Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-02-28 19:02 UTC (permalink / raw) To: git; +Cc: karthik.188, gitster Following the migration of encoding settings into 'struct repo_settings', core commit creation functions in 'commit.c' now require a repository context to query the commit output encoding. Update the signatures of 'commit_tree()' and 'commit_tree_extended()', as well as the internal 'write_commit_tree()', to accept 'struct repository *' as their first argument so they can call 'repo_get_commit_output_encoding(r)/(repo)' without relying on the global 'the_repository' macro. Consequently, update all callers across the codebase to pass the repository context down the call chain. To facilitate this dependency bubbling, update the signatures of several intermediate helper functions, explicitly 'notes_cache_write()' and 'get_message()' (in sequencer.c). For callers in the 'builtin/' directory, fallback to using 'the_repository'. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 2 +- builtin/commit-tree.c | 2 +- builtin/commit.c | 2 +- builtin/history.c | 2 +- builtin/merge.c | 4 ++-- builtin/rebase.c | 2 +- builtin/stash.c | 10 +++++----- commit.c | 31 +++++++++++++++++-------------- commit.h | 6 ++++-- diff.c | 2 +- notes-cache.c | 4 ++-- notes-cache.h | 2 +- notes-utils.c | 2 +- replay.c | 2 +- sequencer.c | 12 ++++++------ 15 files changed, 45 insertions(+), 40 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 96b8c00007..eee3c9864c 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1699,7 +1699,7 @@ static void do_commit(const struct am_state *state) : state->author_date, IDENT_STRICT); - if (commit_tree_extended(state->msg, state->msg_len, &tree, parents, + if (commit_tree_extended(the_repository, state->msg, state->msg_len, &tree, parents, &commit, author, committer, state->sign_commit, NULL)) die(_("failed to write commit object")); diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 30535db131..c489749588 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -144,7 +144,7 @@ int cmd_commit_tree(int argc, die_errno(_("git commit-tree: failed to read")); } - if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, + if (commit_tree(the_repository, buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, NULL, sign_commit)) { ret = 1; goto out; diff --git a/builtin/commit.c b/builtin/commit.c index 2bbdd4c4c3..da2b8ce541 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1931,7 +1931,7 @@ int cmd_commit(int argc, append_merge_tag_headers(parents, &tail); } - if (commit_tree_extended(sb.buf, sb.len, &the_repository->index->cache_tree->oid, + if (commit_tree_extended(the_repository, sb.buf, sb.len, &the_repository->index->cache_tree->oid, parents, &oid, author_ident.buf, NULL, sign_commit, extra)) { rollback_index_files(); diff --git a/builtin/history.c b/builtin/history.c index 8dcb9a6046..ca36d065a5 100644 --- a/builtin/history.c +++ b/builtin/history.c @@ -136,7 +136,7 @@ static int commit_tree_with_edited_message(struct repository *repo, original_extra_headers = read_commit_extra_headers(original, exclude_gpgsig); - ret = commit_tree_extended(commit_message.buf, commit_message.len, &original_tree_oid, + ret = commit_tree_extended(the_repository, commit_message.buf, commit_message.len, &original_tree_oid, original->parents, &rewritten_commit_oid, original_author, NULL, NULL, original_extra_headers); if (ret < 0) diff --git a/builtin/merge.c b/builtin/merge.c index 4e456a381c..7c944fe179 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1000,7 +1000,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) pptr = commit_list_append(head, pptr); pptr = commit_list_append(remoteheads->item, pptr); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, &result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, &result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); finish(head, remoteheads, &result_commit, "In-index merge"); @@ -1027,7 +1027,7 @@ static int finish_automerge(struct commit *head, if (!head_subsumed || fast_forward == FF_NO) commit_list_insert(head, &parents); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy); diff --git a/builtin/rebase.c b/builtin/rebase.c index c487e10907..7b9ab85cc0 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1647,7 +1647,7 @@ int cmd_rebase(int argc, options.upstream_arg = options.upstream_name; } else { if (!options.onto_name) { - if (commit_tree("", 0, the_hash_algo->empty_tree, NULL, + if (commit_tree(the_repository, "", 0, the_hash_algo->empty_tree, NULL, &squash_onto, NULL, NULL) < 0) die(_("Could not create new root commit")); options.squash_onto = &squash_onto; diff --git a/builtin/stash.c b/builtin/stash.c index f06cfa7989..3d94726251 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1258,7 +1258,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, goto done; } - if (commit_tree(untracked_msg.buf, untracked_msg.len, + if (commit_tree(the_repository, untracked_msg.buf, untracked_msg.len, &info->u_tree, NULL, &info->u_commit, NULL, NULL)) { ret = -1; goto done; @@ -1486,7 +1486,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b commit_list_insert(head_commit, &parents); if (write_index_as_tree(&info->i_tree, the_repository->index, repo_get_index_file(the_repository), 0, NULL) || - commit_tree(commit_tree_label.buf, commit_tree_label.len, + commit_tree(the_repository, commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1551,7 +1551,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &parents); commit_list_insert(head_commit, &parents); - if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, + if (commit_tree(the_repository, stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, parents, &info->w_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot record " @@ -2035,7 +2035,7 @@ static int write_commit_with_parents(struct repository *r, author = xmemdupz(orig_author, author_len); committer = xmemdupz(orig_committer, committer_len); - if (commit_tree_extended(msg.buf, msg.len, + if (commit_tree_extended(the_repository, msg.buf, msg.len, r->hash_algo->empty_tree, parents, out, author, committer, NULL, NULL)) { @@ -2258,7 +2258,7 @@ static int do_export_stash(struct repository *r, "2001-09-17T00:00:00Z", 0); /* First, we create a single empty commit. */ - if (commit_tree_extended("", 0, r->hash_algo->empty_tree, NULL, + if (commit_tree_extended(the_repository, "", 0, r->hash_algo->empty_tree, NULL, &base, author, committer, NULL, NULL)) return error(_("unable to write base commit")); diff --git a/commit.c b/commit.c index d558db52dc..b05cd8d9da 100644 --- a/commit.c +++ b/commit.c @@ -1534,7 +1534,8 @@ void free_commit_extra_headers(struct commit_extra_header *extra) } } -int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, +int commit_tree(struct repository *r, + const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit) { @@ -1542,7 +1543,7 @@ int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, int result; append_merge_tag_headers(parents, &tail); - result = commit_tree_extended(msg, msg_len, tree, parents, ret, author, + result = commit_tree_extended(r, msg, msg_len, tree, parents, ret, author, NULL, sign_commit, extra); free_commit_extra_headers(extra); return result; @@ -1663,17 +1664,18 @@ N_("Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" "variable i18n.commitEncoding to the encoding your project uses.\n"); -static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg_len, - const struct object_id *tree, - const struct object_id *parents, size_t parents_len, - const char *author, const char *committer, - const struct commit_extra_header *extra) +static void write_commit_tree(struct repository *r, + struct strbuf *buffer, const char *msg, size_t msg_len, + const struct object_id *tree, + const struct object_id *parents, size_t parents_len, + const char *author, const char *committer, + const struct commit_extra_header *extra) { int encoding_is_utf8; size_t i; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository)); + encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(r)); strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */ strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree)); @@ -1694,7 +1696,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg committer = git_committer_info(IDENT_STRICT); strbuf_addf(buffer, "committer %s\n", committer); if (!encoding_is_utf8) - strbuf_addf(buffer, "encoding %s\n", repo_get_commit_output_encoding(the_repository)); + strbuf_addf(buffer, "encoding %s\n", repo_get_commit_output_encoding(r)); while (extra) { add_extra_header(buffer, extra); @@ -1706,14 +1708,15 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg strbuf_add(buffer, msg, msg_len); } -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended( + struct repository *r, + const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, const char *sign_commit, const struct commit_extra_header *extra) { - struct repository *r = the_repository; int result = 0; int encoding_is_utf8; struct strbuf buffer = STRBUF_INIT, compat_buffer = STRBUF_INIT; @@ -1723,7 +1726,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, size_t i, nparents; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(the_repository)); + encoding_is_utf8 = is_encoding_utf8(repo_get_commit_output_encoding(r)); odb_assert_oid_type(the_repository->objects, tree, OBJ_TREE); @@ -1736,7 +1739,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, for (const struct commit_list *p = parents; p; p = p->next) oidcpy(&parent_buf[i++], &p->item->object.oid); - write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); + write_commit_tree(r, &buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) { result = -1; goto out; @@ -1764,7 +1767,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, free(mapped_parents); goto out; } - write_commit_tree(&compat_buffer, msg, msg_len, &mapped_tree, + write_commit_tree(r, &compat_buffer, msg, msg_len, &mapped_tree, mapped_parents, nparents, author, committer, compat_extra); free_commit_extra_headers(compat_extra); free(mapped_parents); diff --git a/commit.h b/commit.h index 1635de418b..b8aa748fbb 100644 --- a/commit.h +++ b/commit.h @@ -289,12 +289,14 @@ struct commit_extra_header { void append_merge_tag_headers(const struct commit_list *parents, struct commit_extra_header ***tail); -int commit_tree(const char *msg, size_t msg_len, +int commit_tree(struct repository *r, + const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit); -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended(struct repository *r, + const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, diff --git a/diff.c b/diff.c index 35b903a9a0..f0244c14f1 100644 --- a/diff.c +++ b/diff.c @@ -7513,7 +7513,7 @@ size_t fill_textconv(struct repository *r, * Since generating a cache entry is the slow path anyway, * this extra overhead probably isn't a big deal. */ - notes_cache_write(driver->textconv_cache); + notes_cache_write(r, driver->textconv_cache); } return size; diff --git a/notes-cache.c b/notes-cache.c index bf5bb1f6c1..f14e0308af 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -54,7 +54,7 @@ void notes_cache_init(struct repository *r, struct notes_cache *c, strbuf_release(&ref); } -int notes_cache_write(struct notes_cache *c) +int notes_cache_write(struct repository *r, struct notes_cache *c) { struct object_id tree_oid, commit_oid; @@ -66,7 +66,7 @@ int notes_cache_write(struct notes_cache *c) if (write_notes_tree(&c->tree, &tree_oid)) return -1; - if (commit_tree(c->validity, strlen(c->validity), &tree_oid, NULL, + if (commit_tree(r, c->validity, strlen(c->validity), &tree_oid, NULL, &commit_oid, NULL, NULL) < 0) return -1; if (refs_update_ref(get_main_ref_store(the_repository), "update notes cache", c->tree.update_ref, &commit_oid, diff --git a/notes-cache.h b/notes-cache.h index 56f8c98e24..f268425fd7 100644 --- a/notes-cache.h +++ b/notes-cache.h @@ -12,7 +12,7 @@ struct notes_cache { void notes_cache_init(struct repository *r, struct notes_cache *c, const char *name, const char *validity); -int notes_cache_write(struct notes_cache *c); +int notes_cache_write(struct repository *r, struct notes_cache *c); char *notes_cache_get(struct notes_cache *c, struct object_id *oid, size_t *outsize); diff --git a/notes-utils.c b/notes-utils.c index 5c1c75d5b8..4671a11993 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -36,7 +36,7 @@ void create_notes_commit(struct repository *r, /* else: t->ref points to nothing, assume root/orphan commit */ } - if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL, + if (commit_tree(r, msg, msg_len, &tree_oid, parents, result_oid, NULL, NULL)) die("Failed to commit notes tree to database"); diff --git a/replay.c b/replay.c index 45d539f8fc..69a69deab4 100644 --- a/replay.c +++ b/replay.c @@ -68,7 +68,7 @@ static struct commit *create_commit(struct repository *repo, strbuf_addstr(&msg, orig_message); author = get_author(message); reset_ident_date(); - if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents, + if (commit_tree_extended(repo, msg.buf, msg.len, &tree->object.oid, parents, &ret, author, NULL, sign_commit, extra)) { error(_("failed to write commit object")); goto out; diff --git a/sequencer.c b/sequencer.c index 612f47fd12..b9a4f75c5f 100644 --- a/sequencer.c +++ b/sequencer.c @@ -480,13 +480,13 @@ static const char *short_commit_name(struct repository *r, struct commit *commit return repo_find_unique_abbrev(r, &commit->object.oid, DEFAULT_ABBREV); } -static int get_message(struct commit *commit, struct commit_message *out) +static int get_message(struct repository *r, struct commit *commit, struct commit_message *out) { const char *abbrev, *subject; int subject_len; out->message = repo_logmsg_reencode(the_repository, commit, NULL, - repo_get_commit_output_encoding(the_repository)); + repo_get_commit_output_encoding(r)); abbrev = short_commit_name(the_repository, commit); subject_len = find_commit_subject(out->message, &subject); @@ -1672,7 +1672,7 @@ static int try_to_commit(struct repository *r, free(email); } - if (commit_tree_extended(msg->buf, msg->len, &tree, parents, oid, + if (commit_tree_extended(r, msg->buf, msg->len, &tree, parents, oid, author, committer, opts->gpg_sign, extra)) { res = error(_("failed to write commit object")); goto out; @@ -2324,7 +2324,7 @@ static int do_pick_commit(struct repository *r, else parent = commit->parents->item; - if (get_message(commit, &msg) != 0) + if (get_message(r, commit, &msg) != 0) return error(_("cannot get commit message for %s"), oid_to_hex(&commit->object.oid)); @@ -3989,7 +3989,7 @@ static int do_reset(struct repository *r, if (len == 10 && !strncmp("[new root]", name, len)) { if (!opts->have_squash_onto) { const char *hex; - if (commit_tree("", 0, the_hash_algo->empty_tree, + if (commit_tree(r, "", 0, the_hash_algo->empty_tree, NULL, &opts->squash_onto, NULL, NULL)) return error(_("writing fake root commit")); @@ -4831,7 +4831,7 @@ static int stopped_at_head(struct repository *r) if (repo_get_oid(r, "HEAD", &head) || !(commit = lookup_commit(r, &head)) || - repo_parse_commit(r, commit) || get_message(commit, &message)) + repo_parse_commit(r, commit) || get_message(r, commit, &message)) fprintf(stderr, _("Stopped at HEAD\n")); else { fprintf(stderr, _("Stopped at %s\n"), message.label); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/3] pretty: pass 'struct repository' to pretty_print_commit() 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 1/3] environment: migrate encoding settings to repo-settings Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 2/3] commit: pass 'struct repository' to commit creation APIs Tian Yuchen @ 2026-02-28 19:02 ` Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-02-28 19:02 UTC (permalink / raw) To: git; +Cc: karthik.188, gitster Following the migration of encoding settings into 'struct repo_settings', the commit formatting and logging APIs now require a repository context. Update the signatures of 'pretty_print_commit()' and 'pp_commit_easy()' to accept 'struct repository *' as their first argument, allowing them to call 'repo_get_log_output_encoding(r)' without relying on the global 'the_repository'. For callers residing in the 'builtin/' directory, and for areas that do not yet possess a repository context (such as 'bundle.c'), fallback to using 'the_repository'. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/checkout.c | 4 ++-- builtin/log.c | 2 +- builtin/merge.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- builtin/show-branch.c | 2 +- builtin/stash.c | 2 +- bundle.c | 2 +- log-tree.c | 6 +++--- pretty.c | 13 +++++++------ pretty.h | 4 ++-- range-diff.c | 10 +++++----- revision.c | 4 ++-- sequencer.c | 12 ++++++------ 15 files changed, 35 insertions(+), 34 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index f7b313816e..64c5c9ed1a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -689,7 +689,7 @@ static void describe_detached_head(const char *msg, struct commit *commit) struct strbuf sb = STRBUF_INIT; if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &sb); if (print_sha1_ellipsis()) { fprintf(stderr, "%s %s... %s\n", msg, repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), @@ -1077,7 +1077,7 @@ static void describe_one_orphan(struct strbuf *sb, struct commit *commit) strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(sb, ' '); if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, sb); strbuf_addch(sb, '\n'); } diff --git a/builtin/log.c b/builtin/log.c index 1c9ec09098..922a0788e9 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -2521,7 +2521,7 @@ static void print_commit(char sign, struct commit *commit, int verbose, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev)); } else { struct strbuf buf = STRBUF_INIT; - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); fprintf(file, "%c %s %s\n", sign, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev), buf.buf); diff --git a/builtin/merge.c b/builtin/merge.c index 7c944fe179..dff8185776 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -470,7 +470,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", oid_to_hex(&commit->object.oid)); - pretty_print_commit(&ctx, commit, &out); + pretty_print_commit(the_repository, &ctx, commit, &out); } write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len); strbuf_release(&out); diff --git a/builtin/reset.c b/builtin/reset.c index c48d9845f8..733f3fa905 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -141,7 +141,7 @@ static void print_new_head_line(struct commit *commit) printf(_("HEAD is now at %s"), repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); if (buf.len > 0) printf(" %s", buf.buf); putchar('\n'); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 3c6a2914d8..1ebe0e6038 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -307,7 +307,7 @@ static void show_commit(struct commit *commit, void *data) ctx.output_encoding = repo_get_log_output_encoding(the_repository); ctx.color = revs->diffopt.use_color; ctx.rev = revs; - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); if (buf.len) { if (revs->commit_format != CMIT_FMT_ONELINE) graph_show_oneline(revs->graph); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index ce9f20de2f..0e47c4dc40 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -252,7 +252,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) if (!log->summary) { if (log->user_format) - pretty_print_commit(&ctx, commit, &oneline); + pretty_print_commit(the_repository, &ctx, commit, &oneline); else repo_format_commit_message(the_repository, commit, "%s", &oneline, &ctx); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index f02831b085..6bfe9e2e96 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -310,7 +310,7 @@ static void show_one_commit(struct commit *commit, int no_name) struct commit_name *name = commit_to_name(commit); if (commit->object.parsed) { - pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &pretty); pretty_str = pretty.buf; } skip_prefix(pretty_str, "[PATCH] ", &pretty_str); diff --git a/builtin/stash.c b/builtin/stash.c index 3d94726251..caaff35cb7 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1480,7 +1480,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &head_commit->object.oid, DEFAULT_ABBREV); strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1); - pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, head_commit, &msg); strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); diff --git a/bundle.c b/bundle.c index 7914a57b43..4876d0a852 100644 --- a/bundle.c +++ b/bundle.c @@ -463,7 +463,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) ctx.fmt = CMIT_FMT_ONELINE; ctx.output_encoding = repo_get_log_output_encoding(the_repository); strbuf_reset(&buf); - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); strbuf_trim(&buf); object = (struct object *)commit; diff --git a/log-tree.c b/log-tree.c index aea3cbf7c6..2039c31297 100644 --- a/log-tree.c +++ b/log-tree.c @@ -859,7 +859,7 @@ void show_log(struct rev_info *opt) raw = (opt->commit_format == CMIT_FMT_USERFORMAT); format_display_notes(&commit->object.oid, ¬ebuf, - repo_get_log_output_encoding(the_repository), raw); + repo_get_log_output_encoding(opt->repo), raw); ctx.notes_message = strbuf_detach(¬ebuf, NULL); } @@ -879,13 +879,13 @@ void show_log(struct rev_info *opt) ctx.mailmap = opt->mailmap; ctx.color = opt->diffopt.use_color; ctx.expand_tabs_in_log = opt->expand_tabs_in_log; - ctx.output_encoding = repo_get_log_output_encoding(the_repository); + ctx.output_encoding = repo_get_log_output_encoding(opt->repo); ctx.rev = opt; if (opt->from_ident.mail_begin && opt->from_ident.name_begin) ctx.from_ident = &opt->from_ident; if (opt->graph) ctx.graph_width = graph_width(opt->graph); - pretty_print_commit(&ctx, commit, &msgbuf); + pretty_print_commit(opt->repo, &ctx, commit, &msgbuf); if (opt->add_signoff) append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP); diff --git a/pretty.c b/pretty.c index e939d0ff3b..8bcd57905d 100644 --- a/pretty.c +++ b/pretty.c @@ -2281,7 +2281,8 @@ void pp_remainder(struct pretty_print_context *pp, } } -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, + struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb) { @@ -2293,13 +2294,13 @@ void pretty_print_commit(struct pretty_print_context *pp, int need_8bit_cte = pp->need_8bit_cte; if (pp->fmt == CMIT_FMT_USERFORMAT) { - repo_format_commit_message(the_repository, commit, + repo_format_commit_message(r, commit, user_format, sb, pp); return; } - encoding = repo_get_log_output_encoding(the_repository); - msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL, + encoding = repo_get_log_output_encoding(r); + msg = reencoded = repo_logmsg_reencode(r, commit, NULL, encoding); if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt)) @@ -2363,10 +2364,10 @@ void pretty_print_commit(struct pretty_print_context *pp, repo_unuse_commit_buffer(the_repository, commit, reencoded); } -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb) { struct pretty_print_context pp = {0}; pp.fmt = fmt; - pretty_print_commit(&pp, commit, sb); + pretty_print_commit(r, &pp, commit, sb); } diff --git a/pretty.h b/pretty.h index fac699033e..13eb0189bd 100644 --- a/pretty.h +++ b/pretty.h @@ -82,7 +82,7 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w); * Shortcut for invoking pretty_print_commit if we do not have any context. * Context would be set empty except "fmt". */ -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb); /* @@ -132,7 +132,7 @@ void get_commit_format(const char *arg, struct rev_info *); * and put it into "sb". * Please use this function if you have a context (candidate for "pp"). */ -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb); diff --git a/range-diff.c b/range-diff.c index 57edff40a8..368d033ceb 100644 --- a/range-diff.c +++ b/range-diff.c @@ -418,7 +418,7 @@ static void output_pair_header(struct diff_options *diffopt, if (!dashes->len) strbuf_addchars(dashes, '-', - strlen(repo_find_unique_abbrev(the_repository, oid, abbrev))); + strlen(repo_find_unique_abbrev(diffopt->repo, oid, abbrev))); if (!b_util) { color = color_old; @@ -440,7 +440,7 @@ static void output_pair_header(struct diff_options *diffopt, strbuf_addf(buf, "%*s: %s ", patch_no_width, "-", dashes->buf); else strbuf_addf(buf, "%*d: %s ", patch_no_width, a_util->i + 1, - repo_find_unique_abbrev(the_repository, &a_util->oid, abbrev)); + repo_find_unique_abbrev(diffopt->repo, &a_util->oid, abbrev)); if (status == '!') strbuf_addf(buf, "%s%s", color_reset, color); @@ -452,15 +452,15 @@ static void output_pair_header(struct diff_options *diffopt, strbuf_addf(buf, " %*s: %s", patch_no_width, "-", dashes->buf); else strbuf_addf(buf, " %*d: %s", patch_no_width, b_util->i + 1, - repo_find_unique_abbrev(the_repository, &b_util->oid, abbrev)); + repo_find_unique_abbrev(diffopt->repo, &b_util->oid, abbrev)); - commit = lookup_commit_reference(the_repository, oid); + commit = lookup_commit_reference(diffopt->repo, oid); if (commit) { if (status == '!') strbuf_addf(buf, "%s%s", color_reset, color); strbuf_addch(buf, ' '); - pp_commit_easy(CMIT_FMT_ONELINE, commit, buf); + pp_commit_easy(diffopt->repo, CMIT_FMT_ONELINE, commit, buf); } strbuf_addf(buf, "%s\n", color_reset); diff --git a/revision.c b/revision.c index 961ecd1d6c..5c3c5a102d 100644 --- a/revision.c +++ b/revision.c @@ -3130,7 +3130,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s diff_setup_done(&revs->diffopt); - if (!is_encoding_utf8(repo_get_log_output_encoding(the_repository))) + if (!is_encoding_utf8(repo_get_log_output_encoding(revs->repo))) revs->grep_filter.ignore_locale = 1; compile_grep_patterns(&revs->grep_filter); @@ -4064,7 +4064,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) * so we will not end up with a buffer that has two different encodings * in it. */ - encoding = repo_get_log_output_encoding(the_repository); + encoding = repo_get_log_output_encoding(opt->repo); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); /* Copy the commit to temporary if we are using "fake" headers */ diff --git a/sequencer.c b/sequencer.c index b9a4f75c5f..09e6dcca43 100644 --- a/sequencer.c +++ b/sequencer.c @@ -3332,7 +3332,7 @@ int write_basic_state(struct replay_opts *opts, const char *head_name, return 0; } -static int walk_revs_populate_todo(struct todo_list *todo_list, +static int walk_revs_populate_todo(struct repository *r, struct todo_list *todo_list, struct replay_opts *opts) { enum todo_command command = opts->action == REPLAY_PICK ? @@ -3344,7 +3344,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list, if (prepare_revs(opts)) return -1; - encoding = repo_get_log_output_encoding(the_repository); + encoding = repo_get_log_output_encoding(r); while ((commit = get_revision(opts->revs))) { struct todo_item *item = append_new_todo(todo_list); @@ -5543,7 +5543,7 @@ int sequencer_pick_revisions(struct repository *r, * progress */ - if (walk_revs_populate_todo(&todo_list, opts) || + if (walk_revs_populate_todo(r, &todo_list, opts) || create_seq_dir(r) < 0) { res = -1; goto out; @@ -5870,7 +5870,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, continue; strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); to_merge = commit->parents ? commit->parents->next : NULL; if (!to_merge) { @@ -6012,7 +6012,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, strbuf_addf(out, "%s onto\n", cmd_reset); else { strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); strbuf_addf(out, "%s %s %s\n", cmd_reset, to, oneline.buf); } @@ -6124,7 +6124,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, continue; strbuf_addf(out, "%s %s ", insn, oid_to_hex(&commit->object.oid)); - pretty_print_commit(&pp, commit, out); + pretty_print_commit(r, &pp, commit, out); if (is_empty) strbuf_addf(out, " %s empty", comment_line_str); strbuf_addch(out, '\n'); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 0/3] environment: move encoding configs to struct repository 2026-02-28 4:07 [PATCH v1] environment: migrate encoding settings to repo-settings Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen @ 2026-03-01 20:35 ` Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen ` (2 more replies) 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen 2 siblings, 3 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-01 20:35 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood This is v3 of the series aimed at reducing the global state associated with 'git_commit_encoding' and 'git_log_output_encoding'. Changes since v2: Based on the invaluable feedback from Phillip Wood, the architectural approach has been fundamentally adjusted. In v2, I attempted to migrate these variables into 'struct repo_settings'. However, since these are eagerly parsed user preferences, deferring them to lazy evaluation broke early validation. In this v3 series, the variables are migrated directly into 'struct repository'. According to the thread Phillip Wood shared, plumbing the repository pointer safely through the 'git_default_config' callback machinery is highly invasive. Many top-level callers pass custom structs via the 'void *cb' pointer so that blindly casting 'cb' to 'struct repository *' results in weird bugs (at least I can't fix them all in one single patch) Therefore: 1. The variables are parsed directly into 'the_repository' during config parsing to maintain eager validation. 2. However, the entire read/write paths (commit creation and log APIs) are fully plumbed to accept any 'struct repository' instance. Future efforts to libify the config machinery itself will only need to update the parser, as the core APIs are now context-aware. Tian Yuchen (3): commit: plumb 'struct repository' into commit creation APIs pretty: plumb 'struct repository' into pretty-print APIs environment: migrate encoding configs to struct repository builtin/am.c | 6 +++--- builtin/blame.c | 2 +- builtin/checkout.c | 4 ++-- builtin/commit-tree.c | 2 +- builtin/commit.c | 8 ++++---- builtin/history.c | 2 +- builtin/log.c | 4 ++-- builtin/mailinfo.c | 6 +++--- builtin/merge.c | 6 +++--- builtin/rebase.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 4 ++-- builtin/shortlog.c | 4 ++-- builtin/show-branch.c | 2 +- builtin/stash.c | 12 ++++++------ bundle.c | 4 ++-- commit.c | 20 ++++++++++---------- commit.h | 4 ++-- environment.c | 19 ++++++++----------- environment.h | 7 ++----- log-tree.c | 6 +++--- notes-cache.c | 2 +- notes-utils.c | 2 +- pretty.c | 8 ++++---- pretty.h | 4 ++-- range-diff.c | 2 +- remote-curl.c | 2 +- replay.c | 4 ++-- repository.c | 2 ++ repository.h | 5 +++++ revision.c | 10 +++++----- sequencer.c | 32 ++++++++++++++++---------------- submodule.c | 2 +- 33 files changed, 101 insertions(+), 100 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 1/3] commit: plumb 'struct repository' into commit creation APIs 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen @ 2026-03-01 20:35 ` Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 3/3] environment: migrate encoding configs to struct repository Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-01 20:35 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood To pave the way for reducing the global state tied to commit encoding in a subsequent patch, functions like 'commit_tree()' and 'commit_tree_extended()' must be able to access a repository instance. Plumb the 'struct repository' pointer down the call chain for these APIs. For built-ins or subsystems already dependent on global state (e.g., 'notes_cache_write()'), fallback to 'the_repository'. No functional changes are introduced in this preparatory step. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 2 +- builtin/commit-tree.c | 2 +- builtin/commit.c | 2 +- builtin/history.c | 2 +- builtin/merge.c | 4 ++-- builtin/rebase.c | 2 +- builtin/stash.c | 10 +++++----- commit.c | 7 +++---- commit.h | 4 ++-- notes-cache.c | 2 +- notes-utils.c | 2 +- replay.c | 2 +- sequencer.c | 4 ++-- 13 files changed, 22 insertions(+), 23 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index e0c767e223..5296124f84 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1699,7 +1699,7 @@ static void do_commit(const struct am_state *state) : state->author_date, IDENT_STRICT); - if (commit_tree_extended(state->msg, state->msg_len, &tree, parents, + if (commit_tree_extended(the_repository, state->msg, state->msg_len, &tree, parents, &commit, author, committer, state->sign_commit, NULL)) die(_("failed to write commit object")); diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 30535db131..c489749588 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -144,7 +144,7 @@ int cmd_commit_tree(int argc, die_errno(_("git commit-tree: failed to read")); } - if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, + if (commit_tree(the_repository, buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, NULL, sign_commit)) { ret = 1; goto out; diff --git a/builtin/commit.c b/builtin/commit.c index 9e3a09d532..d619fd2ace 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1931,7 +1931,7 @@ int cmd_commit(int argc, append_merge_tag_headers(parents, &tail); } - if (commit_tree_extended(sb.buf, sb.len, &the_repository->index->cache_tree->oid, + if (commit_tree_extended(the_repository, sb.buf, sb.len, &the_repository->index->cache_tree->oid, parents, &oid, author_ident.buf, NULL, sign_commit, extra)) { rollback_index_files(); diff --git a/builtin/history.c b/builtin/history.c index 8dcb9a6046..3d83ac021b 100644 --- a/builtin/history.c +++ b/builtin/history.c @@ -136,7 +136,7 @@ static int commit_tree_with_edited_message(struct repository *repo, original_extra_headers = read_commit_extra_headers(original, exclude_gpgsig); - ret = commit_tree_extended(commit_message.buf, commit_message.len, &original_tree_oid, + ret = commit_tree_extended(repo, commit_message.buf, commit_message.len, &original_tree_oid, original->parents, &rewritten_commit_oid, original_author, NULL, NULL, original_extra_headers); if (ret < 0) diff --git a/builtin/merge.c b/builtin/merge.c index 4e456a381c..7c944fe179 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1000,7 +1000,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) pptr = commit_list_append(head, pptr); pptr = commit_list_append(remoteheads->item, pptr); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, &result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, &result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); finish(head, remoteheads, &result_commit, "In-index merge"); @@ -1027,7 +1027,7 @@ static int finish_automerge(struct commit *head, if (!head_subsumed || fast_forward == FF_NO) commit_list_insert(head, &parents); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy); diff --git a/builtin/rebase.c b/builtin/rebase.c index c487e10907..7b9ab85cc0 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1647,7 +1647,7 @@ int cmd_rebase(int argc, options.upstream_arg = options.upstream_name; } else { if (!options.onto_name) { - if (commit_tree("", 0, the_hash_algo->empty_tree, NULL, + if (commit_tree(the_repository, "", 0, the_hash_algo->empty_tree, NULL, &squash_onto, NULL, NULL) < 0) die(_("Could not create new root commit")); options.squash_onto = &squash_onto; diff --git a/builtin/stash.c b/builtin/stash.c index f06cfa7989..785c1f9e5d 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1258,7 +1258,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, goto done; } - if (commit_tree(untracked_msg.buf, untracked_msg.len, + if (commit_tree(the_repository, untracked_msg.buf, untracked_msg.len, &info->u_tree, NULL, &info->u_commit, NULL, NULL)) { ret = -1; goto done; @@ -1486,7 +1486,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b commit_list_insert(head_commit, &parents); if (write_index_as_tree(&info->i_tree, the_repository->index, repo_get_index_file(the_repository), 0, NULL) || - commit_tree(commit_tree_label.buf, commit_tree_label.len, + commit_tree(the_repository, commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1551,7 +1551,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &parents); commit_list_insert(head_commit, &parents); - if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, + if (commit_tree(the_repository, stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, parents, &info->w_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot record " @@ -2035,7 +2035,7 @@ static int write_commit_with_parents(struct repository *r, author = xmemdupz(orig_author, author_len); committer = xmemdupz(orig_committer, committer_len); - if (commit_tree_extended(msg.buf, msg.len, + if (commit_tree_extended(r, msg.buf, msg.len, r->hash_algo->empty_tree, parents, out, author, committer, NULL, NULL)) { @@ -2258,7 +2258,7 @@ static int do_export_stash(struct repository *r, "2001-09-17T00:00:00Z", 0); /* First, we create a single empty commit. */ - if (commit_tree_extended("", 0, r->hash_algo->empty_tree, NULL, + if (commit_tree_extended(the_repository, "", 0, r->hash_algo->empty_tree, NULL, &base, author, committer, NULL, NULL)) return error(_("unable to write base commit")); diff --git a/commit.c b/commit.c index d16ae73345..71a2b7bbe5 100644 --- a/commit.c +++ b/commit.c @@ -1534,7 +1534,7 @@ void free_commit_extra_headers(struct commit_extra_header *extra) } } -int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, +int commit_tree(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit) { @@ -1542,7 +1542,7 @@ int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, int result; append_merge_tag_headers(parents, &tail); - result = commit_tree_extended(msg, msg_len, tree, parents, ret, author, + result = commit_tree_extended(r, msg, msg_len, tree, parents, ret, author, NULL, sign_commit, extra); free_commit_extra_headers(extra); return result; @@ -1706,14 +1706,13 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg strbuf_add(buffer, msg, msg_len); } -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, const char *sign_commit, const struct commit_extra_header *extra) { - struct repository *r = the_repository; int result = 0; int encoding_is_utf8; struct strbuf buffer = STRBUF_INIT, compat_buffer = STRBUF_INIT; diff --git a/commit.h b/commit.h index 1635de418b..d3d664d0ff 100644 --- a/commit.h +++ b/commit.h @@ -289,12 +289,12 @@ struct commit_extra_header { void append_merge_tag_headers(const struct commit_list *parents, struct commit_extra_header ***tail); -int commit_tree(const char *msg, size_t msg_len, +int commit_tree(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit); -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, diff --git a/notes-cache.c b/notes-cache.c index bf5bb1f6c1..5dbbd94ea3 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -66,7 +66,7 @@ int notes_cache_write(struct notes_cache *c) if (write_notes_tree(&c->tree, &tree_oid)) return -1; - if (commit_tree(c->validity, strlen(c->validity), &tree_oid, NULL, + if (commit_tree(the_repository, c->validity, strlen(c->validity), &tree_oid, NULL, &commit_oid, NULL, NULL) < 0) return -1; if (refs_update_ref(get_main_ref_store(the_repository), "update notes cache", c->tree.update_ref, &commit_oid, diff --git a/notes-utils.c b/notes-utils.c index 5c1c75d5b8..4671a11993 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -36,7 +36,7 @@ void create_notes_commit(struct repository *r, /* else: t->ref points to nothing, assume root/orphan commit */ } - if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL, + if (commit_tree(r, msg, msg_len, &tree_oid, parents, result_oid, NULL, NULL)) die("Failed to commit notes tree to database"); diff --git a/replay.c b/replay.c index f97d652f33..8704547aa1 100644 --- a/replay.c +++ b/replay.c @@ -68,7 +68,7 @@ static struct commit *create_commit(struct repository *repo, strbuf_addstr(&msg, orig_message); author = get_author(message); reset_ident_date(); - if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents, + if (commit_tree_extended(repo, msg.buf, msg.len, &tree->object.oid, parents, &ret, author, NULL, sign_commit, extra)) { error(_("failed to write commit object")); goto out; diff --git a/sequencer.c b/sequencer.c index a3eb39bb25..627020d65b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1672,7 +1672,7 @@ static int try_to_commit(struct repository *r, free(email); } - if (commit_tree_extended(msg->buf, msg->len, &tree, parents, oid, + if (commit_tree_extended(r, msg->buf, msg->len, &tree, parents, oid, author, committer, opts->gpg_sign, extra)) { res = error(_("failed to write commit object")); goto out; @@ -3989,7 +3989,7 @@ static int do_reset(struct repository *r, if (len == 10 && !strncmp("[new root]", name, len)) { if (!opts->have_squash_onto) { const char *hex; - if (commit_tree("", 0, the_hash_algo->empty_tree, + if (commit_tree(r, "", 0, the_hash_algo->empty_tree, NULL, &opts->squash_onto, NULL, NULL)) return error(_("writing fake root commit")); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 2/3] pretty: plumb 'struct repository' into pretty-print APIs 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen @ 2026-03-01 20:35 ` Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 3/3] environment: migrate encoding configs to struct repository Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-01 20:35 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood To prepare for the elimination of the global state associated with 'log_output_encoding', functions responsible for formatting commit messages, such as 'pretty_print_commit()' and 'pp_commit_easy()', must be able to access a repository instance. Plumb the 'struct repository' pointer down the call chain for these APIs. Where no such context is readily available in built-ins or high-level functions, fallback to 'the_repository'. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/checkout.c | 4 ++-- builtin/log.c | 2 +- builtin/merge.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- builtin/show-branch.c | 2 +- builtin/stash.c | 2 +- bundle.c | 2 +- log-tree.c | 2 +- pretty.c | 6 +++--- pretty.h | 4 ++-- range-diff.c | 2 +- sequencer.c | 6 +++--- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index f7b313816e..64c5c9ed1a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -689,7 +689,7 @@ static void describe_detached_head(const char *msg, struct commit *commit) struct strbuf sb = STRBUF_INIT; if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &sb); if (print_sha1_ellipsis()) { fprintf(stderr, "%s %s... %s\n", msg, repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), @@ -1077,7 +1077,7 @@ static void describe_one_orphan(struct strbuf *sb, struct commit *commit) strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(sb, ' '); if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, sb); strbuf_addch(sb, '\n'); } diff --git a/builtin/log.c b/builtin/log.c index 8ab6d3a943..0758aed580 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -2521,7 +2521,7 @@ static void print_commit(char sign, struct commit *commit, int verbose, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev)); } else { struct strbuf buf = STRBUF_INIT; - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); fprintf(file, "%c %s %s\n", sign, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev), buf.buf); diff --git a/builtin/merge.c b/builtin/merge.c index 7c944fe179..dff8185776 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -470,7 +470,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", oid_to_hex(&commit->object.oid)); - pretty_print_commit(&ctx, commit, &out); + pretty_print_commit(the_repository, &ctx, commit, &out); } write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len); strbuf_release(&out); diff --git a/builtin/reset.c b/builtin/reset.c index c48d9845f8..733f3fa905 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -141,7 +141,7 @@ static void print_new_head_line(struct commit *commit) printf(_("HEAD is now at %s"), repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); if (buf.len > 0) printf(" %s", buf.buf); putchar('\n'); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index ddea8aa251..57c7b8d3ff 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -307,7 +307,7 @@ static void show_commit(struct commit *commit, void *data) ctx.output_encoding = get_log_output_encoding(); ctx.color = revs->diffopt.use_color; ctx.rev = revs; - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); if (buf.len) { if (revs->commit_format != CMIT_FMT_ONELINE) graph_show_oneline(revs->graph); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index d80bf1a7d0..109785fd00 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -252,7 +252,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) if (!log->summary) { if (log->user_format) - pretty_print_commit(&ctx, commit, &oneline); + pretty_print_commit(the_repository, &ctx, commit, &oneline); else repo_format_commit_message(the_repository, commit, "%s", &oneline, &ctx); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index f02831b085..6bfe9e2e96 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -310,7 +310,7 @@ static void show_one_commit(struct commit *commit, int no_name) struct commit_name *name = commit_to_name(commit); if (commit->object.parsed) { - pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &pretty); pretty_str = pretty.buf; } skip_prefix(pretty_str, "[PATCH] ", &pretty_str); diff --git a/builtin/stash.c b/builtin/stash.c index 785c1f9e5d..a522bb6de5 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1480,7 +1480,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &head_commit->object.oid, DEFAULT_ABBREV); strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1); - pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, head_commit, &msg); strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); diff --git a/bundle.c b/bundle.c index 42327f9739..3bc2ed9ee9 100644 --- a/bundle.c +++ b/bundle.c @@ -463,7 +463,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) ctx.fmt = CMIT_FMT_ONELINE; ctx.output_encoding = get_log_output_encoding(); strbuf_reset(&buf); - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); strbuf_trim(&buf); object = (struct object *)commit; diff --git a/log-tree.c b/log-tree.c index 7e048701d0..fd2fb0bed6 100644 --- a/log-tree.c +++ b/log-tree.c @@ -885,7 +885,7 @@ void show_log(struct rev_info *opt) ctx.from_ident = &opt->from_ident; if (opt->graph) ctx.graph_width = graph_width(opt->graph); - pretty_print_commit(&ctx, commit, &msgbuf); + pretty_print_commit(opt->repo, &ctx, commit, &msgbuf); if (opt->add_signoff) append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP); diff --git a/pretty.c b/pretty.c index e0646bbc5d..51e3480431 100644 --- a/pretty.c +++ b/pretty.c @@ -2281,7 +2281,7 @@ void pp_remainder(struct pretty_print_context *pp, } } -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb) { @@ -2363,10 +2363,10 @@ void pretty_print_commit(struct pretty_print_context *pp, repo_unuse_commit_buffer(the_repository, commit, reencoded); } -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb) { struct pretty_print_context pp = {0}; pp.fmt = fmt; - pretty_print_commit(&pp, commit, sb); + pretty_print_commit(r, &pp, commit, sb); } diff --git a/pretty.h b/pretty.h index fac699033e..13eb0189bd 100644 --- a/pretty.h +++ b/pretty.h @@ -82,7 +82,7 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w); * Shortcut for invoking pretty_print_commit if we do not have any context. * Context would be set empty except "fmt". */ -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb); /* @@ -132,7 +132,7 @@ void get_commit_format(const char *arg, struct rev_info *); * and put it into "sb". * Please use this function if you have a context (candidate for "pp"). */ -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb); diff --git a/range-diff.c b/range-diff.c index 57edff40a8..31d38c2318 100644 --- a/range-diff.c +++ b/range-diff.c @@ -460,7 +460,7 @@ static void output_pair_header(struct diff_options *diffopt, strbuf_addf(buf, "%s%s", color_reset, color); strbuf_addch(buf, ' '); - pp_commit_easy(CMIT_FMT_ONELINE, commit, buf); + pp_commit_easy(diffopt->repo, CMIT_FMT_ONELINE, commit, buf); } strbuf_addf(buf, "%s\n", color_reset); diff --git a/sequencer.c b/sequencer.c index 627020d65b..e6b3e05fce 100644 --- a/sequencer.c +++ b/sequencer.c @@ -5870,7 +5870,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, continue; strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); to_merge = commit->parents ? commit->parents->next : NULL; if (!to_merge) { @@ -6012,7 +6012,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, strbuf_addf(out, "%s onto\n", cmd_reset); else { strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); strbuf_addf(out, "%s %s %s\n", cmd_reset, to, oneline.buf); } @@ -6124,7 +6124,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, continue; strbuf_addf(out, "%s %s ", insn, oid_to_hex(&commit->object.oid)); - pretty_print_commit(&pp, commit, out); + pretty_print_commit(r, &pp, commit, out); if (is_empty) strbuf_addf(out, " %s empty", comment_line_str); strbuf_addch(out, '\n'); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 3/3] environment: migrate encoding configs to struct repository 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen @ 2026-03-01 20:35 ` Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-01 20:35 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood The global variables 'git_commit_encoding' and 'git_log_output_encoding' prevent libification. Migrate these variables into 'struct repository'. Note that these variables are not migrated to 'repo_settings'. As user preferences, they must be parsed eagerly to maintain immediate UX feedback. While the core read and write APIs (updated in previous patches) now utilize the 'struct repository' pointer, the config parsing step ('git_default_i18n_config') currently parses these values into 'the_repository', since safely plumbing a repository pointer through the 'git_default_config' callback machinery is highly invasive due to the diverse and custom structures currently passed via the 'void *cb' parameter. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 4 ++-- builtin/blame.c | 2 +- builtin/commit.c | 6 +++--- builtin/log.c | 2 +- builtin/mailinfo.c | 6 +++--- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- bundle.c | 2 +- commit.c | 13 +++++++------ environment.c | 19 ++++++++----------- environment.h | 7 ++----- log-tree.c | 4 ++-- pretty.c | 2 +- remote-curl.c | 2 +- replay.c | 2 +- repository.c | 2 ++ repository.h | 5 +++++ revision.c | 10 +++++----- sequencer.c | 22 +++++++++++----------- submodule.c | 2 +- 20 files changed, 59 insertions(+), 57 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 5296124f84..990b6c54e7 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail) setup_mailinfo(the_repository, &mi); if (state->utf8) - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = get_commit_output_encoding(the_repository); else mi.metainfo_charset = NULL; @@ -1355,7 +1355,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit) struct ident_split id; buffer = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + get_commit_output_encoding(the_repository)); ident_line = find_commit_header(buffer, "author", &ident_len); if (!ident_line) diff --git a/builtin/blame.c b/builtin/blame.c index eac2fe7320..0ad9f2c9f7 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -202,7 +202,7 @@ static void get_commit_info(struct commit *commit, struct commit_info *ret) const char *subject, *encoding; const char *message; - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(the_repository); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); get_ac_line(message, "\nauthor ", &ret->author, &ret->author_mail, diff --git a/builtin/commit.c b/builtin/commit.c index d619fd2ace..caf5896d97 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -794,7 +794,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, c = lookup_commit_reference_by_name(squash_message); if (!c) die(_("could not lookup commit '%s'"), squash_message); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = get_commit_output_encoding(the_repository); repo_format_commit_message(the_repository, c, "squash! %s\n\n", &sb, &ctx); @@ -829,7 +829,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, commit = lookup_commit_reference_by_name(fixup_commit); if (!commit) die(_("could not lookup commit '%s'"), fixup_commit); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = get_commit_output_encoding(the_repository); fmt = xstrfmt("%s! %%s\n\n", fixup_prefix); repo_format_commit_message(the_repository, commit, fmt, &sb, &ctx); @@ -1235,7 +1235,7 @@ static const char *read_commit_message(const char *name) commit = lookup_commit_reference_by_name(name); if (!commit) die(_("could not lookup commit '%s'"), name); - out_enc = get_commit_output_encoding(); + out_enc = get_commit_output_encoding(the_repository); return repo_logmsg_reencode(the_repository, commit, NULL, out_enc); } diff --git a/builtin/log.c b/builtin/log.c index 0758aed580..8edb3c54e7 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -568,7 +568,7 @@ static void show_tagger(const char *buf, struct rev_info *rev) pp.fmt = rev->commit_format; pp.date_mode = rev->date_mode; - pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding()); + pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding(the_repository)); fprintf(rev->diffopt.file, "%s", out.buf); strbuf_release(&out); } diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 8de7ba7de1..4f17cf1598 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -52,7 +52,7 @@ static int parse_opt_quoted_cr(const struct option *opt, const char *arg, int un int cmd_mailinfo(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { struct metainfo_charset meta_charset; struct mailinfo mi; @@ -83,7 +83,7 @@ int cmd_mailinfo(int argc, OPT_END() }; - setup_mailinfo(the_repository, &mi); + setup_mailinfo(repo, &mi); meta_charset.policy = CHARSET_DEFAULT; argc = parse_options(argc, argv, prefix, options, mailinfo_usage, 0); @@ -93,7 +93,7 @@ int cmd_mailinfo(int argc, switch (meta_charset.policy) { case CHARSET_DEFAULT: - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = get_commit_output_encoding(repo); break; case CHARSET_NO_REENCODE: mi.metainfo_charset = NULL; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 57c7b8d3ff..3732edae8b 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -304,7 +304,7 @@ static void show_commit(struct commit *commit, void *data) ctx.date_mode = revs->date_mode; ctx.date_mode_explicit = revs->date_mode_explicit; ctx.fmt = revs->commit_format; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); ctx.color = revs->diffopt.use_color; ctx.rev = revs; pretty_print_commit(the_repository, &ctx, commit, &buf); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 109785fd00..79606e57be 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -248,7 +248,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) ctx.fmt = CMIT_FMT_USERFORMAT; ctx.abbrev = log->abbrev; ctx.date_mode = log->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); if (!log->summary) { if (log->user_format) diff --git a/bundle.c b/bundle.c index 3bc2ed9ee9..3b98cdd6fd 100644 --- a/bundle.c +++ b/bundle.c @@ -461,7 +461,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) write_or_die(bpi->fd, buf.buf, buf.len); ctx.fmt = CMIT_FMT_ONELINE; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); strbuf_reset(&buf); pretty_print_commit(the_repository, &ctx, commit, &buf); strbuf_trim(&buf); diff --git a/commit.c b/commit.c index 71a2b7bbe5..cb8ec675d1 100644 --- a/commit.c +++ b/commit.c @@ -1663,7 +1663,8 @@ N_("Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" "variable i18n.commitEncoding to the encoding your project uses.\n"); -static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg_len, +static void write_commit_tree(struct repository *r, struct strbuf *buffer, + const char *msg, size_t msg_len, const struct object_id *tree, const struct object_id *parents, size_t parents_len, const char *author, const char *committer, @@ -1673,7 +1674,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg size_t i; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(get_commit_output_encoding(r)); strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */ strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree)); @@ -1694,7 +1695,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg committer = git_committer_info(IDENT_STRICT); strbuf_addf(buffer, "committer %s\n", committer); if (!encoding_is_utf8) - strbuf_addf(buffer, "encoding %s\n", git_commit_encoding); + strbuf_addf(buffer, "encoding %s\n", get_commit_output_encoding(r)); while (extra) { add_extra_header(buffer, extra); @@ -1722,7 +1723,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, size_t i, nparents; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(get_commit_output_encoding(r)); odb_assert_oid_type(the_repository->objects, tree, OBJ_TREE); @@ -1735,7 +1736,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, for (const struct commit_list *p = parents; p; p = p->next) oidcpy(&parent_buf[i++], &p->item->object.oid); - write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); + write_commit_tree(r, &buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) { result = -1; goto out; @@ -1763,7 +1764,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, free(mapped_parents); goto out; } - write_commit_tree(&compat_buffer, msg, msg_len, &mapped_tree, + write_commit_tree(r, &compat_buffer, msg, msg_len, &mapped_tree, mapped_parents, nparents, author, committer, compat_extra); free_commit_extra_headers(compat_extra); free(mapped_parents); diff --git a/environment.c b/environment.c index 0026eb2274..a27c13da3d 100644 --- a/environment.c +++ b/environment.c @@ -197,15 +197,14 @@ const char *strip_namespace(const char *namespaced_ref) return NULL; } -const char *get_log_output_encoding(void) +const char *get_log_output_encoding(struct repository *r) { - return git_log_output_encoding ? git_log_output_encoding - : get_commit_output_encoding(); + return r->log_output_encoding ? r->log_output_encoding : get_commit_output_encoding(r); } -const char *get_commit_output_encoding(void) +const char *get_commit_output_encoding(struct repository *r) { - return git_commit_encoding ? git_commit_encoding : "UTF-8"; + return r->commit_encoding ? r->commit_encoding : "UTF-8"; } int use_optional_locks(void) @@ -569,16 +568,14 @@ static int git_default_sparse_config(const char *var, const char *value) static int git_default_i18n_config(const char *var, const char *value) { if (!strcmp(var, "i18n.commitencoding")) { - FREE_AND_NULL(git_commit_encoding); - return git_config_string(&git_commit_encoding, var, value); + FREE_AND_NULL(the_repository->commit_encoding); + return git_config_string(&the_repository->commit_encoding, var, value); } - if (!strcmp(var, "i18n.logoutputencoding")) { - FREE_AND_NULL(git_log_output_encoding); - return git_config_string(&git_log_output_encoding, var, value); + FREE_AND_NULL(the_repository->log_output_encoding); + return git_config_string(&the_repository->log_output_encoding, var, value); } - /* Add other config variables here and to Documentation/config.adoc. */ return 0; } diff --git a/environment.h b/environment.h index 27f657af04..d1c62a8296 100644 --- a/environment.h +++ b/environment.h @@ -193,11 +193,8 @@ extern enum object_creation_mode object_creation_mode; extern int grafts_keep_true_parents; -const char *get_log_output_encoding(void); -const char *get_commit_output_encoding(void); - -extern char *git_commit_encoding; -extern char *git_log_output_encoding; +const char *get_log_output_encoding(struct repository *r); +const char *get_commit_output_encoding(struct repository *r); extern char *editor_program; extern char *askpass_program; diff --git a/log-tree.c b/log-tree.c index fd2fb0bed6..364fd015f5 100644 --- a/log-tree.c +++ b/log-tree.c @@ -859,7 +859,7 @@ void show_log(struct rev_info *opt) raw = (opt->commit_format == CMIT_FMT_USERFORMAT); format_display_notes(&commit->object.oid, ¬ebuf, - get_log_output_encoding(), raw); + get_log_output_encoding(opt->repo), raw); ctx.notes_message = strbuf_detach(¬ebuf, NULL); } @@ -879,7 +879,7 @@ void show_log(struct rev_info *opt) ctx.mailmap = opt->mailmap; ctx.color = opt->diffopt.use_color; ctx.expand_tabs_in_log = opt->expand_tabs_in_log; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(opt->repo); ctx.rev = opt; if (opt->from_ident.mail_begin && opt->from_ident.name_begin) ctx.from_ident = &opt->from_ident; diff --git a/pretty.c b/pretty.c index 51e3480431..6b585e2763 100644 --- a/pretty.c +++ b/pretty.c @@ -2298,7 +2298,7 @@ void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, return; } - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(r); msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL, encoding); diff --git a/remote-curl.c b/remote-curl.c index 92e40bb682..146cb8930d 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -379,7 +379,7 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset, if (strcmp(type->buf, "text/plain")) return -1; if (charset->len) - strbuf_reencode(msg, charset->buf, get_log_output_encoding()); + strbuf_reencode(msg, charset->buf, get_log_output_encoding(the_repository)); strbuf_trim(msg); if (!msg->len) diff --git a/replay.c b/replay.c index 8704547aa1..0012d3aa18 100644 --- a/replay.c +++ b/replay.c @@ -56,7 +56,7 @@ static struct commit *create_commit(struct repository *repo, char *sign_commit = NULL; /* FIXME: cli users might want to sign again */ struct commit_extra_header *extra = NULL; struct strbuf msg = STRBUF_INIT; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = get_commit_output_encoding(repo); const char *message = repo_logmsg_reencode(repo, based_on, NULL, out_enc); const char *orig_message = NULL; diff --git a/repository.c b/repository.c index 46a7c99930..a2ab093a68 100644 --- a/repository.c +++ b/repository.c @@ -370,6 +370,8 @@ void repo_clear(struct repository *repo) FREE_AND_NULL(repo->index_file); FREE_AND_NULL(repo->worktree); FREE_AND_NULL(repo->submodule_prefix); + FREE_AND_NULL(repo->commit_encoding); + FREE_AND_NULL(repo->log_output_encoding); odb_free(repo->objects); repo->objects = NULL; diff --git a/repository.h b/repository.h index 7141237f97..4e67b15c36 100644 --- a/repository.h +++ b/repository.h @@ -172,6 +172,11 @@ struct repository { /* Should repo_config() check for deprecated settings */ bool check_deprecated_config; + + /* User's preferred encoding for commit messages and log output. */ + + char *commit_encoding; + char *log_output_encoding; }; #ifdef USE_THE_REPOSITORY_VARIABLE diff --git a/revision.c b/revision.c index 29972c3a19..b85cac9877 100644 --- a/revision.c +++ b/revision.c @@ -2675,11 +2675,11 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--invert-grep")) { revs->grep_filter.no_body_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { - free(git_log_output_encoding); + free(revs->repo->log_output_encoding); if (strcmp(optarg, "none")) - git_log_output_encoding = xstrdup(optarg); + revs->repo->log_output_encoding = xstrdup(optarg); else - git_log_output_encoding = xstrdup(""); + revs->repo->log_output_encoding = xstrdup(""); return argcount; } else if (!strcmp(arg, "--reverse")) { revs->reverse ^= 1; @@ -3129,7 +3129,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s diff_setup_done(&revs->diffopt); - if (!is_encoding_utf8(get_log_output_encoding())) + if (!is_encoding_utf8(get_log_output_encoding(revs->repo))) revs->grep_filter.ignore_locale = 1; compile_grep_patterns(&revs->grep_filter); @@ -4063,7 +4063,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) * so we will not end up with a buffer that has two different encodings * in it. */ - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(opt->repo); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); /* Copy the commit to temporary if we are using "fake" headers */ diff --git a/sequencer.c b/sequencer.c index e6b3e05fce..62717910d2 100644 --- a/sequencer.c +++ b/sequencer.c @@ -480,13 +480,13 @@ static const char *short_commit_name(struct repository *r, struct commit *commit return repo_find_unique_abbrev(r, &commit->object.oid, DEFAULT_ABBREV); } -static int get_message(struct commit *commit, struct commit_message *out) +static int get_message(struct repository *r, struct commit *commit, struct commit_message *out) { const char *abbrev, *subject; int subject_len; out->message = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + get_commit_output_encoding(r)); abbrev = short_commit_name(the_repository, commit); subject_len = find_commit_subject(out->message, &subject); @@ -1539,7 +1539,7 @@ static int try_to_commit(struct repository *r, if (flags & AMEND_MSG) { const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL }; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, current_head, NULL, out_enc); @@ -2054,7 +2054,7 @@ static int update_squash_messages(struct repository *r, struct strbuf buf = STRBUF_INIT; int res = 0; const char *message, *body; - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); if (!is_fixup(command)) BUG("not a FIXUP or SQUASH %d", command); @@ -2324,7 +2324,7 @@ static int do_pick_commit(struct repository *r, else parent = commit->parents->item; - if (get_message(commit, &msg) != 0) + if (get_message(r, commit, &msg) != 0) return error(_("cannot get commit message for %s"), oid_to_hex(&commit->object.oid)); @@ -3344,7 +3344,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list, if (prepare_revs(opts)) return -1; - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(the_repository); while ((commit = get_revision(opts->revs))) { struct todo_item *item = append_new_todo(todo_list); @@ -3730,7 +3730,7 @@ static int make_patch(struct repository *r, } if (!file_exists(rebase_path_message())) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); const char *commit_buffer = repo_logmsg_reencode(r, commit, NULL, encoding); @@ -4187,7 +4187,7 @@ static int do_merge(struct repository *r, } if (commit) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, commit, NULL, encoding); const char *body; @@ -4831,7 +4831,7 @@ static int stopped_at_head(struct repository *r) if (repo_get_oid(r, "HEAD", &head) || !(commit = lookup_commit(r, &head)) || - repo_parse_commit(r, commit) || get_message(commit, &message)) + repo_parse_commit(r, commit) || get_message(r, commit, &message)) fprintf(stderr, _("Stopped at HEAD\n")); else { fprintf(stderr, _("Stopped at %s\n"), message.label); @@ -5311,7 +5311,7 @@ static int commit_staged_changes(struct repository *r, struct commit *commit; const char *msg; const char *path = rebase_path_squash_msg(); - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); if (parse_head(r, &commit)) { ret = error(_("could not parse HEAD")); @@ -6092,7 +6092,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, get_commit_format(format, &revs); free(format); pp.fmt = revs.commit_format; - pp.output_encoding = get_log_output_encoding(); + pp.output_encoding = get_log_output_encoding(r); setup_revisions_from_strvec(argv, &revs, NULL); if (argv->nr > 1) { diff --git a/submodule.c b/submodule.c index 508938e4da..a58ed3652c 100644 --- a/submodule.c +++ b/submodule.c @@ -479,7 +479,7 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info * while ((commit = get_revision(rev))) { struct pretty_print_context ctx = {0}; ctx.date_mode = rev->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(r); strbuf_setlen(&sb, 0); repo_format_commit_message(r, commit, format, &sb, &ctx); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 0/3] move encoding configs to repo_config_values() 2026-02-28 4:07 [PATCH v1] environment: migrate encoding settings to repo-settings Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen @ 2026-03-02 8:57 ` Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen ` (2 more replies) 2 siblings, 3 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-02 8:57 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood, karthik.188, jltobler This is v4 of the series aimed at reducing the global state associated with `git_commit_encoding` and `git_log_output_encoding`. This v4 series is built on top of Olamide Caleb Bello's recent patch: "[Outreachy PATCH v7 1/3] environment: stop storing `core.attributesFile` globally" (Message-ID: <48821a3848bef25c13038be8377ad73e7c17a924.1771258573.git.belkid98@gmail.com>) It adopts the 'struct repo_config_values' introduced in that patch to safely encapsulate repository-specific parsed configurations. I would like to express my gratitude to Phillip Wood for help and guidance. Tian Yuchen (3): commit: plumb 'struct repository' into commit creation APIs pretty: plumb 'struct repository' into pretty-print APIs environment: migrate encoding configs to repo_config_values() builtin/am.c | 6 +++--- builtin/blame.c | 2 +- builtin/checkout.c | 4 ++-- builtin/commit-tree.c | 2 +- builtin/commit.c | 8 ++++---- builtin/history.c | 2 +- builtin/log.c | 4 ++-- builtin/mailinfo.c | 6 +++--- builtin/merge.c | 6 +++--- builtin/rebase.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 4 ++-- builtin/shortlog.c | 4 ++-- builtin/show-branch.c | 2 +- builtin/stash.c | 12 ++++++------ bundle.c | 4 ++-- commit.c | 20 ++++++++++---------- commit.h | 4 ++-- environment.c | 33 ++++++++++++++++++++------------- environment.h | 10 +++++----- log-tree.c | 6 +++--- notes-cache.c | 2 +- notes-utils.c | 2 +- pretty.c | 8 ++++---- pretty.h | 4 ++-- range-diff.c | 2 +- remote-curl.c | 2 +- replay.c | 4 ++-- repository.c | 2 ++ revision.c | 12 +++++++----- sequencer.c | 32 ++++++++++++++++---------------- submodule.c | 2 +- 32 files changed, 113 insertions(+), 102 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v4 1/3] commit: plumb 'struct repository' into commit creation APIs 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen @ 2026-03-02 8:57 ` Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 3/3] environment: migrate encoding configs to repo_config_values() Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-02 8:57 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood, karthik.188, jltobler To pave the way for reducing the global state tied to commit encoding in a subsequent patch, functions like 'commit_tree()' and 'commit_tree_extended()' must be able to access a repository instance. Plumb the 'struct repository' pointer down the call chain for these APIs. For built-ins or subsystems already dependent on global state (e.g., 'notes_cache_write()'), fallback to 'the_repository'. No functional changes are introduced in this preparatory step. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 2 +- builtin/commit-tree.c | 2 +- builtin/commit.c | 2 +- builtin/history.c | 2 +- builtin/merge.c | 4 ++-- builtin/rebase.c | 2 +- builtin/stash.c | 10 +++++----- commit.c | 7 +++---- commit.h | 4 ++-- notes-cache.c | 2 +- notes-utils.c | 2 +- replay.c | 2 +- sequencer.c | 4 ++-- 13 files changed, 22 insertions(+), 23 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index e0c767e223..5296124f84 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1699,7 +1699,7 @@ static void do_commit(const struct am_state *state) : state->author_date, IDENT_STRICT); - if (commit_tree_extended(state->msg, state->msg_len, &tree, parents, + if (commit_tree_extended(the_repository, state->msg, state->msg_len, &tree, parents, &commit, author, committer, state->sign_commit, NULL)) die(_("failed to write commit object")); diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 30535db131..c489749588 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -144,7 +144,7 @@ int cmd_commit_tree(int argc, die_errno(_("git commit-tree: failed to read")); } - if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, + if (commit_tree(the_repository, buffer.buf, buffer.len, &tree_oid, parents, &commit_oid, NULL, sign_commit)) { ret = 1; goto out; diff --git a/builtin/commit.c b/builtin/commit.c index 9e3a09d532..d619fd2ace 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1931,7 +1931,7 @@ int cmd_commit(int argc, append_merge_tag_headers(parents, &tail); } - if (commit_tree_extended(sb.buf, sb.len, &the_repository->index->cache_tree->oid, + if (commit_tree_extended(the_repository, sb.buf, sb.len, &the_repository->index->cache_tree->oid, parents, &oid, author_ident.buf, NULL, sign_commit, extra)) { rollback_index_files(); diff --git a/builtin/history.c b/builtin/history.c index 8dcb9a6046..3d83ac021b 100644 --- a/builtin/history.c +++ b/builtin/history.c @@ -136,7 +136,7 @@ static int commit_tree_with_edited_message(struct repository *repo, original_extra_headers = read_commit_extra_headers(original, exclude_gpgsig); - ret = commit_tree_extended(commit_message.buf, commit_message.len, &original_tree_oid, + ret = commit_tree_extended(repo, commit_message.buf, commit_message.len, &original_tree_oid, original->parents, &rewritten_commit_oid, original_author, NULL, NULL, original_extra_headers); if (ret < 0) diff --git a/builtin/merge.c b/builtin/merge.c index 4e456a381c..7c944fe179 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1000,7 +1000,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) pptr = commit_list_append(head, pptr); pptr = commit_list_append(remoteheads->item, pptr); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, &result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, &result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); finish(head, remoteheads, &result_commit, "In-index merge"); @@ -1027,7 +1027,7 @@ static int finish_automerge(struct commit *head, if (!head_subsumed || fast_forward == FF_NO) commit_list_insert(head, &parents); prepare_to_commit(remoteheads); - if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents, + if (commit_tree(the_repository, merge_msg.buf, merge_msg.len, result_tree, parents, &result_commit, NULL, sign_commit)) die(_("failed to write commit object")); strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy); diff --git a/builtin/rebase.c b/builtin/rebase.c index c487e10907..7b9ab85cc0 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1647,7 +1647,7 @@ int cmd_rebase(int argc, options.upstream_arg = options.upstream_name; } else { if (!options.onto_name) { - if (commit_tree("", 0, the_hash_algo->empty_tree, NULL, + if (commit_tree(the_repository, "", 0, the_hash_algo->empty_tree, NULL, &squash_onto, NULL, NULL) < 0) die(_("Could not create new root commit")); options.squash_onto = &squash_onto; diff --git a/builtin/stash.c b/builtin/stash.c index f06cfa7989..785c1f9e5d 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1258,7 +1258,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, goto done; } - if (commit_tree(untracked_msg.buf, untracked_msg.len, + if (commit_tree(the_repository, untracked_msg.buf, untracked_msg.len, &info->u_tree, NULL, &info->u_commit, NULL, NULL)) { ret = -1; goto done; @@ -1486,7 +1486,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b commit_list_insert(head_commit, &parents); if (write_index_as_tree(&info->i_tree, the_repository->index, repo_get_index_file(the_repository), 0, NULL) || - commit_tree(commit_tree_label.buf, commit_tree_label.len, + commit_tree(the_repository, commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1551,7 +1551,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &parents); commit_list_insert(head_commit, &parents); - if (commit_tree(stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, + if (commit_tree(the_repository, stash_msg_buf->buf, stash_msg_buf->len, &info->w_tree, parents, &info->w_commit, NULL, NULL)) { if (!quiet) fprintf_ln(stderr, _("Cannot record " @@ -2035,7 +2035,7 @@ static int write_commit_with_parents(struct repository *r, author = xmemdupz(orig_author, author_len); committer = xmemdupz(orig_committer, committer_len); - if (commit_tree_extended(msg.buf, msg.len, + if (commit_tree_extended(r, msg.buf, msg.len, r->hash_algo->empty_tree, parents, out, author, committer, NULL, NULL)) { @@ -2258,7 +2258,7 @@ static int do_export_stash(struct repository *r, "2001-09-17T00:00:00Z", 0); /* First, we create a single empty commit. */ - if (commit_tree_extended("", 0, r->hash_algo->empty_tree, NULL, + if (commit_tree_extended(the_repository, "", 0, r->hash_algo->empty_tree, NULL, &base, author, committer, NULL, NULL)) return error(_("unable to write base commit")); diff --git a/commit.c b/commit.c index d16ae73345..71a2b7bbe5 100644 --- a/commit.c +++ b/commit.c @@ -1534,7 +1534,7 @@ void free_commit_extra_headers(struct commit_extra_header *extra) } } -int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, +int commit_tree(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit) { @@ -1542,7 +1542,7 @@ int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree, int result; append_merge_tag_headers(parents, &tail); - result = commit_tree_extended(msg, msg_len, tree, parents, ret, author, + result = commit_tree_extended(r, msg, msg_len, tree, parents, ret, author, NULL, sign_commit, extra); free_commit_extra_headers(extra); return result; @@ -1706,14 +1706,13 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg strbuf_add(buffer, msg, msg_len); } -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, const char *sign_commit, const struct commit_extra_header *extra) { - struct repository *r = the_repository; int result = 0; int encoding_is_utf8; struct strbuf buffer = STRBUF_INIT, compat_buffer = STRBUF_INIT; diff --git a/commit.h b/commit.h index 1635de418b..d3d664d0ff 100644 --- a/commit.h +++ b/commit.h @@ -289,12 +289,12 @@ struct commit_extra_header { void append_merge_tag_headers(const struct commit_list *parents, struct commit_extra_header ***tail); -int commit_tree(const char *msg, size_t msg_len, +int commit_tree(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *sign_commit); -int commit_tree_extended(const char *msg, size_t msg_len, +int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, const struct object_id *tree, const struct commit_list *parents, struct object_id *ret, const char *author, const char *committer, diff --git a/notes-cache.c b/notes-cache.c index bf5bb1f6c1..5dbbd94ea3 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -66,7 +66,7 @@ int notes_cache_write(struct notes_cache *c) if (write_notes_tree(&c->tree, &tree_oid)) return -1; - if (commit_tree(c->validity, strlen(c->validity), &tree_oid, NULL, + if (commit_tree(the_repository, c->validity, strlen(c->validity), &tree_oid, NULL, &commit_oid, NULL, NULL) < 0) return -1; if (refs_update_ref(get_main_ref_store(the_repository), "update notes cache", c->tree.update_ref, &commit_oid, diff --git a/notes-utils.c b/notes-utils.c index 5c1c75d5b8..4671a11993 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -36,7 +36,7 @@ void create_notes_commit(struct repository *r, /* else: t->ref points to nothing, assume root/orphan commit */ } - if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL, + if (commit_tree(r, msg, msg_len, &tree_oid, parents, result_oid, NULL, NULL)) die("Failed to commit notes tree to database"); diff --git a/replay.c b/replay.c index f97d652f33..8704547aa1 100644 --- a/replay.c +++ b/replay.c @@ -68,7 +68,7 @@ static struct commit *create_commit(struct repository *repo, strbuf_addstr(&msg, orig_message); author = get_author(message); reset_ident_date(); - if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents, + if (commit_tree_extended(repo, msg.buf, msg.len, &tree->object.oid, parents, &ret, author, NULL, sign_commit, extra)) { error(_("failed to write commit object")); goto out; diff --git a/sequencer.c b/sequencer.c index a3eb39bb25..627020d65b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1672,7 +1672,7 @@ static int try_to_commit(struct repository *r, free(email); } - if (commit_tree_extended(msg->buf, msg->len, &tree, parents, oid, + if (commit_tree_extended(r, msg->buf, msg->len, &tree, parents, oid, author, committer, opts->gpg_sign, extra)) { res = error(_("failed to write commit object")); goto out; @@ -3989,7 +3989,7 @@ static int do_reset(struct repository *r, if (len == 10 && !strncmp("[new root]", name, len)) { if (!opts->have_squash_onto) { const char *hex; - if (commit_tree("", 0, the_hash_algo->empty_tree, + if (commit_tree(r, "", 0, the_hash_algo->empty_tree, NULL, &opts->squash_onto, NULL, NULL)) return error(_("writing fake root commit")); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 2/3] pretty: plumb 'struct repository' into pretty-print APIs 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen @ 2026-03-02 8:57 ` Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 3/3] environment: migrate encoding configs to repo_config_values() Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-02 8:57 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood, karthik.188, jltobler To prepare for the elimination of the global state associated with 'log_output_encoding', functions responsible for formatting commit messages, such as 'pretty_print_commit()' and 'pp_commit_easy()', must be able to access a repository instance. Plumb the 'struct repository' pointer down the call chain for these APIs. Where no such context is readily available in built-ins or high-level functions, fallback to 'the_repository'. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/checkout.c | 4 ++-- builtin/log.c | 2 +- builtin/merge.c | 2 +- builtin/reset.c | 2 +- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- builtin/show-branch.c | 2 +- builtin/stash.c | 2 +- bundle.c | 2 +- log-tree.c | 2 +- pretty.c | 6 +++--- pretty.h | 4 ++-- range-diff.c | 2 +- sequencer.c | 6 +++--- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 2d816de583..3b9e3e45f9 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -689,7 +689,7 @@ static void describe_detached_head(const char *msg, struct commit *commit) struct strbuf sb = STRBUF_INIT; if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &sb); if (print_sha1_ellipsis()) { fprintf(stderr, "%s %s... %s\n", msg, repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), @@ -1077,7 +1077,7 @@ static void describe_one_orphan(struct strbuf *sb, struct commit *commit) strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(sb, ' '); if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, sb); strbuf_addch(sb, '\n'); } diff --git a/builtin/log.c b/builtin/log.c index 8ab6d3a943..0758aed580 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -2521,7 +2521,7 @@ static void print_commit(char sign, struct commit *commit, int verbose, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev)); } else { struct strbuf buf = STRBUF_INIT; - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); fprintf(file, "%c %s %s\n", sign, repo_find_unique_abbrev(the_repository, &commit->object.oid, abbrev), buf.buf); diff --git a/builtin/merge.c b/builtin/merge.c index 7c944fe179..dff8185776 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -470,7 +470,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead strbuf_addch(&out, '\n'); strbuf_addf(&out, "commit %s\n", oid_to_hex(&commit->object.oid)); - pretty_print_commit(&ctx, commit, &out); + pretty_print_commit(the_repository, &ctx, commit, &out); } write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len); strbuf_release(&out); diff --git a/builtin/reset.c b/builtin/reset.c index c48d9845f8..733f3fa905 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -141,7 +141,7 @@ static void print_new_head_line(struct commit *commit) printf(_("HEAD is now at %s"), repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); - pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &buf); if (buf.len > 0) printf(" %s", buf.buf); putchar('\n'); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index ddea8aa251..57c7b8d3ff 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -307,7 +307,7 @@ static void show_commit(struct commit *commit, void *data) ctx.output_encoding = get_log_output_encoding(); ctx.color = revs->diffopt.use_color; ctx.rev = revs; - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); if (buf.len) { if (revs->commit_format != CMIT_FMT_ONELINE) graph_show_oneline(revs->graph); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index d80bf1a7d0..109785fd00 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -252,7 +252,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) if (!log->summary) { if (log->user_format) - pretty_print_commit(&ctx, commit, &oneline); + pretty_print_commit(the_repository, &ctx, commit, &oneline); else repo_format_commit_message(the_repository, commit, "%s", &oneline, &ctx); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index f02831b085..6bfe9e2e96 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -310,7 +310,7 @@ static void show_one_commit(struct commit *commit, int no_name) struct commit_name *name = commit_to_name(commit); if (commit->object.parsed) { - pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, commit, &pretty); pretty_str = pretty.buf; } skip_prefix(pretty_str, "[PATCH] ", &pretty_str); diff --git a/builtin/stash.c b/builtin/stash.c index 785c1f9e5d..a522bb6de5 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1480,7 +1480,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b &head_commit->object.oid, DEFAULT_ABBREV); strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1); - pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg); + pp_commit_easy(the_repository, CMIT_FMT_ONELINE, head_commit, &msg); strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); diff --git a/bundle.c b/bundle.c index 42327f9739..3bc2ed9ee9 100644 --- a/bundle.c +++ b/bundle.c @@ -463,7 +463,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) ctx.fmt = CMIT_FMT_ONELINE; ctx.output_encoding = get_log_output_encoding(); strbuf_reset(&buf); - pretty_print_commit(&ctx, commit, &buf); + pretty_print_commit(the_repository, &ctx, commit, &buf); strbuf_trim(&buf); object = (struct object *)commit; diff --git a/log-tree.c b/log-tree.c index 7e048701d0..fd2fb0bed6 100644 --- a/log-tree.c +++ b/log-tree.c @@ -885,7 +885,7 @@ void show_log(struct rev_info *opt) ctx.from_ident = &opt->from_ident; if (opt->graph) ctx.graph_width = graph_width(opt->graph); - pretty_print_commit(&ctx, commit, &msgbuf); + pretty_print_commit(opt->repo, &ctx, commit, &msgbuf); if (opt->add_signoff) append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP); diff --git a/pretty.c b/pretty.c index e0646bbc5d..51e3480431 100644 --- a/pretty.c +++ b/pretty.c @@ -2281,7 +2281,7 @@ void pp_remainder(struct pretty_print_context *pp, } } -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb) { @@ -2363,10 +2363,10 @@ void pretty_print_commit(struct pretty_print_context *pp, repo_unuse_commit_buffer(the_repository, commit, reencoded); } -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb) { struct pretty_print_context pp = {0}; pp.fmt = fmt; - pretty_print_commit(&pp, commit, sb); + pretty_print_commit(r, &pp, commit, sb); } diff --git a/pretty.h b/pretty.h index fac699033e..13eb0189bd 100644 --- a/pretty.h +++ b/pretty.h @@ -82,7 +82,7 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w); * Shortcut for invoking pretty_print_commit if we do not have any context. * Context would be set empty except "fmt". */ -void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit, +void pp_commit_easy(struct repository *r, enum cmit_fmt fmt, const struct commit *commit, struct strbuf *sb); /* @@ -132,7 +132,7 @@ void get_commit_format(const char *arg, struct rev_info *); * and put it into "sb". * Please use this function if you have a context (candidate for "pp"). */ -void pretty_print_commit(struct pretty_print_context *pp, +void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb); diff --git a/range-diff.c b/range-diff.c index 57edff40a8..31d38c2318 100644 --- a/range-diff.c +++ b/range-diff.c @@ -460,7 +460,7 @@ static void output_pair_header(struct diff_options *diffopt, strbuf_addf(buf, "%s%s", color_reset, color); strbuf_addch(buf, ' '); - pp_commit_easy(CMIT_FMT_ONELINE, commit, buf); + pp_commit_easy(diffopt->repo, CMIT_FMT_ONELINE, commit, buf); } strbuf_addf(buf, "%s\n", color_reset); diff --git a/sequencer.c b/sequencer.c index 627020d65b..e6b3e05fce 100644 --- a/sequencer.c +++ b/sequencer.c @@ -5870,7 +5870,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, continue; strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); to_merge = commit->parents ? commit->parents->next : NULL; if (!to_merge) { @@ -6012,7 +6012,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, strbuf_addf(out, "%s onto\n", cmd_reset); else { strbuf_reset(&oneline); - pretty_print_commit(pp, commit, &oneline); + pretty_print_commit(revs->repo, pp, commit, &oneline); strbuf_addf(out, "%s %s %s\n", cmd_reset, to, oneline.buf); } @@ -6124,7 +6124,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, continue; strbuf_addf(out, "%s %s ", insn, oid_to_hex(&commit->object.oid)); - pretty_print_commit(&pp, commit, out); + pretty_print_commit(r, &pp, commit, out); if (is_empty) strbuf_addf(out, " %s empty", comment_line_str); strbuf_addch(out, '\n'); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v4 3/3] environment: migrate encoding configs to repo_config_values() 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen @ 2026-03-02 8:57 ` Tian Yuchen 2 siblings, 0 replies; 13+ messages in thread From: Tian Yuchen @ 2026-03-02 8:57 UTC (permalink / raw) To: git; +Cc: gitster, phillip.wood, karthik.188, jltobler The global variables 'git_commit_encoding' and 'git_log_output_encoding' prevent libification. Migrate these variables into the 'struct repo_config_values'. This ensures that they are safely accessed via the 'repo_config_values()' accessor which prevents uninitialized or cross-repository access. Note that these variables are not migrated to 'repo_settings'. As eagerly parsed user preferences, deferring them to lazy evaluation would break early validation. Currently, during the config parsing phase in 'git_default_i18n_config()', the values are still parsed into the 'the_repository' instance of 'repo_config_values', Since safely plumbing a repository pointer through the 'git_default_config' callback machinery remains highly invasive due to custom contexts being passed via the 'void *cb' parameter. However, the read-paths (commit APIs and log formatters) updated in previous patches are now fully plumbed to accept any repository instance. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> --- builtin/am.c | 4 ++-- builtin/blame.c | 2 +- builtin/commit.c | 6 +++--- builtin/log.c | 2 +- builtin/mailinfo.c | 6 +++--- builtin/rev-list.c | 2 +- builtin/shortlog.c | 2 +- bundle.c | 2 +- commit.c | 13 +++++++------ environment.c | 33 ++++++++++++++++++++------------- environment.h | 10 +++++----- log-tree.c | 4 ++-- pretty.c | 2 +- remote-curl.c | 2 +- replay.c | 2 +- repository.c | 2 ++ revision.c | 12 +++++++----- sequencer.c | 22 +++++++++++----------- submodule.c | 2 +- 19 files changed, 71 insertions(+), 59 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 5296124f84..990b6c54e7 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail) setup_mailinfo(the_repository, &mi); if (state->utf8) - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = get_commit_output_encoding(the_repository); else mi.metainfo_charset = NULL; @@ -1355,7 +1355,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit) struct ident_split id; buffer = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + get_commit_output_encoding(the_repository)); ident_line = find_commit_header(buffer, "author", &ident_len); if (!ident_line) diff --git a/builtin/blame.c b/builtin/blame.c index eac2fe7320..0ad9f2c9f7 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -202,7 +202,7 @@ static void get_commit_info(struct commit *commit, struct commit_info *ret) const char *subject, *encoding; const char *message; - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(the_repository); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); get_ac_line(message, "\nauthor ", &ret->author, &ret->author_mail, diff --git a/builtin/commit.c b/builtin/commit.c index d619fd2ace..caf5896d97 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -794,7 +794,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, c = lookup_commit_reference_by_name(squash_message); if (!c) die(_("could not lookup commit '%s'"), squash_message); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = get_commit_output_encoding(the_repository); repo_format_commit_message(the_repository, c, "squash! %s\n\n", &sb, &ctx); @@ -829,7 +829,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, commit = lookup_commit_reference_by_name(fixup_commit); if (!commit) die(_("could not lookup commit '%s'"), fixup_commit); - ctx.output_encoding = get_commit_output_encoding(); + ctx.output_encoding = get_commit_output_encoding(the_repository); fmt = xstrfmt("%s! %%s\n\n", fixup_prefix); repo_format_commit_message(the_repository, commit, fmt, &sb, &ctx); @@ -1235,7 +1235,7 @@ static const char *read_commit_message(const char *name) commit = lookup_commit_reference_by_name(name); if (!commit) die(_("could not lookup commit '%s'"), name); - out_enc = get_commit_output_encoding(); + out_enc = get_commit_output_encoding(the_repository); return repo_logmsg_reencode(the_repository, commit, NULL, out_enc); } diff --git a/builtin/log.c b/builtin/log.c index 0758aed580..8edb3c54e7 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -568,7 +568,7 @@ static void show_tagger(const char *buf, struct rev_info *rev) pp.fmt = rev->commit_format; pp.date_mode = rev->date_mode; - pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding()); + pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding(the_repository)); fprintf(rev->diffopt.file, "%s", out.buf); strbuf_release(&out); } diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 8de7ba7de1..4f17cf1598 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -52,7 +52,7 @@ static int parse_opt_quoted_cr(const struct option *opt, const char *arg, int un int cmd_mailinfo(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { struct metainfo_charset meta_charset; struct mailinfo mi; @@ -83,7 +83,7 @@ int cmd_mailinfo(int argc, OPT_END() }; - setup_mailinfo(the_repository, &mi); + setup_mailinfo(repo, &mi); meta_charset.policy = CHARSET_DEFAULT; argc = parse_options(argc, argv, prefix, options, mailinfo_usage, 0); @@ -93,7 +93,7 @@ int cmd_mailinfo(int argc, switch (meta_charset.policy) { case CHARSET_DEFAULT: - mi.metainfo_charset = get_commit_output_encoding(); + mi.metainfo_charset = get_commit_output_encoding(repo); break; case CHARSET_NO_REENCODE: mi.metainfo_charset = NULL; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 57c7b8d3ff..3732edae8b 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -304,7 +304,7 @@ static void show_commit(struct commit *commit, void *data) ctx.date_mode = revs->date_mode; ctx.date_mode_explicit = revs->date_mode_explicit; ctx.fmt = revs->commit_format; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); ctx.color = revs->diffopt.use_color; ctx.rev = revs; pretty_print_commit(the_repository, &ctx, commit, &buf); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 109785fd00..79606e57be 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -248,7 +248,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) ctx.fmt = CMIT_FMT_USERFORMAT; ctx.abbrev = log->abbrev; ctx.date_mode = log->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); if (!log->summary) { if (log->user_format) diff --git a/bundle.c b/bundle.c index 3bc2ed9ee9..3b98cdd6fd 100644 --- a/bundle.c +++ b/bundle.c @@ -461,7 +461,7 @@ static void write_bundle_prerequisites(struct commit *commit, void *data) write_or_die(bpi->fd, buf.buf, buf.len); ctx.fmt = CMIT_FMT_ONELINE; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(the_repository); strbuf_reset(&buf); pretty_print_commit(the_repository, &ctx, commit, &buf); strbuf_trim(&buf); diff --git a/commit.c b/commit.c index 71a2b7bbe5..cb8ec675d1 100644 --- a/commit.c +++ b/commit.c @@ -1663,7 +1663,8 @@ N_("Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" "variable i18n.commitEncoding to the encoding your project uses.\n"); -static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg_len, +static void write_commit_tree(struct repository *r, struct strbuf *buffer, + const char *msg, size_t msg_len, const struct object_id *tree, const struct object_id *parents, size_t parents_len, const char *author, const char *committer, @@ -1673,7 +1674,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg size_t i; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(get_commit_output_encoding(r)); strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */ strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree)); @@ -1694,7 +1695,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg committer = git_committer_info(IDENT_STRICT); strbuf_addf(buffer, "committer %s\n", committer); if (!encoding_is_utf8) - strbuf_addf(buffer, "encoding %s\n", git_commit_encoding); + strbuf_addf(buffer, "encoding %s\n", get_commit_output_encoding(r)); while (extra) { add_extra_header(buffer, extra); @@ -1722,7 +1723,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, size_t i, nparents; /* Not having i18n.commitencoding is the same as having utf-8 */ - encoding_is_utf8 = is_encoding_utf8(git_commit_encoding); + encoding_is_utf8 = is_encoding_utf8(get_commit_output_encoding(r)); odb_assert_oid_type(the_repository->objects, tree, OBJ_TREE); @@ -1735,7 +1736,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, for (const struct commit_list *p = parents; p; p = p->next) oidcpy(&parent_buf[i++], &p->item->object.oid); - write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); + write_commit_tree(r, &buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra); if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) { result = -1; goto out; @@ -1763,7 +1764,7 @@ int commit_tree_extended(struct repository *r, const char *msg, size_t msg_len, free(mapped_parents); goto out; } - write_commit_tree(&compat_buffer, msg, msg_len, &mapped_tree, + write_commit_tree(r, &compat_buffer, msg, msg_len, &mapped_tree, mapped_parents, nparents, author, committer, compat_extra); free_commit_extra_headers(compat_extra); free(mapped_parents); diff --git a/environment.c b/environment.c index 3ee88e20ff..948e22ec26 100644 --- a/environment.c +++ b/environment.c @@ -50,8 +50,6 @@ int ignore_case; int assume_unchanged; int is_bare_repository_cfg = -1; /* unspecified */ int warn_on_object_refname_ambiguity = 1; -char *git_commit_encoding; -char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; int zlib_compression_level = Z_BEST_SPEED; @@ -194,15 +192,22 @@ const char *strip_namespace(const char *namespaced_ref) return NULL; } -const char *get_log_output_encoding(void) +const char *get_log_output_encoding(struct repository *r) { - return git_log_output_encoding ? git_log_output_encoding - : get_commit_output_encoding(); + struct repo_config_values *cfg; + if (r != the_repository) + return get_commit_output_encoding(r); + cfg = repo_config_values(r); + return cfg->log_output_encoding ? cfg->log_output_encoding : get_commit_output_encoding(r); } -const char *get_commit_output_encoding(void) +const char *get_commit_output_encoding(struct repository *r) { - return git_commit_encoding ? git_commit_encoding : "UTF-8"; + struct repo_config_values *cfg; + if (r != the_repository) + return "UTF-8"; + cfg= repo_config_values(r); + return cfg->commit_encoding ? cfg->commit_encoding : "UTF-8"; } int use_optional_locks(void) @@ -567,17 +572,17 @@ static int git_default_sparse_config(const char *var, const char *value) static int git_default_i18n_config(const char *var, const char *value) { + struct repo_config_values *cfg = repo_config_values(the_repository); + if (!strcmp(var, "i18n.commitencoding")) { - FREE_AND_NULL(git_commit_encoding); - return git_config_string(&git_commit_encoding, var, value); + FREE_AND_NULL(cfg->commit_encoding); + return git_config_string(&cfg->commit_encoding, var, value); } - if (!strcmp(var, "i18n.logoutputencoding")) { - FREE_AND_NULL(git_log_output_encoding); - return git_config_string(&git_log_output_encoding, var, value); + FREE_AND_NULL(cfg->log_output_encoding); + return git_config_string(&cfg->log_output_encoding, var, value); } - /* Add other config variables here and to Documentation/config.adoc. */ return 0; } @@ -738,6 +743,8 @@ int git_default_config(const char *var, const char *value, void repo_config_values_init(struct repo_config_values *cfg) { cfg->attributes_file = NULL; + cfg->commit_encoding = NULL; + cfg->log_output_encoding = NULL; cfg->apply_sparse_checkout = 0; cfg->branch_track = BRANCH_TRACK_REMOTE; } diff --git a/environment.h b/environment.h index 8c221b567b..358c7d05e0 100644 --- a/environment.h +++ b/environment.h @@ -93,6 +93,9 @@ struct repo_config_values { /* section "branch" config values */ enum branch_track branch_track; + + char *commit_encoding; + char *log_output_encoding; }; struct repo_config_values *repo_config_values(struct repository *repo); @@ -206,11 +209,8 @@ extern enum object_creation_mode object_creation_mode; extern int grafts_keep_true_parents; -const char *get_log_output_encoding(void); -const char *get_commit_output_encoding(void); - -extern char *git_commit_encoding; -extern char *git_log_output_encoding; +const char *get_log_output_encoding(struct repository *r); +const char *get_commit_output_encoding(struct repository *r); extern char *editor_program; extern char *askpass_program; diff --git a/log-tree.c b/log-tree.c index fd2fb0bed6..364fd015f5 100644 --- a/log-tree.c +++ b/log-tree.c @@ -859,7 +859,7 @@ void show_log(struct rev_info *opt) raw = (opt->commit_format == CMIT_FMT_USERFORMAT); format_display_notes(&commit->object.oid, ¬ebuf, - get_log_output_encoding(), raw); + get_log_output_encoding(opt->repo), raw); ctx.notes_message = strbuf_detach(¬ebuf, NULL); } @@ -879,7 +879,7 @@ void show_log(struct rev_info *opt) ctx.mailmap = opt->mailmap; ctx.color = opt->diffopt.use_color; ctx.expand_tabs_in_log = opt->expand_tabs_in_log; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(opt->repo); ctx.rev = opt; if (opt->from_ident.mail_begin && opt->from_ident.name_begin) ctx.from_ident = &opt->from_ident; diff --git a/pretty.c b/pretty.c index 51e3480431..6b585e2763 100644 --- a/pretty.c +++ b/pretty.c @@ -2298,7 +2298,7 @@ void pretty_print_commit(struct repository *r, struct pretty_print_context *pp, return; } - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(r); msg = reencoded = repo_logmsg_reencode(the_repository, commit, NULL, encoding); diff --git a/remote-curl.c b/remote-curl.c index 92e40bb682..146cb8930d 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -379,7 +379,7 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset, if (strcmp(type->buf, "text/plain")) return -1; if (charset->len) - strbuf_reencode(msg, charset->buf, get_log_output_encoding()); + strbuf_reencode(msg, charset->buf, get_log_output_encoding(the_repository)); strbuf_trim(msg); if (!msg->len) diff --git a/replay.c b/replay.c index 8704547aa1..0012d3aa18 100644 --- a/replay.c +++ b/replay.c @@ -56,7 +56,7 @@ static struct commit *create_commit(struct repository *repo, char *sign_commit = NULL; /* FIXME: cli users might want to sign again */ struct commit_extra_header *extra = NULL; struct strbuf msg = STRBUF_INIT; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = get_commit_output_encoding(repo); const char *message = repo_logmsg_reencode(repo, based_on, NULL, out_enc); const char *orig_message = NULL; diff --git a/repository.c b/repository.c index 0207bcb299..3202d67bf0 100644 --- a/repository.c +++ b/repository.c @@ -384,6 +384,8 @@ void repo_clear(struct repository *repo) FREE_AND_NULL(repo->index_file); FREE_AND_NULL(repo->worktree); FREE_AND_NULL(repo->submodule_prefix); + FREE_AND_NULL(repo->config_values_private_.commit_encoding); + FREE_AND_NULL(repo->config_values_private_.log_output_encoding); odb_free(repo->objects); repo->objects = NULL; diff --git a/revision.c b/revision.c index 29972c3a19..5fb85c0f13 100644 --- a/revision.c +++ b/revision.c @@ -2675,11 +2675,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--invert-grep")) { revs->grep_filter.no_body_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { - free(git_log_output_encoding); + struct repo_config_values *cfg = repo_config_values(revs->repo); + + free(cfg->log_output_encoding); if (strcmp(optarg, "none")) - git_log_output_encoding = xstrdup(optarg); + cfg->log_output_encoding = xstrdup(optarg); else - git_log_output_encoding = xstrdup(""); + cfg->log_output_encoding = xstrdup(""); return argcount; } else if (!strcmp(arg, "--reverse")) { revs->reverse ^= 1; @@ -3129,7 +3131,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s diff_setup_done(&revs->diffopt); - if (!is_encoding_utf8(get_log_output_encoding())) + if (!is_encoding_utf8(get_log_output_encoding(revs->repo))) revs->grep_filter.ignore_locale = 1; compile_grep_patterns(&revs->grep_filter); @@ -4063,7 +4065,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) * so we will not end up with a buffer that has two different encodings * in it. */ - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(opt->repo); message = repo_logmsg_reencode(the_repository, commit, NULL, encoding); /* Copy the commit to temporary if we are using "fake" headers */ diff --git a/sequencer.c b/sequencer.c index e6b3e05fce..62717910d2 100644 --- a/sequencer.c +++ b/sequencer.c @@ -480,13 +480,13 @@ static const char *short_commit_name(struct repository *r, struct commit *commit return repo_find_unique_abbrev(r, &commit->object.oid, DEFAULT_ABBREV); } -static int get_message(struct commit *commit, struct commit_message *out) +static int get_message(struct repository *r, struct commit *commit, struct commit_message *out) { const char *abbrev, *subject; int subject_len; out->message = repo_logmsg_reencode(the_repository, commit, NULL, - get_commit_output_encoding()); + get_commit_output_encoding(r)); abbrev = short_commit_name(the_repository, commit); subject_len = find_commit_subject(out->message, &subject); @@ -1539,7 +1539,7 @@ static int try_to_commit(struct repository *r, if (flags & AMEND_MSG) { const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL }; - const char *out_enc = get_commit_output_encoding(); + const char *out_enc = get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, current_head, NULL, out_enc); @@ -2054,7 +2054,7 @@ static int update_squash_messages(struct repository *r, struct strbuf buf = STRBUF_INIT; int res = 0; const char *message, *body; - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); if (!is_fixup(command)) BUG("not a FIXUP or SQUASH %d", command); @@ -2324,7 +2324,7 @@ static int do_pick_commit(struct repository *r, else parent = commit->parents->item; - if (get_message(commit, &msg) != 0) + if (get_message(r, commit, &msg) != 0) return error(_("cannot get commit message for %s"), oid_to_hex(&commit->object.oid)); @@ -3344,7 +3344,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list, if (prepare_revs(opts)) return -1; - encoding = get_log_output_encoding(); + encoding = get_log_output_encoding(the_repository); while ((commit = get_revision(opts->revs))) { struct todo_item *item = append_new_todo(todo_list); @@ -3730,7 +3730,7 @@ static int make_patch(struct repository *r, } if (!file_exists(rebase_path_message())) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); const char *commit_buffer = repo_logmsg_reencode(r, commit, NULL, encoding); @@ -4187,7 +4187,7 @@ static int do_merge(struct repository *r, } if (commit) { - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); const char *message = repo_logmsg_reencode(r, commit, NULL, encoding); const char *body; @@ -4831,7 +4831,7 @@ static int stopped_at_head(struct repository *r) if (repo_get_oid(r, "HEAD", &head) || !(commit = lookup_commit(r, &head)) || - repo_parse_commit(r, commit) || get_message(commit, &message)) + repo_parse_commit(r, commit) || get_message(r, commit, &message)) fprintf(stderr, _("Stopped at HEAD\n")); else { fprintf(stderr, _("Stopped at %s\n"), message.label); @@ -5311,7 +5311,7 @@ static int commit_staged_changes(struct repository *r, struct commit *commit; const char *msg; const char *path = rebase_path_squash_msg(); - const char *encoding = get_commit_output_encoding(); + const char *encoding = get_commit_output_encoding(r); if (parse_head(r, &commit)) { ret = error(_("could not parse HEAD")); @@ -6092,7 +6092,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, get_commit_format(format, &revs); free(format); pp.fmt = revs.commit_format; - pp.output_encoding = get_log_output_encoding(); + pp.output_encoding = get_log_output_encoding(r); setup_revisions_from_strvec(argv, &revs, NULL); if (argv->nr > 1) { diff --git a/submodule.c b/submodule.c index 508938e4da..a58ed3652c 100644 --- a/submodule.c +++ b/submodule.c @@ -479,7 +479,7 @@ static void print_submodule_diff_summary(struct repository *r, struct rev_info * while ((commit = get_revision(rev))) { struct pretty_print_context ctx = {0}; ctx.date_mode = rev->date_mode; - ctx.output_encoding = get_log_output_encoding(); + ctx.output_encoding = get_log_output_encoding(r); strbuf_setlen(&sb, 0); repo_format_commit_message(r, commit, format, &sb, &ctx); -- 2.43.0 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-03-02 8:58 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-28 4:07 [PATCH v1] environment: migrate encoding settings to repo-settings Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 0/3] migrate encoding settings and bubble up repository Tian Yuchen 2026-02-28 19:01 ` [PATCH v2 1/3] environment: migrate encoding settings to repo-settings Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 2/3] commit: pass 'struct repository' to commit creation APIs Tian Yuchen 2026-02-28 19:02 ` [PATCH v2 3/3] pretty: pass 'struct repository' to pretty_print_commit() Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 0/3] environment: move encoding configs to struct repository Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen 2026-03-01 20:35 ` [PATCH v3 3/3] environment: migrate encoding configs to struct repository Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 0/3] move encoding configs to repo_config_values() Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 1/3] commit: plumb 'struct repository' into commit creation APIs Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 2/3] pretty: plumb 'struct repository' into pretty-print APIs Tian Yuchen 2026-03-02 8:57 ` [PATCH v4 3/3] environment: migrate encoding configs to repo_config_values() Tian Yuchen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox