Merge branch 'sw/pull-ipv46-passthru' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:09:00 +0000 (09:09 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 6 Dec 2017 17:09:00 +0000 (09:09 -0800)
Contrary to the documentation, "git pull -4/-6 other-args" did not
ask the underlying "git fetch" to go over IPv4/IPv6, which has been
corrected.

* sw/pull-ipv46-passthru:
  pull: pass -4/-6 option to 'git fetch'

1  2 
builtin/pull.c

diff --combined builtin/pull.c
@@@ -6,7 -6,6 +6,7 @@@
   * Fetch one or more remote refs and merge it/them into the current HEAD.
   */
  #include "cache.h"
 +#include "config.h"
  #include "builtin.h"
  #include "parse-options.h"
  #include "exec_cmd.h"
@@@ -16,8 -15,6 +16,8 @@@
  #include "dir.h"
  #include "refs.h"
  #include "revision.h"
 +#include "submodule.h"
 +#include "submodule-config.h"
  #include "tempfile.h"
  #include "lockfile.h"
  #include "wt-status.h"
@@@ -39,7 -36,7 +39,7 @@@ enum rebase_type 
  static enum rebase_type parse_config_rebase(const char *key, const char *value,
                int fatal)
  {
 -      int v = git_config_maybe_bool("pull.rebase", value);
 +      int v = git_parse_maybe_bool(value);
  
        if (!v)
                return REBASE_FALSE;
@@@ -80,7 -77,6 +80,7 @@@ static const char * const pull_usage[] 
  /* Shared options */
  static int opt_verbosity;
  static char *opt_progress;
 +static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
  
  /* Options passed to git-merge or git-rebase */
  static enum rebase_type opt_rebase = -1;
@@@ -105,6 -101,7 +105,6 @@@ static char *opt_upload_pack
  static int opt_force;
  static char *opt_tags;
  static char *opt_prune;
 -static char *opt_recurse_submodules;
  static char *max_children;
  static int opt_dry_run;
  static char *opt_keep;
@@@ -112,6 -109,8 +112,8 @@@ static char *opt_depth
  static char *opt_unshallow;
  static char *opt_update_shallow;
  static char *opt_refmap;
+ static char *opt_ipv4;
+ static char *opt_ipv6;
  
  static struct option pull_options[] = {
        /* Shared options */
        OPT_PASSTHRU(0, "progress", &opt_progress, NULL,
                N_("force progress reporting"),
                PARSE_OPT_NOARG),
 +      { OPTION_CALLBACK, 0, "recurse-submodules",
 +                 &recurse_submodules, N_("on-demand"),
 +                 N_("control for recursive fetching of submodules"),
 +                 PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules },
  
        /* Options passed to git-merge or git-rebase */
        OPT_GROUP(N_("Options related to merging")),
        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_PASSTHRU('j', "jobs", &max_children, N_("n"),
                N_("number of submodules pulled in parallel"),
                PARSE_OPT_OPTARG),
        OPT_PASSTHRU(0, "refmap", &opt_refmap, N_("refmap"),
                N_("specify fetch refmap"),
                PARSE_OPT_NONEG),
+       OPT_PASSTHRU('4',  "ipv4", &opt_ipv4, NULL,
+               N_("use IPv4 addresses only"),
+               PARSE_OPT_NOARG),
+       OPT_PASSTHRU('6',  "ipv6", &opt_ipv6, NULL,
+               N_("use IPv6 addresses only"),
+               PARSE_OPT_NOARG),
  
        OPT_END()
  };
@@@ -274,7 -279,7 +282,7 @@@ static const char *config_get_ff(void
        if (git_config_get_value("pull.ff", &value))
                return NULL;
  
 -      switch (git_config_maybe_bool("pull.ff", value)) {
 +      switch (git_parse_maybe_bool(value)) {
        case 0:
                return "--no-ff";
        case 1:
@@@ -325,10 -330,6 +333,10 @@@ static int git_pull_config(const char *
        if (!strcmp(var, "rebase.autostash")) {
                config_autostash = git_config_bool(var, value);
                return 0;
 +      } else if (!strcmp(var, "submodule.recurse")) {
 +              recurse_submodules = git_config_bool(var, value) ?
 +                      RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
 +              return 0;
        }
        return git_default_config(var, value, cb);
  }
@@@ -344,7 -345,8 +352,7 @@@ static void get_merge_heads(struct oid_
        struct strbuf sb = STRBUF_INIT;
        struct object_id oid;
  
 -      if (!(fp = fopen(filename, "r")))
 -              die_errno(_("could not open '%s' for reading"), filename);
 +      fp = xfopen(filename, "r");
        while (strbuf_getline_lf(&sb, fp) != EOF) {
                if (get_oid_hex(sb.buf, &oid))
                        continue;  /* invalid line: does not start with SHA1 */
@@@ -490,20 -492,8 +498,20 @@@ static int run_fetch(const char *repo, 
                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 (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
 +              switch (recurse_submodules) {
 +              case RECURSE_SUBMODULES_ON:
 +                      argv_array_push(&args, "--recurse-submodules=on");
 +                      break;
 +              case RECURSE_SUBMODULES_OFF:
 +                      argv_array_push(&args, "--recurse-submodules=no");
 +                      break;
 +              case RECURSE_SUBMODULES_ON_DEMAND:
 +                      argv_array_push(&args, "--recurse-submodules=on-demand");
 +                      break;
 +              default:
 +                      BUG("submodule recursion option not understood");
 +              }
        if (max_children)
                argv_array_push(&args, max_children);
        if (opt_dry_run)
                argv_array_push(&args, opt_update_shallow);
        if (opt_refmap)
                argv_array_push(&args, opt_refmap);
+       if (opt_ipv4)
+               argv_array_push(&args, opt_ipv4);
+       if (opt_ipv6)
+               argv_array_push(&args, opt_ipv6);
  
        if (repo) {
                argv_array_push(&args, repo);
@@@ -541,7 -535,7 +553,7 @@@ static int pull_into_void(const struct 
         * index/worktree changes that the user already made on the unborn
         * branch.
         */
 -      if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head->hash, 0))
 +      if (checkout_fast_forward(&empty_tree_oid, merge_head, 0))
                return 1;
  
        if (update_ref("initial pull", "HEAD", merge_head->hash, curr_head->hash, 0, UPDATE_REFS_DIE_ON_ERR))
        return 0;
  }
  
 +static int rebase_submodules(void)
 +{
 +      struct child_process cp = CHILD_PROCESS_INIT;
 +
 +      cp.git_cmd = 1;
 +      cp.no_stdin = 1;
 +      argv_array_pushl(&cp.args, "submodule", "update",
 +                                 "--recursive", "--rebase", NULL);
 +
 +      return run_command(&cp);
 +}
 +
 +static int update_submodules(void)
 +{
 +      struct child_process cp = CHILD_PROCESS_INIT;
 +
 +      cp.git_cmd = 1;
 +      cp.no_stdin = 1;
 +      argv_array_pushl(&cp.args, "submodule", "update",
 +                                 "--recursive", "--checkout", NULL);
 +
 +      return run_command(&cp);
 +}
 +
  /**
   * Runs git-merge, returning its exit status.
   */
@@@ -740,20 -710,17 +752,20 @@@ static int get_octopus_merge_base(struc
  {
        struct commit_list *revs = NULL, *result;
  
 -      commit_list_insert(lookup_commit_reference(curr_head->hash), &revs);
 -      commit_list_insert(lookup_commit_reference(merge_head->hash), &revs);
 +      commit_list_insert(lookup_commit_reference(curr_head), &revs);
 +      commit_list_insert(lookup_commit_reference(merge_head), &revs);
        if (!is_null_oid(fork_point))
 -              commit_list_insert(lookup_commit_reference(fork_point->hash), &revs);
 +              commit_list_insert(lookup_commit_reference(fork_point), &revs);
  
 -      result = reduce_heads(get_octopus_merge_bases(revs));
 +      result = get_octopus_merge_bases(revs);
        free_commit_list(revs);
 +      reduce_heads_replace(&result);
 +
        if (!result)
                return 1;
  
        oidcpy(merge_base, &result->item->object.oid);
 +      free_commit_list(result);
        return 0;
  }
  
@@@ -822,8 -789,6 +834,8 @@@ int cmd_pull(int argc, const char **arg
        if (!getenv("GIT_REFLOG_ACTION"))
                set_reflog_message(argc, argv);
  
 +      git_config(git_pull_config, NULL);
 +
        argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
  
        parse_repo_refspecs(argc, argv, &repo, &refspecs);
        if (opt_rebase < 0)
                opt_rebase = config_get_rebase();
  
 -      git_config(git_pull_config, NULL);
 -
        if (read_cache_unmerged())
                die_resolve_conflict("pull");
  
                        "fast-forwarding your working tree from\n"
                        "commit %s."), oid_to_hex(&orig_head));
  
 -              if (checkout_fast_forward(orig_head.hash, curr_head.hash, 0))
 +              if (checkout_fast_forward(&orig_head, &curr_head, 0))
                        die(_("Cannot fast-forward your working tree.\n"
                                "After making sure that you saved anything precious from\n"
                                "$ git diff %s\n"
                die(_("Cannot rebase onto multiple branches."));
  
        if (opt_rebase) {
 +              int ret = 0;
 +              if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
 +                   recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
 +                  submodule_touches_in_range(&rebase_fork_point, &curr_head))
 +                      die(_("cannot rebase with locally recorded submodule modifications"));
                if (!autostash) {
                        struct commit_list *list = NULL;
                        struct commit *merge_head, *head;
  
 -                      head = lookup_commit_reference(orig_head.hash);
 +                      head = lookup_commit_reference(&orig_head);
                        commit_list_insert(head, &list);
 -                      merge_head = lookup_commit_reference(merge_heads.oid[0].hash);
 +                      merge_head = lookup_commit_reference(&merge_heads.oid[0]);
                        if (is_descendant_of(merge_head, list)) {
                                /* we can fast-forward this without invoking rebase */
                                opt_ff = "--ff-only";
 -                              return run_merge();
 +                              ret = run_merge();
                        }
                }
 -              return run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
 +              ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
 +
 +              if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
 +                           recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
 +                      ret = rebase_submodules();
 +
 +              return ret;
        } else {
 -              return run_merge();
 +              int ret = run_merge();
 +              if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
 +                           recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
 +                      ret = update_submodules();
 +              return ret;
        }
  }