merge: introduce {copy|clear}_merge_options()

When mostly the same set of options are to be used to perform multiple merges, one instance of the merge_options structure may want to be created and used by copying from the same template instance. We saw such a use recently in "git merge-tree". Let's make the pattern official by introducing copy_merge_options() as a supported way to make a copy of the structure, and also give clear_merge_options() to release any resources held by a copied instance. Currently we only make a shallow copy, so the former is a mere structure assignment while the latter is a no-op, but this may change in the future as the members of merge_options structure evolve. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Oct 11, 2023 at 13:37 UTC b182658e3ed412e21a472db42ebc37130cee68e0
3 files changed +22 -1
builtin/merge-tree.c
+3 -1
@@ -425,10 +425,11 @@ static int real_merge(struct merge_tree_options *o,
425 {
426 struct commit *parent1, *parent2;
427 struct commit_list *merge_bases = NULL;
428 - struct merge_options opt = o->merge_options;
428 struct merge_result result = { 0 };
429 int show_messages = o->show_messages;
430 + struct merge_options opt;
431
432 + copy_merge_options(&opt, &o->merge_options);
433 parent1 = get_merge_parent(branch1);
434 if (!parent1)
435 help_unknown_ref(branch1, "merge-tree",
@@ -507,6 +508,7 @@ static int real_merge(struct merge_tree_options *o,
508 if (o->use_stdin)
509 putchar(line_termination);
510 merge_finalize(&opt, &result);
511 + clear_merge_options(&opt);
512 return !result.clean; /* result.clean < 0 handled above */
513 }
514
merge-recursive.c
+16
@@ -3912,6 +3912,22 @@ void init_merge_options(struct merge_options *opt,
3912 opt->buffer_output = 0;
3913 }
3914
3915 +/*
3916 + * For now, members of merge_options do not need deep copying, but
3917 + * it may change in the future, in which case we would need to update
3918 + * this, and also make a matching change to clear_merge_options() to
3919 + * release the resources held by a copied instance.
3920 + */
3921 +void copy_merge_options(struct merge_options *dst, struct merge_options *src)
3922 +{
3923 + *dst = *src;
3924 +}
3925 +
3926 +void clear_merge_options(struct merge_options *opt UNUSED)
3927 +{
3928 + ; /* no-op as our copy is shallow right now */
3929 +}
3930 +
3931 int parse_merge_opt(struct merge_options *opt, const char *s)
3932 {
3933 const char *arg;
merge-recursive.h
+3
@@ -55,6 +55,9 @@ struct merge_options {
55
56 void init_merge_options(struct merge_options *opt, struct repository *repo);
57
58 +void copy_merge_options(struct merge_options *dst, struct merge_options *src);
59 +void clear_merge_options(struct merge_options *opt);
60 +
61 /* parse the option in s and update the relevant field of opt */
62 int parse_merge_opt(struct merge_options *opt, const char *s);
63