ref-filter: free item->value and item->value->s
[gitweb.git] / builtin / fetch.c
index e03a1db1a392d20bf45eac693ba3dd01f75da044..0696abfc2a158baa3177fa9e71e2c16bc64655a4 100644 (file)
@@ -22,6 +22,7 @@
 #include "utf8.h"
 #include "packfile.h"
 #include "list-objects-filter-options.h"
+#include "commit-reach.h"
 
 static const char * const builtin_fetch_usage[] = {
        N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -114,7 +115,7 @@ static struct option builtin_fetch_options[] = {
                 N_("append to .git/FETCH_HEAD instead of overwriting")),
        OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
                   N_("path to upload pack on remote end")),
-       OPT__FORCE(&force, N_("force overwrite of local branch"), 0),
+       OPT__FORCE(&force, N_("force overwrite of local reference"), 0),
        OPT_BOOL('m', "multiple", &multiple,
                 N_("fetch from multiple remotes")),
        OPT_SET_INT('t', "tags", &tags,
@@ -238,7 +239,7 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
 {
        struct ref *rm = *head;
        while (rm) {
-               if (!hashcmp(rm->old_oid.hash, sha1))
+               if (hasheq(rm->old_oid.hash, sha1))
                        return 1;
                rm = rm->next;
        }
@@ -507,7 +508,7 @@ static void adjust_refcol_width(const struct ref *ref)
        int max, rlen, llen, len;
 
        /* uptodate lines are only shown on high verbosity level */
-       if (!verbosity && !oidcmp(&ref->peer_ref->old_oid, &ref->old_oid))
+       if (!verbosity && oideq(&ref->peer_ref->old_oid, &ref->old_oid))
                return;
 
        max    = term_columns();
@@ -644,7 +645,7 @@ static int update_local_ref(struct ref *ref,
        if (type < 0)
                die(_("object %s not found"), oid_to_hex(&ref->new_oid));
 
-       if (!oidcmp(&ref->old_oid, &ref->new_oid)) {
+       if (oideq(&ref->old_oid, &ref->new_oid)) {
                if (verbosity > 0)
                        format_display(display, '=', _("[up to date]"), NULL,
                                       remote, pretty_ref, summary_width);
@@ -667,12 +668,18 @@ static int update_local_ref(struct ref *ref,
 
        if (!is_null_oid(&ref->old_oid) &&
            starts_with(ref->name, "refs/tags/")) {
-               int r;
-               r = s_update_ref("updating tag", ref, 0);
-               format_display(display, r ? '!' : 't', _("[tag update]"),
-                              r ? _("unable to update local ref") : NULL,
-                              remote, pretty_ref, summary_width);
-               return r;
+               if (force || ref->force) {
+                       int r;
+                       r = s_update_ref("updating tag", ref, 0);
+                       format_display(display, r ? '!' : 't', _("[tag update]"),
+                                      r ? _("unable to update local ref") : NULL,
+                                      remote, pretty_ref, summary_width);
+                       return r;
+               } else {
+                       format_display(display, '!', _("[rejected]"), _("would clobber existing tag"),
+                                      remote, pretty_ref, summary_width);
+                       return 1;
+               }
        }
 
        current = lookup_commit_reference_gently(the_repository,
@@ -942,13 +949,11 @@ static int quickfetch(struct ref *ref_map)
        return check_connected(iterate_ref_map, &rm, &opt);
 }
 
-static int fetch_refs(struct transport *transport, struct ref *ref_map,
-                     struct ref **updated_remote_refs)
+static int fetch_refs(struct transport *transport, struct ref *ref_map)
 {
        int ret = quickfetch(ref_map);
        if (ret)
-               ret = transport_fetch_refs(transport, ref_map,
-                                          updated_remote_refs);
+               ret = transport_fetch_refs(transport, ref_map);
        if (!ret)
                /*
                 * Keep the new pack's ".keep" file around to allow the caller
@@ -1153,7 +1158,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
        transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, NULL);
        transport_set_option(transport, TRANS_OPT_DEPTH, "0");
        transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
-       if (!fetch_refs(transport, ref_map, NULL))
+       if (!fetch_refs(transport, ref_map))
                consume_refs(transport, ref_map);
 
        if (gsecondary) {
@@ -1169,7 +1174,6 @@ static int do_fetch(struct transport *transport,
        int autotags = (transport->remote->fetch_tags == 1);
        int retcode = 0;
        const struct ref *remote_refs;
-       struct ref *updated_remote_refs = NULL;
        struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
        if (tags == TAGS_DEFAULT) {
@@ -1220,24 +1224,7 @@ static int do_fetch(struct transport *transport,
                                   transport->url);
                }
        }
-
-       if (fetch_refs(transport, ref_map, &updated_remote_refs)) {
-               free_refs(ref_map);
-               retcode = 1;
-               goto cleanup;
-       }
-       if (updated_remote_refs) {
-               /*
-                * Regenerate ref_map using the updated remote refs.  This is
-                * to account for additional information which may be provided
-                * by the transport (e.g. shallow info).
-                */
-               free_refs(ref_map);
-               ref_map = get_ref_map(transport->remote, updated_remote_refs, rs,
-                                     tags, &autotags);
-               free_refs(updated_remote_refs);
-       }
-       if (consume_refs(transport, ref_map)) {
+       if (fetch_refs(transport, ref_map) || consume_refs(transport, ref_map)) {
                free_refs(ref_map);
                retcode = 1;
                goto cleanup;