Skip to content

Commit cdb8a60

Browse files
committed
clone: make use of the remote's default branch guessing
Let's use the remote's default branch guessing instead of reinventing one ourselves with callbacks.
1 parent d22db24 commit cdb8a60

File tree

1 file changed

+17
-67
lines changed

1 file changed

+17
-67
lines changed

src/clone.c

Lines changed: 17 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -108,51 +108,10 @@ static int create_tracking_branch(
108108
struct head_info {
109109
git_repository *repo;
110110
git_oid remote_head_oid;
111-
git_buf branchname;
112111
const git_refspec *refspec;
113112
bool found;
114113
};
115114

116-
static int reference_matches_remote_head(
117-
const char *reference_name,
118-
void *payload)
119-
{
120-
struct head_info *head_info = (struct head_info *)payload;
121-
git_oid oid;
122-
int error;
123-
124-
/* TODO: Should we guard against references
125-
* which name doesn't start with refs/heads/ ?
126-
*/
127-
128-
error = git_reference_name_to_id(&oid, head_info->repo, reference_name);
129-
if (error == GIT_ENOTFOUND) {
130-
/* If the reference doesn't exists, it obviously cannot match the
131-
* expected oid. */
132-
giterr_clear();
133-
return 0;
134-
}
135-
136-
if (!error && !git_oid__cmp(&head_info->remote_head_oid, &oid)) {
137-
/* Determine the local reference name from the remote tracking one */
138-
error = git_refspec_rtransform(
139-
&head_info->branchname, head_info->refspec, reference_name);
140-
141-
if (!error &&
142-
git_buf_len(&head_info->branchname) > 0 &&
143-
!(error = git_buf_sets(
144-
&head_info->branchname,
145-
git_buf_cstr(&head_info->branchname) +
146-
strlen(GIT_REFS_HEADS_DIR))))
147-
{
148-
head_info->found = true;
149-
error = GIT_ITEROVER;
150-
}
151-
}
152-
153-
return error;
154-
}
155-
156115
static int update_head_to_new_branch(
157116
git_repository *repo,
158117
const git_oid *target,
@@ -161,6 +120,10 @@ static int update_head_to_new_branch(
161120
const char *reflog_message)
162121
{
163122
git_reference *tracking_branch = NULL;
123+
124+
if (!git__prefixcmp(name, GIT_REFS_HEADS_DIR))
125+
name += strlen(GIT_REFS_HEADS_DIR);
126+
164127
int error = create_tracking_branch(&tracking_branch, repo, target, name,
165128
signature, reflog_message);
166129

@@ -190,6 +153,7 @@ static int update_head_to_remote(
190153
const git_remote_head *remote_head, **refs;
191154
struct head_info head_info;
192155
git_buf remote_master_name = GIT_BUF_INIT;
156+
git_buf branch = GIT_BUF_INIT;
193157

194158
if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
195159
return error;
@@ -199,15 +163,22 @@ static int update_head_to_remote(
199163
return setup_tracking_config(
200164
repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE);
201165

166+
memset(&head_info, 0, sizeof(head_info));
167+
error = git_remote_default_branch(&branch, remote);
168+
if (error == GIT_ENOTFOUND) {
169+
git_buf_puts(&branch, GIT_REFS_HEADS_MASTER_FILE);
170+
} else {
171+
head_info.found = 1;
172+
}
173+
202174
/* Get the remote's HEAD. This is always the first ref in the list. */
203175
remote_head = refs[0];
204176
assert(remote_head);
205177

206-
memset(&head_info, 0, sizeof(head_info));
207178
git_oid_cpy(&head_info.remote_head_oid, &remote_head->oid);
208179
head_info.repo = repo;
209180
head_info.refspec =
210-
git_remote__matching_refspec(remote, GIT_REFS_HEADS_MASTER_FILE);
181+
git_remote__matching_refspec(remote, git_buf_cstr(&branch));
211182

212183
if (head_info.refspec == NULL) {
213184
memset(&dummy_spec, 0, sizeof(git_refspec));
@@ -218,35 +189,14 @@ static int update_head_to_remote(
218189
if ((error = git_refspec_transform(
219190
&remote_master_name,
220191
head_info.refspec,
221-
GIT_REFS_HEADS_MASTER_FILE)) < 0)
192+
git_buf_cstr(&branch))) < 0)
222193
return error;
223194

224-
/* Check to see if the remote HEAD points to the remote master */
225-
error = reference_matches_remote_head(
226-
git_buf_cstr(&remote_master_name), &head_info);
227-
if (error < 0 && error != GIT_ITEROVER)
228-
goto cleanup;
229-
230-
if (head_info.found) {
231-
error = update_head_to_new_branch(
232-
repo,
233-
&head_info.remote_head_oid,
234-
git_buf_cstr(&head_info.branchname),
235-
signature, reflog_message);
236-
goto cleanup;
237-
}
238-
239-
/* Not master. Check all the other refs. */
240-
error = git_reference_foreach_name(
241-
repo, reference_matches_remote_head, &head_info);
242-
if (error < 0 && error != GIT_ITEROVER)
243-
goto cleanup;
244-
245195
if (head_info.found) {
246196
error = update_head_to_new_branch(
247197
repo,
248198
&head_info.remote_head_oid,
249-
git_buf_cstr(&head_info.branchname),
199+
git_buf_cstr(&branch),
250200
signature, reflog_message);
251201
} else {
252202
error = git_repository_set_head_detached(
@@ -255,7 +205,7 @@ static int update_head_to_remote(
255205

256206
cleanup:
257207
git_buf_free(&remote_master_name);
258-
git_buf_free(&head_info.branchname);
208+
git_buf_free(&branch);
259209
return error;
260210
}
261211

0 commit comments

Comments
 (0)