From: Michael Grubb <devel@dailyvoid.com>
To: Jonathan Nieder <jrnieder@gmail.com>
Cc: Junio C Hamano <gitster@pobox.com>,
git@vger.kernel.org, vmiklos@frugalware.org
Subject: Re: [PATCH v4] Add default merge options for all branches
Date: Wed, 04 May 2011 13:58:04 -0500 [thread overview]
Message-ID: <4DC1A1BC.5010601@dailyvoid.com> (raw)
In-Reply-To: <20110504045802.GF8187@elie>
Well, it certainly serves *my* immediate needs and addresses the specific use case that I was originally working on. Though I think that what we've come up with would benefit the codebase in general if for no other reason than it lays some ground work for future features and is a bit more generic. I also wouldn't mind going a step further and working on the globbing feature in a separate series.
Here are some corrections to the previous patch:
This patch makes the branch specific options more flexible by laying
the ground work for supporting globs for the branch names.
At this time only the value '*' is supported which will set default
values for all branches. In the future this may be expanded to support
true globbing.
Signed-off-by: Michael Grubb <devel@dailyvoid.com>
---
builtin/merge.c | 120 ++++++++++++++++++++++++++++++++++-------------------
t/t7600-merge.sh | 27 ++++++++----
2 files changed, 95 insertions(+), 52 deletions(-)
diff --git a/builtin/merge.c b/builtin/merge.c
index fa56205..9e6ec5f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -31,20 +31,12 @@
#define DEFAULT_OCTOPUS (1<<1)
#define NO_FAST_FORWARD (1<<2)
#define NO_TRIVIAL (1<<3)
+#define MERGE_OPTIONS_INIT {NULL, NULL, NULL}
-/* This is for branch.<foo>. blocks
- * the vote member holds a value between
- * 0.0 and 1.0 which measures how closely
- * a branch name matches the key member.
- * where branch.*.mergeoptions would be 0.1 and
- * branch.<name>.mergeoptions would be 1.0
- * Also it is called vote because I couldn't come
- * up with a better name.
- */
struct merge_options_cb {
- char *key;
- char *value;
- float vote;
+ char *option;
+ char *spec;
+ char *name;
};
struct strategy {
@@ -518,30 +510,11 @@ cleanup:
strbuf_release(&bname);
}
-static void parse_git_merge_options(const char *k, const char *v,
- void *cb)
+static void free_merge_options_cb(struct merge_options_cb *data)
{
- struct merge_options_cb *merge_options = cb;
- int changed = 0;
-
- /* We only handle mergeoptions for now */
- if (suffixcmp(k, ".mergeoptions"))
- return;
-
- if (!prefixcmp(k, "branch.*") && merge_options->vote <= 0.1 ) {
- merge_options->vote = 0.1;
- changed = 1;
- } else if (branch && !prefixcmp(k, "branch.") &&
- !prefixcmp(k + 7, branch) &&
- merge_options->vote < 1.0) {
- merge_options->vote = 1.0;
- changed = 1;
- }
-
- if (changed) {
- merge_options->key = (char *)k;
- merge_options->value = (char *)v;
- }
+ free(data->option);
+ free(data->spec);
+ free(data->name);
}
static void apply_merge_options(struct merge_options_cb *opts)
@@ -550,26 +523,85 @@ static void apply_merge_options(struct merge_options_cb *opts)
int argc;
char *buf;
- if ( opts == NULL )
+ if (!opts)
return;
- buf = xstrdup(opts->value);
+ buf = xstrdup(opts->option);
argc = split_cmdline(buf, &argv);
if (argc < 0)
- die(_("Bad %s string: %s"),
- opts->key, split_cmdline_strerror(argc));
+ die(_("Bad branch.%s.%s string: %s"),
+ opts->spec, opts->name, split_cmdline_strerror(argc));
argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
argc++;
parse_options(argc, argv, NULL, builtin_merge_options,
- builtin_merge_usage, 0);
+ builtin_merge_usage, 0);
free(buf);
}
+/*
+ * This function returns -1 if the first argument is less specific
+ * than the second, and 1 vice versa. Returns -1 if both arguments
+ * are the same.
+ */
+static int cmp_specificity(const char *a, const char *b)
+{
+ switch((!strcmp(a, "*") ? 2 : 0) |
+ (!strcmp(b, "*") ? 1 : 0)) {
+ case 3:
+ case 0:
+ return -1; /* later one wins if they are the same */
+ case 1:
+ return 1;
+ case 2:
+ return -1;
+ }
+ return 0; /* should never happen */
+}
+
+static void parse_git_merge_options(const char *k, const char *v,
+ void *cb)
+{
+ struct merge_options_cb *merge_options = cb;
+ char *spec, *eon; /* end-of-name */
+
+ k += 7; /* not interested in the leading "branch." */
+ eon = strrchr(k, '.');
+ if (!eon || strcmp(eon, ".mergeoptions"))
+ return;
+
+ /* k through eon is name or glob */
+ spec = xmemdupz(k, eon - k);
+ /*
+ * NEEDSWORK: for now we say "*" matches; we would need
+ * to turn the following into something like:
+ * if (has_wildcard(spec)
+ * ? !glob_matches(spec, branch)
+ * : strcmp(spec, branch)) {
+ * free(spec);
+ * return;
+ * }
+ */
+ if (strcmp(spec, "*") && strcmp(spec, branch)) {
+ free(spec);
+ return;
+ }
+
+ if (!merge_options->option ||
+ cmp_specificity(merge_options->spec, spec) < 0) {
+ free_merge_options_cb(merge_options);
+ merge_options->option = xstrdup(v);
+ merge_options->name = xstrdup(eon + 1);
+ merge_options->spec = spec;
+ return;
+ }
+ free(spec);
+}
+
static int git_merge_config(const char *k, const char *v, void *cb)
{
- if (cb != NULL && branch && !prefixcmp(k, "branch."))
+ if (branch && !prefixcmp(k, "branch."))
parse_git_merge_options(k, v, cb);
if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat"))
@@ -1034,7 +1066,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
const char *head_arg;
int flag, head_invalid = 0, i;
int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0;
- struct merge_options_cb merge_options = {NULL, NULL, 0.0};
+ struct merge_options_cb merge_options = MERGE_OPTIONS_INIT;
struct commit_list *common = NULL;
const char *best_strategy = NULL, *wt_strategy = NULL;
struct commit_list **remotes = &remoteheads;
@@ -1053,8 +1085,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
head_invalid = 1;
git_config(git_merge_config, &merge_options);
- if (merge_options.key != NULL && merge_options.value != NULL)
+ if (merge_options.option) {
apply_merge_options(&merge_options);
+ free_merge_options_cb(&merge_options);
+ }
/* for color.ui */
if (diff_use_color_default == -1)
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 5b1f8e1..d7a60b2 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -417,37 +417,46 @@ test_debug 'git log --graph --decorate --oneline --all'
test_expect_success 'merge c0 with c1 (default no-ff)' '
git reset --hard c0 &&
- test_might_fail git config --unset branch.master.mergeoptions &&
- git config "branch.*.mergeoptions" "--no-ff" &&
+ cat >.git/config <<-\EOF &&
+ [branch "*"]
+ mergeoptions = --no-ff
+ EOF
test_tick &&
git merge c1 &&
git config --remove-section "branch.*" &&
verify_merge file result.1 &&
verify_parents $c0 $c1
'
-
test_debug 'git log --graph --decorate --oneline --all'
test_expect_success 'combine branch.*.mergeoptions with branch.x.mergeoptions' '
git reset --hard c0 &&
- test_might_fail git config --remove-section branch.master &&
- git config "branch.*.mergeoptions" "--no-ff" &&
- git config branch.master.mergeoptions "--ff" &&
+ cat >.git/config <<-\EOF &&
+ [branch "*"]
+ mergeoptions = --no-ff
+ [branch "master"]
+ mergeoptions = --ff
+ EOF
test_tick &&
git merge c1 &&
git config --remove-section "branch.*" &&
+ git config --remove-section "branch.master" &&
verify_merge file result.1 &&
verify_parents "$c0"
'
test_expect_success 'reverse branch.x.mergeoptions with branch.*.mergeoptions' '
git reset --hard c0 &&
- test_might_fail git config --remove-section branch.master &&
- git config branch.master.mergeoptions "--ff" &&
- git config "branch.*.mergeoptions" "--no-ff" &&
+ cat >.git/config <<-\EOF &&
+ [branch "master"]
+ mergeoptions = --ff
+ [branch "*"]
+ mergeoptions = --no-ff
+ EOF
test_tick &&
git merge c1 &&
git config --remove-section "branch.*" &&
+ git config --remove-section "branch.master" &&
verify_merge file result.1 &&
verify_parents "$c0"
'
--
1.7.5
On 5/3/11 11:58 PM, Jonathan Nieder wrote:
> Michael Grubb wrote:
>
>> I take this to mean that my patch is no longer needed/wanted?
>
> No, as usual it means that Junio was thinking and sent us his
> thoughts.
>
> Do you like it? If so, the way to move it forward would be to add
> tests and write a commit log message. If not, the way to move things
> forward would be to explain what use case it misses and work on a
> better patch that takes care of them.
>
> Hope that helps,
> Jonathan
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2011-05-04 18:58 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-02 19:23 [PATCH 2] Add default merge options for all branches Michael Grubb
2011-05-02 22:47 ` Miklos Vajna
2011-05-02 23:36 ` Junio C Hamano
2011-05-03 5:35 ` Michael Grubb
2011-05-03 5:38 ` [PATCH v3] " Michael Grubb
2011-05-03 9:03 ` Jonathan Nieder
2011-05-03 9:49 ` Jonathan Nieder
2011-05-03 16:46 ` Michael Grubb
2011-05-03 18:16 ` Junio C Hamano
2011-05-03 20:22 ` Michael Grubb
2011-05-03 20:50 ` Jonathan Nieder
2011-05-03 20:37 ` Jens Lehmann
2011-05-03 20:07 ` [PATCH v4] " Michael Grubb
2011-05-03 20:36 ` Michael Grubb
2011-05-03 20:44 ` Jonathan Nieder
2011-05-03 22:51 ` Junio C Hamano
2011-05-04 4:25 ` Junio C Hamano
2011-05-04 4:28 ` Michael Grubb
2011-05-04 4:58 ` Jonathan Nieder
2011-05-04 18:58 ` Michael Grubb [this message]
2011-05-04 21:35 ` Junio C Hamano
2011-05-04 10:58 ` John Szakmeister
2011-05-03 22:03 ` Junio C Hamano
2011-05-03 20:37 ` [PATCH v4.1] " Michael Grubb
2011-05-04 22:07 ` [PATCH v5] " Michael Grubb
2011-05-05 0:42 ` Junio C Hamano
2011-05-06 20:36 ` Junio C Hamano
2011-05-06 21:59 ` Jonathan Nieder
2011-05-06 20:54 ` [PATCH 0/2] tests: make verify_merge check that the number of parents is right Jonathan Nieder
2011-05-06 20:58 ` [PATCH 1/2] tests: eliminate unnecessary setup test assertions Jonathan Nieder
2011-05-06 21:48 ` Jeff King
2011-05-06 22:13 ` Jeff King
2011-05-06 22:27 ` Junio C Hamano
2011-05-06 22:29 ` Jeff King
2011-05-07 22:05 ` Junio C Hamano
2011-05-09 13:31 ` [PATCH 0/3] blame --line-porcelain Jeff King
2011-05-09 13:33 ` [PATCH 1/3] add tests for various blame formats Jeff King
2011-05-09 13:34 ` [PATCH 2/3] blame: refactor porcelain output Jeff King
2011-05-09 15:39 ` Thiago Farina
2011-05-09 13:34 ` [PATCH 3/3] blame: add --line-porcelain output format Jeff King
2011-05-06 22:26 ` [PATCH 1/2] tests: eliminate unnecessary setup test assertions Jonathan Nieder
2011-05-06 21:00 ` [PATCH 2/2] tests: teach verify_parents to check for extra parents Jonathan Nieder
2011-05-06 21:34 ` Junio C Hamano
2011-05-06 21:42 ` Jonathan Nieder
2011-05-06 21:32 ` [PATCH v5] Add default merge options for all branches Jonathan Nieder
2011-05-06 22:01 ` Junio C Hamano
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DC1A1BC.5010601@dailyvoid.com \
--to=devel@dailyvoid.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jrnieder@gmail.com \
--cc=vmiklos@frugalware.org \
/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.
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 NNTP newsgroup(s).