Skip to content

Commit 0281c93

Browse files
mhaggergitster
authored andcommitted
fetch: only opportunistically update references based on command line
The old code processed (tags == TAGS_SET) before adding the entries used to opportunistically update references mentioned on the command line. The result was that all tags were also considered candidates for opportunistic updating. This is harmless for two reasons: (a) because it would only add entries if there is a configured refspec that covers tags *and* both --tags and another refspec appear on the command-line; (b) because any extra entries would be deleted later by the call to ref_remove_duplicates() anyway. But, to avoid extra work and extra memory usage, and to make the implementation better match the intention, change the algorithm slightly: compute the opportunistic refspecs based only on the command-line arguments, storing the results into a separate temporary list. Then add the tags (which have to come earlier in the list so that they are not de-duped in favor of an opportunistic entry). Then concatenate the temporary list onto the main list. This change will also make later changes easier. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent e31a17f commit 0281c93

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

builtin/fetch.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,32 +272,50 @@ static struct ref *get_ref_map(struct transport *transport,
272272
const struct ref *remote_refs = transport_get_remote_refs(transport);
273273

274274
if (refspec_count || tags == TAGS_SET) {
275-
struct ref **old_tail;
275+
/* opportunistically-updated references: */
276+
struct ref *orefs = NULL, **oref_tail = &orefs;
276277

277278
for (i = 0; i < refspec_count; i++) {
278279
get_fetch_map(remote_refs, &refspecs[i], &tail, 0);
279280
if (refspecs[i].dst && refspecs[i].dst[0])
280281
*autotags = 1;
281282
}
282-
/* Merge everything on the command line, but not --tags */
283+
/* Merge everything on the command line (but not --tags) */
283284
for (rm = ref_map; rm; rm = rm->next)
284285
rm->fetch_head_status = FETCH_HEAD_MERGE;
285-
if (tags == TAGS_SET)
286-
get_fetch_map(remote_refs, tag_refspec, &tail, 0);
287286

288287
/*
289-
* For any refs that we happen to be fetching via command-line
290-
* arguments, take the opportunity to update their configured
291-
* counterparts. However, we do not want to mention these
292-
* entries in FETCH_HEAD at all, as they would simply be
293-
* duplicates of existing entries.
288+
* For any refs that we happen to be fetching via
289+
* command-line arguments, the destination ref might
290+
* have been missing or have been different than the
291+
* remote-tracking ref that would be derived from the
292+
* configured refspec. In these cases, we want to
293+
* take the opportunity to update their configured
294+
* remote-tracking reference. However, we do not want
295+
* to mention these entries in FETCH_HEAD at all, as
296+
* they would simply be duplicates of existing
297+
* entries, so we set them FETCH_HEAD_IGNORE below.
298+
*
299+
* We compute these entries now, based only on the
300+
* refspecs specified on the command line. But we add
301+
* them to the list following the refspecs resulting
302+
* from the tags option so that one of the latter,
303+
* which has FETCH_HEAD_NOT_FOR_MERGE, is not removed
304+
* by ref_remove_duplicates() in favor of one of these
305+
* opportunistic entries with FETCH_HEAD_IGNORE.
294306
*/
295-
old_tail = tail;
296307
for (i = 0; i < transport->remote->fetch_refspec_nr; i++)
297308
get_fetch_map(ref_map, &transport->remote->fetch[i],
298-
&tail, 1);
299-
for (rm = *old_tail; rm; rm = rm->next)
309+
&oref_tail, 1);
310+
311+
if (tags == TAGS_SET)
312+
get_fetch_map(remote_refs, tag_refspec, &tail, 0);
313+
314+
*tail = orefs;
315+
for (rm = orefs; rm; rm = rm->next) {
300316
rm->fetch_head_status = FETCH_HEAD_IGNORE;
317+
tail = &rm->next;
318+
}
301319
} else {
302320
/* Use the defaults */
303321
struct remote *remote = transport->remote;
@@ -334,8 +352,10 @@ static struct ref *get_ref_map(struct transport *transport,
334352
tail = &ref_map->next;
335353
}
336354
}
355+
337356
if (tags == TAGS_DEFAULT && *autotags)
338357
find_non_local_tags(transport, &ref_map, &tail);
358+
339359
ref_remove_duplicates(ref_map);
340360

341361
return ref_map;

0 commit comments

Comments
 (0)