From: "Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Phillip Wood <phillip.wood@dunelm.org.uk>,
Phillip Wood <phillip.wood@dunelm.org.uk>
Subject: [PATCH 4/4] checkout: cleanup --conflict=<style> parsing
Date: Fri, 08 Mar 2024 14:14:30 +0000 [thread overview]
Message-ID: <317bb7a70d023278087f4370b843d7f28f9ee2f6.1709907271.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1684.git.1709907270.gitgitgadget@gmail.com>
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Passing an invalid conflict style name such as "--conflict=bad" gives
the error message
error: unknown style 'bad' given for 'merge.conflictstyle'
which is unfortunate as it talks about a config setting rather than
the option given on the command line. This happens because the
implementation calls git_xmerge_config() to set the conflict style
using the value given on the command line. Use the newly added
parse_conflict_style() instead and pass the value down the call chain
to override the config setting. This also means we can avoid setting
up a struct config_context required for calling git_xmerge_config().
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
builtin/checkout.c | 37 ++++++++++++++++++++-----------------
t/t7201-co.sh | 6 ++++++
2 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 6ded58bd95c..f5055f059ad 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -91,7 +91,8 @@ struct checkout_opts {
int new_branch_log;
enum branch_track track;
struct diff_options diff_options;
- char *conflict_style;
+ char *conflict_style_name;
+ int conflict_style;
int branch_exists;
const char *prefix;
@@ -100,6 +101,8 @@ struct checkout_opts {
struct tree *source_tree;
};
+#define CHECKOUT_OPTS_INIT { .conflict_style = -1 }
+
struct branch_info {
char *name; /* The short name used */
char *path; /* The full name of a real branch */
@@ -251,7 +254,8 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
}
static int checkout_merged(int pos, const struct checkout *state,
- int *nr_checkouts, struct mem_pool *ce_mem_pool)
+ int *nr_checkouts, struct mem_pool *ce_mem_pool,
+ int conflict_style)
{
struct cache_entry *ce = the_index.cache[pos];
const char *path = ce->name;
@@ -286,6 +290,7 @@ static int checkout_merged(int pos, const struct checkout *state,
git_config_get_bool("merge.renormalize", &renormalize);
ll_opts.renormalize = renormalize;
+ ll_opts.conflict_style = conflict_style;
merge_status = ll_merge(&result_buf, path, &ancestor, "base",
&ours, "ours", &theirs, "theirs",
state->istate, &ll_opts);
@@ -416,7 +421,8 @@ static int checkout_worktree(const struct checkout_opts *opts,
else if (opts->merge)
errs |= checkout_merged(pos, &state,
&nr_unmerged,
- &ce_mem_pool);
+ &ce_mem_pool,
+ opts->conflict_style);
pos = skip_same_name(ce, pos) - 1;
}
}
@@ -886,6 +892,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
}
o.branch1 = new_branch_info->name;
o.branch2 = "local";
+ o.conflict_style = opts->conflict_style;
ret = merge_trees(&o,
new_tree,
work,
@@ -1628,7 +1635,7 @@ static struct option *add_common_options(struct checkout_opts *opts,
PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater),
OPT_BOOL(0, "progress", &opts->show_progress, N_("force progress reporting")),
OPT_BOOL('m', "merge", &opts->merge, N_("perform a 3-way merge with the new branch")),
- OPT_STRING(0, "conflict", &opts->conflict_style, N_("style"),
+ OPT_STRING(0, "conflict", &opts->conflict_style_name, N_("style"),
N_("conflict style (merge, diff3, or zdiff3)")),
OPT_END()
};
@@ -1720,14 +1727,13 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
opts->show_progress = isatty(2);
}
- if (opts->conflict_style) {
- struct key_value_info kvi = KVI_INIT;
- struct config_context ctx = {
- .kvi = &kvi,
- };
+ if (opts->conflict_style_name) {
opts->merge = 1; /* implied */
- git_xmerge_config("merge.conflictstyle", opts->conflict_style,
- &ctx, NULL);
+ opts->conflict_style =
+ parse_conflict_style(opts->conflict_style_name);
+ if (opts->conflict_style < 0)
+ die(_("unknown conflict style '%s'"),
+ opts->conflict_style_name);
}
if (opts->force) {
opts->discard_changes = 1;
@@ -1893,7 +1899,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
int cmd_checkout(int argc, const char **argv, const char *prefix)
{
- struct checkout_opts opts;
+ struct checkout_opts opts = CHECKOUT_OPTS_INIT;
struct option *options;
struct option checkout_options[] = {
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
@@ -1909,7 +1915,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
int ret;
struct branch_info new_branch_info = { 0 };
- memset(&opts, 0, sizeof(opts));
opts.dwim_new_local_branch = 1;
opts.switch_branch_doing_nothing_is_ok = 1;
opts.only_merge_on_switching_branches = 0;
@@ -1948,7 +1953,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
int cmd_switch(int argc, const char **argv, const char *prefix)
{
- struct checkout_opts opts;
+ struct checkout_opts opts = CHECKOUT_OPTS_INIT;
struct option *options = NULL;
struct option switch_options[] = {
OPT_STRING('c', "create", &opts.new_branch, N_("branch"),
@@ -1964,7 +1969,6 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
int ret;
struct branch_info new_branch_info = { 0 };
- memset(&opts, 0, sizeof(opts));
opts.dwim_new_local_branch = 1;
opts.accept_ref = 1;
opts.accept_pathspec = 0;
@@ -1990,7 +1994,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
int cmd_restore(int argc, const char **argv, const char *prefix)
{
- struct checkout_opts opts;
+ struct checkout_opts opts = CHECKOUT_OPTS_INIT;
struct option *options;
struct option restore_options[] = {
OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>",
@@ -2007,7 +2011,6 @@ int cmd_restore(int argc, const char **argv, const char *prefix)
int ret;
struct branch_info new_branch_info = { 0 };
- memset(&opts, 0, sizeof(opts));
opts.accept_ref = 0;
opts.accept_pathspec = 1;
opts.empty_pathspec_ok = 0;
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 10cc6c46051..5746d152b6d 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -631,6 +631,12 @@ test_expect_success 'checkout --conflict=diff3' '
test_cmp merged file
'
+test_expect_success 'checkout with invalid conflict style' '
+ test_must_fail git checkout --conflict=bad 2>actual -- file &&
+ echo "fatal: unknown conflict style ${SQ}bad${SQ}" >expect &&
+ test_cmp expect actual
+'
+
test_expect_success 'failing checkout -b should not break working tree' '
git clean -fd && # Remove untracked files in the way
git reset --hard main &&
--
gitgitgadget
next prev parent reply other threads:[~2024-03-08 14:15 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-08 14:14 [PATCH 0/4] checkout: cleanup --conflict= Phillip Wood via GitGitGadget
2024-03-08 14:14 ` [PATCH 1/4] xdiff-interface: refactor parsing of merge.conflictstyle Phillip Wood via GitGitGadget
2024-03-08 14:14 ` [PATCH 2/4] merge-ll: introduce LL_MERGE_OPTIONS_INIT Phillip Wood via GitGitGadget
2024-03-08 14:14 ` [PATCH 3/4] merge options: add a conflict style member Phillip Wood via GitGitGadget
2024-03-08 15:46 ` Junio C Hamano
2024-03-08 16:13 ` phillip.wood123
2024-03-08 16:48 ` Junio C Hamano
2024-03-09 4:33 ` Elijah Newren
2024-03-09 5:46 ` Junio C Hamano
2024-03-08 14:14 ` Phillip Wood via GitGitGadget [this message]
2024-03-08 16:15 ` [PATCH 4/4] checkout: cleanup --conflict=<style> parsing Junio C Hamano
2024-03-08 16:22 ` phillip.wood123
2024-03-08 21:40 ` Junio C Hamano
2024-03-11 14:36 ` phillip.wood123
2024-03-11 17:41 ` Junio C Hamano
2024-03-12 15:50 ` Phillip Wood
2024-03-08 15:44 ` [PATCH 0/4] checkout: cleanup --conflict= Junio C Hamano
2024-03-08 16:07 ` phillip.wood123
2024-03-14 17:05 ` [PATCH v2 0/5] " Phillip Wood via GitGitGadget
2024-03-14 17:05 ` [PATCH v2 1/5] xdiff-interface: refactor parsing of merge.conflictstyle Phillip Wood via GitGitGadget
2024-03-14 17:19 ` Junio C Hamano
2024-03-14 17:05 ` [PATCH v2 2/5] merge-ll: introduce LL_MERGE_OPTIONS_INIT Phillip Wood via GitGitGadget
2024-03-14 17:05 ` [PATCH v2 3/5] merge options: add a conflict style member Phillip Wood via GitGitGadget
2024-03-14 17:21 ` Junio C Hamano
2024-03-14 17:05 ` [PATCH v2 4/5] checkout: cleanup --conflict=<style> parsing Phillip Wood via GitGitGadget
2024-03-14 17:24 ` Junio C Hamano
2024-03-14 17:05 ` [PATCH v2 5/5] checkout: fix interaction between --conflict and --merge Phillip Wood via GitGitGadget
2024-03-14 17:32 ` Junio C Hamano
2024-03-14 17:07 ` [PATCH v2 0/5] checkout: cleanup --conflict= Phillip Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=317bb7a70d023278087f4370b843d7f28f9ee2f6.1709907271.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood@dunelm.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).