2015-06-14 10:41:51 +02:00
|
|
|
/*
|
|
|
|
* Builtin "git pull"
|
|
|
|
*
|
|
|
|
* Based on git-pull.sh by Junio C Hamano
|
|
|
|
*
|
|
|
|
* Fetch one or more remote refs and merge it/them into the current HEAD.
|
|
|
|
*/
|
|
|
|
#include "cache.h"
|
|
|
|
#include "builtin.h"
|
|
|
|
#include "parse-options.h"
|
|
|
|
#include "exec_cmd.h"
|
2015-06-14 10:41:52 +02:00
|
|
|
#include "run-command.h"
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
#include "sha1-array.h"
|
|
|
|
#include "remote.h"
|
2015-06-14 10:41:51 +02:00
|
|
|
|
|
|
|
static const char * const pull_usage[] = {
|
2015-06-14 10:41:52 +02:00
|
|
|
N_("git pull [options] [<repository> [<refspec>...]]"),
|
2015-06-14 10:41:51 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2015-06-14 10:41:53 +02:00
|
|
|
/* Shared options */
|
|
|
|
static int opt_verbosity;
|
|
|
|
static char *opt_progress;
|
|
|
|
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
/* Options passed to git-merge */
|
|
|
|
static char *opt_diffstat;
|
|
|
|
static char *opt_log;
|
|
|
|
static char *opt_squash;
|
|
|
|
static char *opt_commit;
|
|
|
|
static char *opt_edit;
|
|
|
|
static char *opt_ff;
|
|
|
|
static char *opt_verify_signatures;
|
|
|
|
static struct argv_array opt_strategies = ARGV_ARRAY_INIT;
|
|
|
|
static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT;
|
|
|
|
static char *opt_gpg_sign;
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
static char *opt_all;
|
|
|
|
static char *opt_append;
|
|
|
|
static char *opt_upload_pack;
|
|
|
|
static int opt_force;
|
|
|
|
static char *opt_tags;
|
|
|
|
static char *opt_prune;
|
|
|
|
static char *opt_recurse_submodules;
|
|
|
|
static int opt_dry_run;
|
|
|
|
static char *opt_keep;
|
|
|
|
static char *opt_depth;
|
|
|
|
static char *opt_unshallow;
|
|
|
|
static char *opt_update_shallow;
|
|
|
|
static char *opt_refmap;
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
static struct option pull_options[] = {
|
2015-06-14 10:41:53 +02:00
|
|
|
/* Shared options */
|
|
|
|
OPT__VERBOSITY(&opt_verbosity),
|
|
|
|
OPT_PASSTHRU(0, "progress", &opt_progress, NULL,
|
|
|
|
N_("force progress reporting"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
/* Options passed to git-merge */
|
|
|
|
OPT_GROUP(N_("Options related to merging")),
|
|
|
|
OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
|
|
|
|
N_("do not show a diffstat at the end of the merge"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_NONEG),
|
|
|
|
OPT_PASSTHRU(0, "stat", &opt_diffstat, NULL,
|
|
|
|
N_("show a diffstat at the end of the merge"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "summary", &opt_diffstat, NULL,
|
|
|
|
N_("(synonym to --stat)"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),
|
|
|
|
OPT_PASSTHRU(0, "log", &opt_log, N_("n"),
|
|
|
|
N_("add (at most <n>) entries from shortlog to merge commit message"),
|
|
|
|
PARSE_OPT_OPTARG),
|
|
|
|
OPT_PASSTHRU(0, "squash", &opt_squash, NULL,
|
|
|
|
N_("create a single commit instead of doing a merge"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "commit", &opt_commit, NULL,
|
|
|
|
N_("perform a commit if the merge succeeds (default)"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "edit", &opt_edit, NULL,
|
|
|
|
N_("edit message before committing"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "ff", &opt_ff, NULL,
|
|
|
|
N_("allow fast-forward"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "ff-only", &opt_ff, NULL,
|
|
|
|
N_("abort if fast-forward is not possible"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_NONEG),
|
|
|
|
OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL,
|
|
|
|
N_("verify that the named commit has a valid GPG signature"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU_ARGV('s', "strategy", &opt_strategies, N_("strategy"),
|
|
|
|
N_("merge strategy to use"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU_ARGV('X', "strategy-option", &opt_strategy_opts,
|
|
|
|
N_("option=value"),
|
|
|
|
N_("option for selected merge strategy"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU('S', "gpg-sign", &opt_gpg_sign, N_("key-id"),
|
|
|
|
N_("GPG sign commit"),
|
|
|
|
PARSE_OPT_OPTARG),
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
OPT_GROUP(N_("Options related to fetching")),
|
|
|
|
OPT_PASSTHRU(0, "all", &opt_all, NULL,
|
|
|
|
N_("fetch from all remotes"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU('a', "append", &opt_append, NULL,
|
|
|
|
N_("append to .git/FETCH_HEAD instead of overwriting"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "upload-pack", &opt_upload_pack, N_("path"),
|
|
|
|
N_("path to upload pack on remote end"),
|
|
|
|
0),
|
|
|
|
OPT__FORCE(&opt_force, N_("force overwrite of local branch")),
|
|
|
|
OPT_PASSTHRU('t', "tags", &opt_tags, NULL,
|
|
|
|
N_("fetch all tags and associated objects"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU('p', "prune", &opt_prune, NULL,
|
|
|
|
N_("prune remote-tracking branches no longer on remote"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "recurse-submodules", &opt_recurse_submodules,
|
|
|
|
N_("on-demand"),
|
|
|
|
N_("control recursive fetching of submodules"),
|
|
|
|
PARSE_OPT_OPTARG),
|
|
|
|
OPT_BOOL(0, "dry-run", &opt_dry_run,
|
|
|
|
N_("dry run")),
|
|
|
|
OPT_PASSTHRU('k', "keep", &opt_keep, NULL,
|
|
|
|
N_("keep downloaded pack"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "depth", &opt_depth, N_("depth"),
|
|
|
|
N_("deepen history of shallow clone"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU(0, "unshallow", &opt_unshallow, NULL,
|
|
|
|
N_("convert to a complete repository"),
|
|
|
|
PARSE_OPT_NONEG | PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "update-shallow", &opt_update_shallow, NULL,
|
|
|
|
N_("accept refs that update .git/shallow"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "refmap", &opt_refmap, N_("refmap"),
|
|
|
|
N_("specify fetch refmap"),
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
OPT_END()
|
|
|
|
};
|
|
|
|
|
2015-06-14 10:41:53 +02:00
|
|
|
/**
|
|
|
|
* Pushes "-q" or "-v" switches into arr to match the opt_verbosity level.
|
|
|
|
*/
|
|
|
|
static void argv_push_verbosity(struct argv_array *arr)
|
|
|
|
{
|
|
|
|
int verbosity;
|
|
|
|
|
|
|
|
for (verbosity = opt_verbosity; verbosity > 0; verbosity--)
|
|
|
|
argv_array_push(arr, "-v");
|
|
|
|
|
|
|
|
for (verbosity = opt_verbosity; verbosity < 0; verbosity++)
|
|
|
|
argv_array_push(arr, "-q");
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/**
|
|
|
|
* Pushes "-f" switches into arr to match the opt_force level.
|
|
|
|
*/
|
|
|
|
static void argv_push_force(struct argv_array *arr)
|
|
|
|
{
|
|
|
|
int force = opt_force;
|
|
|
|
while (force-- > 0)
|
|
|
|
argv_array_push(arr, "-f");
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:03 +02:00
|
|
|
/**
|
|
|
|
* If pull.ff is unset, returns NULL. If pull.ff is "true", returns "--ff". If
|
|
|
|
* pull.ff is "false", returns "--no-ff". If pull.ff is "only", returns
|
|
|
|
* "--ff-only". Otherwise, if pull.ff is set to an invalid value, die with an
|
|
|
|
* error.
|
|
|
|
*/
|
|
|
|
static const char *config_get_ff(void)
|
|
|
|
{
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
if (git_config_get_value("pull.ff", &value))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
switch (git_config_maybe_bool("pull.ff", value)) {
|
|
|
|
case 0:
|
|
|
|
return "--no-ff";
|
|
|
|
case 1:
|
|
|
|
return "--ff";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(value, "only"))
|
|
|
|
return "--ff-only";
|
|
|
|
|
|
|
|
die(_("Invalid value for pull.ff: %s"), value);
|
|
|
|
}
|
|
|
|
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
/**
|
|
|
|
* Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
|
|
|
|
* into merge_heads.
|
|
|
|
*/
|
|
|
|
static void get_merge_heads(struct sha1_array *merge_heads)
|
|
|
|
{
|
|
|
|
const char *filename = git_path("FETCH_HEAD");
|
|
|
|
FILE *fp;
|
|
|
|
struct strbuf sb = STRBUF_INIT;
|
|
|
|
unsigned char sha1[GIT_SHA1_RAWSZ];
|
|
|
|
|
|
|
|
if (!(fp = fopen(filename, "r")))
|
|
|
|
die_errno(_("could not open '%s' for reading"), filename);
|
|
|
|
while (strbuf_getline(&sb, fp, '\n') != EOF) {
|
|
|
|
if (get_sha1_hex(sb.buf, sha1))
|
|
|
|
continue; /* invalid line: does not start with SHA1 */
|
|
|
|
if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
|
|
|
|
continue; /* ref is not-for-merge */
|
|
|
|
sha1_array_append(merge_heads, sha1);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
strbuf_release(&sb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used by die_no_merge_candidates() as a for_each_remote() callback to
|
|
|
|
* retrieve the name of the remote if the repository only has one remote.
|
|
|
|
*/
|
|
|
|
static int get_only_remote(struct remote *remote, void *cb_data)
|
|
|
|
{
|
|
|
|
const char **remote_name = cb_data;
|
|
|
|
|
|
|
|
if (*remote_name)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*remote_name = remote->name;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dies with the appropriate reason for why there are no merge candidates:
|
|
|
|
*
|
|
|
|
* 1. We fetched from a specific remote, and a refspec was given, but it ended
|
|
|
|
* up not fetching anything. This is usually because the user provided a
|
|
|
|
* wildcard refspec which had no matches on the remote end.
|
|
|
|
*
|
|
|
|
* 2. We fetched from a non-default remote, but didn't specify a branch to
|
|
|
|
* merge. We can't use the configured one because it applies to the default
|
|
|
|
* remote, thus the user must specify the branches to merge.
|
|
|
|
*
|
|
|
|
* 3. We fetched from the branch's or repo's default remote, but:
|
|
|
|
*
|
|
|
|
* a. We are not on a branch, so there will never be a configured branch to
|
|
|
|
* merge with.
|
|
|
|
*
|
|
|
|
* b. We are on a branch, but there is no configured branch to merge with.
|
|
|
|
*
|
|
|
|
* 4. We fetched from the branch's or repo's default remote, but the configured
|
|
|
|
* branch to merge didn't get fetched. (Either it doesn't exist, or wasn't
|
|
|
|
* part of the configured fetch refspec.)
|
|
|
|
*/
|
|
|
|
static void NORETURN die_no_merge_candidates(const char *repo, const char **refspecs)
|
|
|
|
{
|
|
|
|
struct branch *curr_branch = branch_get("HEAD");
|
|
|
|
const char *remote = curr_branch ? curr_branch->remote_name : NULL;
|
|
|
|
|
|
|
|
if (*refspecs) {
|
|
|
|
fprintf_ln(stderr, _("There are no candidates for merging among the refs that you just fetched."));
|
|
|
|
fprintf_ln(stderr, _("Generally this means that you provided a wildcard refspec which had no\n"
|
|
|
|
"matches on the remote end."));
|
|
|
|
} else if (repo && curr_branch && (!remote || strcmp(repo, remote))) {
|
|
|
|
fprintf_ln(stderr, _("You asked to pull from the remote '%s', but did not specify\n"
|
|
|
|
"a branch. Because this is not the default configured remote\n"
|
|
|
|
"for your current branch, you must specify a branch on the command line."),
|
|
|
|
repo);
|
|
|
|
} else if (!curr_branch) {
|
|
|
|
fprintf_ln(stderr, _("You are not currently on a branch."));
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
|
|
|
|
fprintf_ln(stderr, _("See git-pull(1) for details."));
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf_ln(stderr, " git pull <remote> <branch>");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
} else if (!curr_branch->merge_nr) {
|
|
|
|
const char *remote_name = NULL;
|
|
|
|
|
|
|
|
if (for_each_remote(get_only_remote, &remote_name) || !remote_name)
|
|
|
|
remote_name = "<remote>";
|
|
|
|
|
|
|
|
fprintf_ln(stderr, _("There is no tracking information for the current branch."));
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
|
|
|
|
fprintf_ln(stderr, _("See git-pull(1) for details."));
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf_ln(stderr, " git pull <remote> <branch>");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:\n"
|
|
|
|
"\n"
|
|
|
|
" git branch --set-upstream-to=%s/<branch> %s\n"),
|
|
|
|
remote_name, curr_branch->name);
|
|
|
|
} else
|
|
|
|
fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n"
|
|
|
|
"from the remote, but no such ref was fetched."),
|
|
|
|
*curr_branch->merge_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
/**
|
|
|
|
* Parses argv into [<repo> [<refspecs>...]], returning their values in `repo`
|
|
|
|
* as a string and `refspecs` as a null-terminated array of strings. If `repo`
|
|
|
|
* is not provided in argv, it is set to NULL.
|
|
|
|
*/
|
|
|
|
static void parse_repo_refspecs(int argc, const char **argv, const char **repo,
|
|
|
|
const char ***refspecs)
|
|
|
|
{
|
|
|
|
if (argc > 0) {
|
|
|
|
*repo = *argv++;
|
|
|
|
argc--;
|
|
|
|
} else
|
|
|
|
*repo = NULL;
|
|
|
|
*refspecs = argv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs git-fetch, returning its exit status. `repo` and `refspecs` are the
|
|
|
|
* repository and refspecs to fetch, or NULL if they are not provided.
|
|
|
|
*/
|
|
|
|
static int run_fetch(const char *repo, const char **refspecs)
|
|
|
|
{
|
|
|
|
struct argv_array args = ARGV_ARRAY_INIT;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
argv_array_pushl(&args, "fetch", "--update-head-ok", NULL);
|
2015-06-14 10:41:53 +02:00
|
|
|
|
|
|
|
/* Shared options */
|
|
|
|
argv_push_verbosity(&args);
|
|
|
|
if (opt_progress)
|
|
|
|
argv_array_push(&args, opt_progress);
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
if (opt_all)
|
|
|
|
argv_array_push(&args, opt_all);
|
|
|
|
if (opt_append)
|
|
|
|
argv_array_push(&args, opt_append);
|
|
|
|
if (opt_upload_pack)
|
|
|
|
argv_array_push(&args, opt_upload_pack);
|
|
|
|
argv_push_force(&args);
|
|
|
|
if (opt_tags)
|
|
|
|
argv_array_push(&args, opt_tags);
|
|
|
|
if (opt_prune)
|
|
|
|
argv_array_push(&args, opt_prune);
|
|
|
|
if (opt_recurse_submodules)
|
|
|
|
argv_array_push(&args, opt_recurse_submodules);
|
|
|
|
if (opt_dry_run)
|
|
|
|
argv_array_push(&args, "--dry-run");
|
|
|
|
if (opt_keep)
|
|
|
|
argv_array_push(&args, opt_keep);
|
|
|
|
if (opt_depth)
|
|
|
|
argv_array_push(&args, opt_depth);
|
|
|
|
if (opt_unshallow)
|
|
|
|
argv_array_push(&args, opt_unshallow);
|
|
|
|
if (opt_update_shallow)
|
|
|
|
argv_array_push(&args, opt_update_shallow);
|
|
|
|
if (opt_refmap)
|
|
|
|
argv_array_push(&args, opt_refmap);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
if (repo) {
|
|
|
|
argv_array_push(&args, repo);
|
|
|
|
argv_array_pushv(&args, refspecs);
|
|
|
|
} else if (*refspecs)
|
|
|
|
die("BUG: refspecs without repo?");
|
|
|
|
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
|
|
|
argv_array_clear(&args);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs git-merge, returning its exit status.
|
|
|
|
*/
|
|
|
|
static int run_merge(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct argv_array args = ARGV_ARRAY_INIT;
|
|
|
|
|
|
|
|
argv_array_pushl(&args, "merge", NULL);
|
2015-06-14 10:41:53 +02:00
|
|
|
|
|
|
|
/* Shared options */
|
|
|
|
argv_push_verbosity(&args);
|
|
|
|
if (opt_progress)
|
|
|
|
argv_array_push(&args, opt_progress);
|
|
|
|
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
/* Options passed to git-merge */
|
|
|
|
if (opt_diffstat)
|
|
|
|
argv_array_push(&args, opt_diffstat);
|
|
|
|
if (opt_log)
|
|
|
|
argv_array_push(&args, opt_log);
|
|
|
|
if (opt_squash)
|
|
|
|
argv_array_push(&args, opt_squash);
|
|
|
|
if (opt_commit)
|
|
|
|
argv_array_push(&args, opt_commit);
|
|
|
|
if (opt_edit)
|
|
|
|
argv_array_push(&args, opt_edit);
|
|
|
|
if (opt_ff)
|
|
|
|
argv_array_push(&args, opt_ff);
|
|
|
|
if (opt_verify_signatures)
|
|
|
|
argv_array_push(&args, opt_verify_signatures);
|
|
|
|
argv_array_pushv(&args, opt_strategies.argv);
|
|
|
|
argv_array_pushv(&args, opt_strategy_opts.argv);
|
|
|
|
if (opt_gpg_sign)
|
|
|
|
argv_array_push(&args, opt_gpg_sign);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
argv_array_push(&args, "FETCH_HEAD");
|
|
|
|
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
|
|
|
argv_array_clear(&args);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
int cmd_pull(int argc, const char **argv, const char *prefix)
|
|
|
|
{
|
2015-06-14 10:41:52 +02:00
|
|
|
const char *repo, **refspecs;
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
struct sha1_array merge_heads = SHA1_ARRAY_INIT;
|
2015-06-14 10:41:52 +02:00
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
if (!getenv("_GIT_USE_BUILTIN_PULL")) {
|
|
|
|
const char *path = mkpath("%s/git-pull", git_exec_path());
|
|
|
|
|
|
|
|
if (sane_execvp(path, (char **)argv) < 0)
|
|
|
|
die_errno("could not exec %s", path);
|
|
|
|
}
|
|
|
|
|
|
|
|
argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
parse_repo_refspecs(argc, argv, &repo, &refspecs);
|
|
|
|
|
2015-06-18 12:54:03 +02:00
|
|
|
if (!opt_ff)
|
|
|
|
opt_ff = xstrdup_or_null(config_get_ff());
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
if (run_fetch(repo, refspecs))
|
|
|
|
return 1;
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
if (opt_dry_run)
|
|
|
|
return 0;
|
|
|
|
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
get_merge_heads(&merge_heads);
|
|
|
|
|
|
|
|
if (!merge_heads.nr)
|
|
|
|
die_no_merge_candidates(repo, refspecs);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
return run_merge();
|
2015-06-14 10:41:51 +02:00
|
|
|
}
|