git/builtin/pull.c

/*
 * 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.
 */

#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "advice.h"
#include "config.h"
#include "gettext.h"
#include "hex.h"
#include "merge.h"
#include "object-name.h"
#include "parse-options.h"
#include "run-command.h"
#include "oid-array.h"
#include "remote.h"
#include "dir.h"
#include "path.h"
#include "read-cache-ll.h"
#include "rebase.h"
#include "refs.h"
#include "refspec.h"
#include "submodule.h"
#include "submodule-config.h"
#include "wt-status.h"
#include "commit-reach.h"
#include "sequencer.h"

/**
 * Parses the value of --rebase. If value is a false value, returns
 * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
 * "merges", returns REBASE_MERGES. If value is a invalid value, dies with
 * a fatal error if fatal is true, otherwise returns REBASE_INVALID.
 */
static enum rebase_type parse_config_rebase(const char *key, const char *value,
		int fatal)
{}

/**
 * Callback for --rebase, which parses arg with parse_config_rebase().
 */
static int parse_opt_rebase(const struct option *opt, const char *arg, int unset)
{}

static const char * const pull_usage[] =;

/* Shared options */
static int opt_verbosity;
static const char *opt_progress;
static int recurse_submodules =;
static int recurse_submodules_cli =;

/* Options passed to git-merge or git-rebase */
static enum rebase_type opt_rebase =;
static const char *opt_diffstat;
static const char *opt_log;
static const char *opt_signoff;
static const char *opt_squash;
static const char *opt_commit;
static const char *opt_edit;
static const char *cleanup_arg;
static char *opt_ff;
static const char *opt_verify_signatures;
static const char *opt_verify;
static int opt_autostash =;
static int config_autostash;
static int check_trust_level =;
static struct strvec opt_strategies =;
static struct strvec opt_strategy_opts =;
static const char *opt_gpg_sign;
static int opt_allow_unrelated_histories;

/* Options passed to git-fetch */
static const char *opt_all;
static const char *opt_append;
static const char *opt_upload_pack;
static int opt_force;
static const char *opt_tags;
static const char *opt_prune;
static const char *max_children;
static int opt_dry_run;
static const char *opt_keep;
static const char *opt_depth;
static const char *opt_unshallow;
static const char *opt_update_shallow;
static const char *opt_refmap;
static const char *opt_ipv4;
static const char *opt_ipv6;
static int opt_show_forced_updates =;
static const char *set_upstream;
static struct strvec opt_fetch =;

static struct option pull_options[] =;

/**
 * Pushes "-q" or "-v" switches into arr to match the opt_verbosity level.
 */
static void argv_push_verbosity(struct strvec *arr)
{}

/**
 * Pushes "-f" switches into arr to match the opt_force level.
 */
static void argv_push_force(struct strvec *arr)
{}

/**
 * Sets the GIT_REFLOG_ACTION environment variable to the concatenation of argv
 */
static void set_reflog_message(int argc, const char **argv)
{}

/**
 * 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)
{}

/**
 * Returns the default configured value for --rebase. It first looks for the
 * value of "branch.$curr_branch.rebase", where $curr_branch is the current
 * branch, and if HEAD is detached or the configuration key does not exist,
 * looks for the value of "pull.rebase". If both configuration keys do not
 * exist, returns REBASE_FALSE.
 */
static enum rebase_type config_get_rebase(int *rebase_unspecified)
{}

/**
 * Read config variables.
 */
static int git_pull_config(const char *var, const char *value,
			   const struct config_context *ctx, void *cb)
{}

/**
 * Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
 * into merge_heads.
 */
static void get_merge_heads(struct oid_array *merge_heads)
{}

/**
 * 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)
{}

/**
 * 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)
{}

/**
 * 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)
{}

/**
 * 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)
{}

/**
 * "Pulls into void" by branching off merge_head.
 */
static int pull_into_void(const struct object_id *merge_head,
		const struct object_id *curr_head)
{}

static int rebase_submodules(void)
{}

static int update_submodules(void)
{}

/**
 * Runs git-merge, returning its exit status.
 */
static int run_merge(void)
{}

/**
 * Returns remote's upstream branch for the current branch. If remote is NULL,
 * the current branch's configured default remote is used. Returns NULL if
 * `remote` does not name a valid remote, HEAD does not point to a branch,
 * remote is not the branch's configured remote or the branch does not have any
 * configured upstream branch.
 */
static const char *get_upstream_branch(const char *remote)
{}

/**
 * Derives the remote-tracking branch from the remote and refspec.
 *
 * FIXME: The current implementation assumes the default mapping of
 * refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>.
 */
static const char *get_tracking_branch(const char *remote, const char *refspec)
{}

/**
 * Given the repo and refspecs, sets fork_point to the point at which the
 * current branch forked from its remote-tracking branch. Returns 0 on success,
 * -1 on failure.
 */
static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
		const char *refspec)
{}

/**
 * Sets merge_base to the octopus merge base of curr_head, merge_head and
 * fork_point. Returns 0 if a merge base is found, 1 otherwise.
 */
static int get_octopus_merge_base(struct object_id *merge_base,
		const struct object_id *curr_head,
		const struct object_id *merge_head,
		const struct object_id *fork_point)
{}

/**
 * Given the current HEAD oid, the merge head returned from git-fetch and the
 * fork point calculated by get_rebase_fork_point(), compute the <newbase> and
 * <upstream> arguments to use for the upcoming git-rebase invocation.
 */
static int get_rebase_newbase_and_upstream(struct object_id *newbase,
		struct object_id *upstream,
		const struct object_id *curr_head,
		const struct object_id *merge_head,
		const struct object_id *fork_point)
{}

/**
 * Given the <newbase> and <upstream> calculated by
 * get_rebase_newbase_and_upstream(), runs git-rebase with the
 * appropriate arguments and returns its exit status.
 */
static int run_rebase(const struct object_id *newbase,
		const struct object_id *upstream)
{}

static int get_can_ff(struct object_id *orig_head,
		      struct oid_array *merge_heads)
{}

/*
 * Is orig_head a descendant of _all_ merge_heads?
 * Unfortunately is_descendant_of() cannot be used as it asks
 * if orig_head is a descendant of at least one of them.
 */
static int already_up_to_date(struct object_id *orig_head,
			      struct oid_array *merge_heads)
{}

static void show_advice_pull_non_ff(void)
{}

int cmd_pull(int argc,
	     const char **argv,
	     const char *prefix,
	     struct repository *repository UNUSED)
{}