checkout.con commit general improvements (43abf13)
   1#include "cache.h"
   2#include "remote.h"
   3#include "refspec.h"
   4#include "checkout.h"
   5#include "config.h"
   6
   7struct tracking_name_data {
   8        /* const */ char *src_ref;
   9        char *dst_ref;
  10        struct object_id *dst_oid;
  11        int num_matches;
  12        const char *default_remote;
  13        char *default_dst_ref;
  14        struct object_id *default_dst_oid;
  15};
  16
  17#define TRACKING_NAME_DATA_INIT { NULL, NULL, NULL, 0, NULL, NULL, NULL }
  18
  19static int check_tracking_name(struct remote *remote, void *cb_data)
  20{
  21        struct tracking_name_data *cb = cb_data;
  22        struct refspec_item query;
  23        memset(&query, 0, sizeof(struct refspec_item));
  24        query.src = cb->src_ref;
  25        if (remote_find_tracking(remote, &query) ||
  26            get_oid(query.dst, cb->dst_oid)) {
  27                free(query.dst);
  28                return 0;
  29        }
  30        cb->num_matches++;
  31        if (cb->default_remote && !strcmp(remote->name, cb->default_remote)) {
  32                struct object_id *dst = xmalloc(sizeof(*cb->default_dst_oid));
  33                cb->default_dst_ref = xstrdup(query.dst);
  34                oidcpy(dst, cb->dst_oid);
  35                cb->default_dst_oid = dst;
  36        }
  37        if (cb->dst_ref) {
  38                free(query.dst);
  39                return 0;
  40        }
  41        cb->dst_ref = query.dst;
  42        return 0;
  43}
  44
  45const char *unique_tracking_name(const char *name, struct object_id *oid,
  46                                 int *dwim_remotes_matched)
  47{
  48        struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT;
  49        const char *default_remote = NULL;
  50        if (!git_config_get_string_const("checkout.defaultremote", &default_remote))
  51                cb_data.default_remote = default_remote;
  52        cb_data.src_ref = xstrfmt("refs/heads/%s", name);
  53        cb_data.dst_oid = oid;
  54        for_each_remote(check_tracking_name, &cb_data);
  55        if (dwim_remotes_matched)
  56                *dwim_remotes_matched = cb_data.num_matches;
  57        free(cb_data.src_ref);
  58        free((char *)default_remote);
  59        if (cb_data.num_matches == 1) {
  60                free(cb_data.default_dst_ref);
  61                free(cb_data.default_dst_oid);
  62                return cb_data.dst_ref;
  63        }
  64        free(cb_data.dst_ref);
  65        if (cb_data.default_dst_ref) {
  66                oidcpy(oid, cb_data.default_dst_oid);
  67                free(cb_data.default_dst_oid);
  68                return cb_data.default_dst_ref;
  69        }
  70        return NULL;
  71}