diff options
-rw-r--r-- | Documentation/git-merge.txt | 11 | ||||
-rw-r--r-- | Documentation/merge-config.txt | 10 | ||||
-rw-r--r-- | builtin/merge.c | 42 |
3 files changed, 58 insertions, 5 deletions
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index fb4c05b83..e2e6aba17 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>] [-X <strategy-option>] - [--[no-]rerere-autoupdate] [-m <msg>] <commit>... + [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...] 'git merge' <msg> HEAD <commit>... 'git merge' --abort @@ -95,8 +95,13 @@ commit or stash your changes before running 'git merge'. <commit>...:: Commits, usually other branch heads, to merge into our branch. - You need at least one <commit>. Specifying more than one - <commit> obviously means you are trying an Octopus. + Specifying more than one commit will create a merge with + more than two parents (affectionately called an Octopus merge). ++ +If no commit is given from the command line, and if `merge.defaultToUpstream` +configuration variable is set, merge the remote tracking branches +that the current branch is configured to use as its upstream. +See also the configuration section of this manual page. PRE-MERGE CHECKS diff --git a/Documentation/merge-config.txt b/Documentation/merge-config.txt index 33bf74c33..8920258ba 100644 --- a/Documentation/merge-config.txt +++ b/Documentation/merge-config.txt @@ -6,6 +6,16 @@ merge.conflictstyle:: a `>>>>>>>` marker. An alternate style, "diff3", adds a `|||||||` marker and the original text before the `=======` marker. +merge.defaultToUpstream:: + If merge is called without any commit argument, merge the upstream + branches configured for the current branch by using their last + observed values stored in their remote tracking branches. + The values of the `branch.<current branch>.merge` that name the + branches at the remote named by `branch.<current branch>.remote` + are consulted, and then they are mapped via `remote.<remote>.fetch` + to their corresponding remote tracking branches, and the tips of + these tracking branches are merged. + merge.log:: In addition to branch names, populate the log message with at most the specified number of one-line descriptions from the diff --git a/builtin/merge.c b/builtin/merge.c index 1e0bcfd79..d54e7ddbb 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -25,6 +25,7 @@ #include "help.h" #include "merge-recursive.h" #include "resolve-undo.h" +#include "remote.h" #define DEFAULT_TWOHEAD (1<<0) #define DEFAULT_OCTOPUS (1<<1) @@ -37,8 +38,9 @@ struct strategy { }; static const char * const builtin_merge_usage[] = { - "git merge [options] <remote>...", - "git merge [options] <msg> HEAD <remote>", + "git merge [options] [<commit>...]", + "git merge [options] <msg> HEAD <commit>", + "git merge --abort", NULL }; @@ -59,6 +61,7 @@ static int verbosity; static int allow_rerere_auto; static int abort_current_merge; static int show_progress = -1; +static int default_to_upstream; static struct strategy all_strategy[] = { { "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL }, @@ -538,6 +541,9 @@ static int git_merge_config(const char *k, const char *v, void *cb) if (is_bool && shortlog_len) shortlog_len = DEFAULT_MERGE_LOG_LEN; return 0; + } else if (!strcmp(k, "merge.defaulttoupstream")) { + default_to_upstream = git_config_bool(k, v); + return 0; } return git_diff_ui_config(k, v, cb); } @@ -945,6 +951,35 @@ static int evaluate_result(void) return cnt; } +/* + * Pretend as if the user told us to merge with the tracking + * branch we have for the upstream of the current branch + */ +static int setup_with_upstream(const char ***argv) +{ + struct branch *branch = branch_get(NULL); + int i; + const char **args; + + if (!branch) + die("No current branch."); + if (!branch->remote) + die("No remote for the current branch."); + if (!branch->merge_nr) + die("No default upstream defined for the current branch."); + + args = xcalloc(branch->merge_nr + 1, sizeof(char *)); + for (i = 0; i < branch->merge_nr; i++) { + if (!branch->merge[i]->dst) + die("No remote tracking branch for %s from %s", + branch->merge[i]->src, branch->remote_name); + args[i] = branch->merge[i]->dst; + } + args[i] = NULL; + *argv = args; + return i; +} + int cmd_merge(int argc, const char **argv, const char *prefix) { unsigned char result_tree[20]; @@ -1027,6 +1062,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (!allow_fast_forward && fast_forward_only) die(_("You cannot combine --no-ff with --ff-only.")); + if (!argc && !abort_current_merge && default_to_upstream) + argc = setup_with_upstream(&argv); + if (!argc) usage_with_options(builtin_merge_usage, builtin_merge_options); |