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