1 #include "git-compat-util.h"
2 #include "object-name.h"
9 struct tracking_name_data
{
10 /* const */ char *src_ref
;
12 struct object_id
*dst_oid
;
14 const char *default_remote
;
15 char *default_dst_ref
;
16 struct object_id
*default_dst_oid
;
19 #define TRACKING_NAME_DATA_INIT { 0 }
21 static int check_tracking_name(struct remote
*remote
, void *cb_data
)
23 struct tracking_name_data
*cb
= cb_data
;
24 struct refspec_item query
;
25 memset(&query
, 0, sizeof(struct refspec_item
));
26 query
.src
= cb
->src_ref
;
27 if (remote_find_tracking(remote
, &query
) ||
28 repo_get_oid(the_repository
, query
.dst
, cb
->dst_oid
)) {
33 if (cb
->default_remote
&& !strcmp(remote
->name
, cb
->default_remote
)) {
34 struct object_id
*dst
= xmalloc(sizeof(*cb
->default_dst_oid
));
35 cb
->default_dst_ref
= xstrdup(query
.dst
);
36 oidcpy(dst
, cb
->dst_oid
);
37 cb
->default_dst_oid
= dst
;
43 cb
->dst_ref
= query
.dst
;
47 const char *unique_tracking_name(const char *name
, struct object_id
*oid
,
48 int *dwim_remotes_matched
)
50 struct tracking_name_data cb_data
= TRACKING_NAME_DATA_INIT
;
51 const char *default_remote
= NULL
;
52 if (!git_config_get_string_tmp("checkout.defaultremote", &default_remote
))
53 cb_data
.default_remote
= default_remote
;
54 cb_data
.src_ref
= xstrfmt("refs/heads/%s", name
);
55 cb_data
.dst_oid
= oid
;
56 for_each_remote(check_tracking_name
, &cb_data
);
57 if (dwim_remotes_matched
)
58 *dwim_remotes_matched
= cb_data
.num_matches
;
59 free(cb_data
.src_ref
);
60 if (cb_data
.num_matches
== 1) {
61 free(cb_data
.default_dst_ref
);
62 free(cb_data
.default_dst_oid
);
63 return cb_data
.dst_ref
;
65 free(cb_data
.dst_ref
);
66 if (cb_data
.default_dst_ref
) {
67 oidcpy(oid
, cb_data
.default_dst_oid
);
68 free(cb_data
.default_dst_oid
);
69 return cb_data
.default_dst_ref
;