* [PATCH] merge-ort: accept rename settings given without a value
@ 2026-10-31 10:06 Thomas Bachem via GitGitGadget
2026-11-01 0:52 ` Junio C Hamano
0 siblings, 1 reply; 2+ messages in thread
From: Thomas Bachem via GitGitGadget @ 2026-10-31 10:06 UTC (permalink / raw)
To: git; +Cc: Elijah Newren, Junio C Hamano, Thomas Bachem, Thomas Bachem
From: Thomas Bachem <mail@thomasbachem.com>
"git -c merge.renames merge" fails with "missing value for
'merge.renames'", although git(1) says that "git -c foo.bar" sets
foo.bar to true. The same happens with diff.renames and
merge.directoryRenames, and with a setting written without
"= <value>" in a config file, which git-config(1) also documents as
true. Every command that merges through merge-ort fails this way.
merge-ort reads these settings with repo_config_get_string(), which
rejects a missing value. Read them with repo_config_get_value()
instead. git_config_rename() and git_parse_maybe_bool() already take
a missing value as true.
Assisted-by: Claude Fable 5.1
Signed-off-by: Thomas Bachem <mail@thomasbachem.com>
---
merge-ort: accept rename settings given without a value
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2284%2Fthomasbachem%2Fmerge-ort-valueless-renames-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2284/thomasbachem/merge-ort-valueless-renames-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2284
merge-ort.c | 20 ++++++++------------
t/t6423-merge-rename-directories.sh | 17 +++++++++++++++++
t/t6434-merge-recursive-rename-options.sh | 12 ++++++++++++
3 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/merge-ort.c b/merge-ort.c
index c410a5d353..24ddd97696 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -5453,31 +5453,27 @@ void merge_incore_recursive(struct merge_options *opt,
static void merge_recursive_config(struct merge_options *opt, int ui)
{
char *value = NULL;
+ const char *v;
int renormalize = 0;
repo_config_get_int(opt->repo, "merge.verbosity", &opt->verbosity);
repo_config_get_int(opt->repo, "diff.renamelimit", &opt->rename_limit);
repo_config_get_int(opt->repo, "merge.renamelimit", &opt->rename_limit);
repo_config_get_bool(opt->repo, "merge.renormalize", &renormalize);
opt->renormalize = renormalize;
- if (!repo_config_get_string(opt->repo, "diff.renames", &value)) {
- opt->detect_renames = git_config_rename("diff.renames", value);
- free(value);
- }
- if (!repo_config_get_string(opt->repo, "merge.renames", &value)) {
- opt->detect_renames = git_config_rename("merge.renames", value);
- free(value);
- }
- if (!repo_config_get_string(opt->repo, "merge.directoryrenames", &value)) {
- int boolval = git_parse_maybe_bool(value);
+ if (!repo_config_get_value(opt->repo, "diff.renames", &v))
+ opt->detect_renames = git_config_rename("diff.renames", v);
+ if (!repo_config_get_value(opt->repo, "merge.renames", &v))
+ opt->detect_renames = git_config_rename("merge.renames", v);
+ if (!repo_config_get_value(opt->repo, "merge.directoryrenames", &v)) {
+ int boolval = git_parse_maybe_bool(v);
if (0 <= boolval) {
opt->detect_directory_renames = boolval ?
MERGE_DIRECTORY_RENAMES_TRUE :
MERGE_DIRECTORY_RENAMES_NONE;
- } else if (!strcasecmp(value, "conflict")) {
+ } else if (!strcasecmp(v, "conflict")) {
opt->detect_directory_renames =
MERGE_DIRECTORY_RENAMES_CONFLICT;
} /* avoid erroring on values from future versions of git */
- free(value);
}
if (ui) {
if (!repo_config_get_string(opt->repo, "diff.algorithm", &value)) {
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 24d4c5447b..da145c150c 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -97,6 +97,23 @@ test_expect_success '1a: Simple directory rename detection' '
)
'
+test_expect_success '1a (valueless): merge.directoryRenames without a value means true' '
+ mkdir valueless &&
+ (
+ cd valueless &&
+ test_setup_1a &&
+ cd 1a &&
+
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames merge -s recursive B^0 &&
+
+ git rev-parse >actual HEAD:y/d HEAD:y/e/f &&
+ git rev-parse >expect B:z/d B:z/e/f &&
+ test_cmp expect actual
+ )
+'
+
# Testcase 1b, Merge a directory with another
# Commit O: z/{b,c}, y/d
# Commit A: z/{b,c,e}, y/d
diff --git a/t/t6434-merge-recursive-rename-options.sh b/t/t6434-merge-recursive-rename-options.sh
index 5a6f74839c..427de2ba95 100755
--- a/t/t6434-merge-recursive-rename-options.sh
+++ b/t/t6434-merge-recursive-rename-options.sh
@@ -332,4 +332,16 @@ test_expect_success 'merge.renames overrides diff.renames' '
$check_50
'
+test_expect_success 'diff.renames without a value means true' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git -c diff.renames merge-recursive $tail &&
+ $check_50
+'
+
+test_expect_success 'merge.renames without a value means true' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git -c diff.renames=false -c merge.renames merge-recursive $tail &&
+ $check_50
+'
+
test_done
base-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd
--
gitgitgadget
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] merge-ort: accept rename settings given without a value
2026-10-31 10:06 [PATCH] merge-ort: accept rename settings given without a value Thomas Bachem via GitGitGadget
@ 2026-11-01 0:52 ` Junio C Hamano
0 siblings, 0 replies; 2+ messages in thread
From: Junio C Hamano @ 2026-11-01 0:52 UTC (permalink / raw)
To: Thomas Bachem via GitGitGadget; +Cc: git, Elijah Newren, Thomas Bachem
"Thomas Bachem via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Thomas Bachem <mail@thomasbachem.com>
>
> "git -c merge.renames merge" fails with "missing value for
> 'merge.renames'", although git(1) says that "git -c foo.bar" sets
> foo.bar to true. The same happens with diff.renames and
> merge.directoryRenames, and with a setting written without
> "= <value>" in a config file, which git-config(1) also documents as
> true. Every command that merges through merge-ort fails this way.
Searching the list archive for "valueless true" tells us that we had
corrected a handful of instances of config_get_string() with a call
to config_get_value() in the past half year.
And this patch seems to be in line with the other efforts to fix the
same misuse.
> + if (!repo_config_get_value(opt->repo, "diff.renames", &v))
> + opt->detect_renames = git_config_rename("diff.renames", v);
> + if (!repo_config_get_value(opt->repo, "merge.renames", &v))
> + opt->detect_renames = git_config_rename("merge.renames", v);
> + if (!repo_config_get_value(opt->repo, "merge.directoryrenames", &v)) {
> + int boolval = git_parse_maybe_bool(v);
> if (0 <= boolval) {
> opt->detect_directory_renames = boolval ?
> MERGE_DIRECTORY_RENAMES_TRUE :
> MERGE_DIRECTORY_RENAMES_NONE;
> - } else if (!strcasecmp(value, "conflict")) {
> + } else if (!strcasecmp(v, "conflict")) {
> opt->detect_directory_renames =
> MERGE_DIRECTORY_RENAMES_CONFLICT;
> } /* avoid erroring on values from future versions of git */
> - free(value);
> }
OK. Since get_value(), unlike get_string(), lets us borrow the
value as "const char *", once we used to drive git_config_rename() or
compared with fixed string to turn it into an enum value, we can simply
forget without calling free(), which is simpler.
Nicely done.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-01 0:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-31 10:06 [PATCH] merge-ort: accept rename settings given without a value Thomas Bachem via GitGitGadget
2026-11-01 0:52 ` Junio C Hamano
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.