Skip to content

Commit 93e535a

Browse files
committed
merge: merge with the default upstream branch without argument
"git merge" without specifying any commit is a no-op by default. A new option merge.defaultupstream can be set to true to cause such an invocation of the command to merge the upstream branches configured for the current branch by using their last observed values stored in their remote tracking branches. Signed-off-by: Junio C Hamano <[email protected]>
1 parent c395c25 commit 93e535a

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

Documentation/git-merge.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SYNOPSIS
1111
[verse]
1212
'git merge' [-n] [--stat] [--no-commit] [--squash]
1313
[-s <strategy>] [-X <strategy-option>]
14-
[--[no-]rerere-autoupdate] [-m <msg>] <commit>...
14+
[--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
1515
'git merge' <msg> HEAD <commit>...
1616
'git merge' --abort
1717

@@ -95,8 +95,13 @@ commit or stash your changes before running 'git merge'.
9595

9696
<commit>...::
9797
Commits, usually other branch heads, to merge into our branch.
98-
You need at least one <commit>. Specifying more than one
99-
<commit> obviously means you are trying an Octopus.
98+
Specifying more than one commit will create a merge with
99+
more than two parents (affectionately called an Octopus merge).
100+
+
101+
If no commit is given from the command line, and if `merge.defaultToUpstream`
102+
configuration variable is set, merge the remote tracking branches
103+
that the current branch is configured to use as its upstream.
104+
See also the configuration section of this manual page.
100105

101106

102107
PRE-MERGE CHECKS

Documentation/merge-config.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ merge.conflictstyle::
66
a `>>>>>>>` marker. An alternate style, "diff3", adds a `|||||||`
77
marker and the original text before the `=======` marker.
88

9+
merge.defaultToUpstream::
10+
If merge is called without any commit argument, merge the upstream
11+
branches configured for the current branch by using their last
12+
observed values stored in their remote tracking branches.
13+
The values of the `branch.<current branch>.merge` that name the
14+
branches at the remote named by `branch.<current branch>.remote`
15+
are consulted, and then they are mapped via `remote.<remote>.fetch`
16+
to their corresponding remote tracking branches, and the tips of
17+
these tracking branches are merged.
18+
919
merge.log::
1020
In addition to branch names, populate the log message with at
1121
most the specified number of one-line descriptions from the

builtin/merge.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "help.h"
2626
#include "merge-recursive.h"
2727
#include "resolve-undo.h"
28+
#include "remote.h"
2829

2930
#define DEFAULT_TWOHEAD (1<<0)
3031
#define DEFAULT_OCTOPUS (1<<1)
@@ -37,7 +38,7 @@ struct strategy {
3738
};
3839

3940
static const char * const builtin_merge_usage[] = {
40-
"git merge [options] <commit>...",
41+
"git merge [options] [<commit>...]",
4142
"git merge [options] <msg> HEAD <commit>",
4243
"git merge --abort",
4344
NULL
@@ -59,6 +60,7 @@ static int option_renormalize;
5960
static int verbosity;
6061
static int allow_rerere_auto;
6162
static int abort_current_merge;
63+
static int default_to_upstream;
6264

6365
static struct strategy all_strategy[] = {
6466
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -537,6 +539,9 @@ static int git_merge_config(const char *k, const char *v, void *cb)
537539
if (is_bool && shortlog_len)
538540
shortlog_len = DEFAULT_MERGE_LOG_LEN;
539541
return 0;
542+
} else if (!strcmp(k, "merge.defaulttoupstream")) {
543+
default_to_upstream = git_config_bool(k, v);
544+
return 0;
540545
}
541546
return git_diff_ui_config(k, v, cb);
542547
}
@@ -912,6 +917,35 @@ static int evaluate_result(void)
912917
return cnt;
913918
}
914919

920+
/*
921+
* Pretend as if the user told us to merge with the tracking
922+
* branch we have for the upstream of the current branch
923+
*/
924+
static int setup_with_upstream(const char ***argv)
925+
{
926+
struct branch *branch = branch_get(NULL);
927+
int i;
928+
const char **args;
929+
930+
if (!branch)
931+
die("No current branch.");
932+
if (!branch->remote)
933+
die("No remote for the current branch.");
934+
if (!branch->merge_nr)
935+
die("No default upstream defined for the current branch.");
936+
937+
args = xcalloc(branch->merge_nr + 1, sizeof(char *));
938+
for (i = 0; i < branch->merge_nr; i++) {
939+
if (!branch->merge[i]->dst)
940+
die("No remote tracking branch for %s from %s",
941+
branch->merge[i]->src, branch->remote_name);
942+
args[i] = branch->merge[i]->dst;
943+
}
944+
args[i] = NULL;
945+
*argv = args;
946+
return i;
947+
}
948+
915949
int cmd_merge(int argc, const char **argv, const char *prefix)
916950
{
917951
unsigned char result_tree[20];
@@ -984,6 +1018,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
9841018
if (!allow_fast_forward && fast_forward_only)
9851019
die("You cannot combine --no-ff with --ff-only.");
9861020

1021+
if (!argc && !abort_current_merge && default_to_upstream)
1022+
argc = setup_with_upstream(&argv);
1023+
9871024
if (!argc)
9881025
usage_with_options(builtin_merge_usage,
9891026
builtin_merge_options);

0 commit comments

Comments
 (0)