Add initial support for many promisor remotes
[gitweb.git] / builtin / pull.c
index 681c127a07071c98641972227a28dbe7f77eaf70..9dd32a115bbbfeedb1c1648348ddd32ccaa9b641 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Fetch one or more remote refs and merge it/them into the current HEAD.
  */
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
 #include "config.h"
 #include "builtin.h"
@@ -22,6 +23,8 @@
 #include "tempfile.h"
 #include "lockfile.h"
 #include "wt-status.h"
+#include "commit-reach.h"
+#include "sequencer.h"
 
 enum rebase_type {
        REBASE_INVALID = -1,
@@ -54,6 +57,10 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value,
                return REBASE_MERGES;
        else if (!strcmp(value, "interactive") || !strcmp(value, "i"))
                return REBASE_INTERACTIVE;
+       /*
+        * Please update _git_config() in git-completion.bash when you
+        * add new rebase modes.
+        */
 
        if (fatal)
                die(_("Invalid value for %s: %s"), key, value);
@@ -95,6 +102,7 @@ static char *opt_signoff;
 static char *opt_squash;
 static char *opt_commit;
 static char *opt_edit;
+static char *cleanup_arg;
 static char *opt_ff;
 static char *opt_verify_signatures;
 static int opt_autostash = -1;
@@ -162,6 +170,7 @@ static struct option pull_options[] = {
        OPT_PASSTHRU(0, "edit", &opt_edit, NULL,
                N_("edit message before committing"),
                PARSE_OPT_NOARG),
+       OPT_CLEANUP(&cleanup_arg),
        OPT_PASSTHRU(0, "ff", &opt_ff, NULL,
                N_("allow fast-forward"),
                PARSE_OPT_NOARG),
@@ -363,9 +372,10 @@ static void get_merge_heads(struct oid_array *merge_heads)
 
        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 */
-               if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
+               const char *p;
+               if (parse_oid_hex(sb.buf, &oid, &p))
+                       continue;  /* invalid line: does not start with object ID */
+               if (starts_with(p, "\tnot-for-merge\t"))
                        continue;  /* ref is not-for-merge */
                oid_array_append(merge_heads, &oid);
        }
@@ -556,13 +566,26 @@ static int run_fetch(const char *repo, const char **refspecs)
 static int pull_into_void(const struct object_id *merge_head,
                const struct object_id *curr_head)
 {
+       if (opt_verify_signatures) {
+               struct commit *commit;
+
+               commit = lookup_commit(the_repository, merge_head);
+               if (!commit)
+                       die(_("unable to access commit %s"),
+                           oid_to_hex(merge_head));
+
+               verify_merge_signature(commit, opt_verbosity);
+       }
+
        /*
         * Two-way merge: we treat the index as based on an empty tree,
         * and try to fast-forward to HEAD. This ensures we will not lose
         * index/worktree changes that the user already made on the unborn
         * branch.
         */
-       if (checkout_fast_forward(the_hash_algo->empty_tree, merge_head, 0))
+       if (checkout_fast_forward(the_repository,
+                                 the_hash_algo->empty_tree,
+                                 merge_head, 0))
                return 1;
 
        if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR))
@@ -625,6 +648,8 @@ static int run_merge(void)
                argv_array_push(&args, opt_commit);
        if (opt_edit)
                argv_array_push(&args, opt_edit);
+       if (cleanup_arg)
+               argv_array_pushf(&args, "--cleanup=%s", cleanup_arg);
        if (opt_ff)
                argv_array_push(&args, opt_ff);
        if (opt_verify_signatures)
@@ -741,7 +766,7 @@ static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
        cp.no_stderr = 1;
        cp.git_cmd = 1;
 
-       ret = capture_command(&cp, &sb, GIT_SHA1_HEXSZ);
+       ret = capture_command(&cp, &sb, GIT_MAX_HEXSZ);
        if (ret)
                goto cleanup;
 
@@ -786,7 +811,7 @@ static int get_octopus_merge_base(struct object_id *merge_base,
 }
 
 /**
- * Given the current HEAD SHA1, the merge head returned from git-fetch and the
+ * Given the current HEAD oid, the merge head returned from git-fetch and the
  * fork point calculated by get_rebase_fork_point(), runs git-rebase with the
  * appropriate arguments and returns its exit status.
  */
@@ -799,7 +824,7 @@ static int run_rebase(const struct object_id *curr_head,
        struct argv_array args = ARGV_ARRAY_INIT;
 
        if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point))
-               if (!is_null_oid(fork_point) && !oidcmp(&oct_merge_base, fork_point))
+               if (!is_null_oid(fork_point) && oideq(&oct_merge_base, fork_point))
                        fork_point = NULL;
 
        argv_array_push(&args, "rebase");
@@ -856,6 +881,13 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
        argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
 
+       if (cleanup_arg)
+               /*
+                * this only checks the validity of cleanup_arg; we don't need
+                * a valid value for use_editor
+                */
+               get_cleanup_mode(cleanup_arg, 0);
+
        parse_repo_refspecs(argc, argv, &repo, &refspecs);
 
        if (!opt_ff)
@@ -885,7 +917,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                        die(_("Updating an unborn branch with changes added to the index."));
 
                if (!autostash)
-                       require_clean_work_tree(N_("pull with rebase"),
+                       require_clean_work_tree(the_repository,
+                               N_("pull with rebase"),
                                _("please commit or stash them."), 1, 0);
 
                if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))
@@ -902,7 +935,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                oidclr(&curr_head);
 
        if (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&
-                       oidcmp(&orig_head, &curr_head)) {
+                       !oideq(&orig_head, &curr_head)) {
                /*
                 * The fetch involved updating the current branch.
                 *
@@ -915,7 +948,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                        "fast-forwarding your working tree from\n"
                        "commit %s."), oid_to_hex(&orig_head));
 
-               if (checkout_fast_forward(&orig_head, &curr_head, 0))
+               if (checkout_fast_forward(the_repository, &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"
@@ -941,7 +975,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                int ret = 0;
                if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
                     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
-                   submodule_touches_in_range(&rebase_fork_point, &curr_head))
+                   submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
                        die(_("cannot rebase with locally recorded submodule modifications"));
                if (!autostash) {
                        struct commit_list *list = NULL;