if (rm)
continue;
- /* Not fetched to a tracking branch? We need to fetch
+ /*
+ * Not fetched to a tracking branch? We need to fetch
* it anyway to allow this branch's "branch.$name.merge"
- * to be honored by git-pull.
+ * to be honored by git-pull, but we do not have to
+ * fail if branch.$name.merge is misconfigured to point
+ * at a nonexisting branch. If we were indeed called by
+ * git-pull, it will notice the misconfiguration because
+ * there is no entry in the resulting FETCH_HEAD marked
+ * for merging.
*/
refspec.src = branch->merge[i]->src;
refspec.dst = NULL;
refspec.pattern = 0;
refspec.force = 0;
- get_fetch_map(remote_refs, &refspec, tail);
+ get_fetch_map(remote_refs, &refspec, tail, 1);
for (rm = *old_tail; rm; rm = rm->next)
rm->merge = 1;
}
if (ref_count || tags) {
for (i = 0; i < ref_count; i++) {
- get_fetch_map(remote_refs, &refs[i], &tail);
+ get_fetch_map(remote_refs, &refs[i], &tail, 0);
if (refs[i].dst && refs[i].dst[0])
*autotags = 1;
}
refspec.dst = "refs/tags/";
refspec.pattern = 1;
refspec.force = 0;
- get_fetch_map(remote_refs, &refspec, &tail);
+ get_fetch_map(remote_refs, &refspec, &tail, 0);
}
} else {
/* Use the defaults */
int has_merge = branch_has_merge_config(branch);
if (remote && (remote->fetch_refspec_nr || has_merge)) {
for (i = 0; i < remote->fetch_refspec_nr; i++) {
- get_fetch_map(remote_refs, &remote->fetch[i], &tail);
+ get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);
if (remote->fetch[i].dst &&
remote->fetch[i].dst[0])
*autotags = 1;
* as given in branch.<name>.remote, we add the
* ref given in branch.<name>.merge, too.
*/
- if (has_merge && !strcmp(branch->remote_name,
- remote->name))
+ if (has_merge &&
+ !strcmp(branch->remote_name, remote->name))
add_merge_config(&ref_map, remote_refs, branch, &tail);
} else {
ref_map = get_remote_ref(remote_refs, "HEAD");
+ if (!ref_map)
+ die("Couldn't find remote ref HEAD");
ref_map->merge = 1;
}
}
struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
if (!ref)
- die("Couldn't find remote ref %s\n", name);
+ return NULL;
return copy_ref(ref);
}
int get_fetch_map(struct ref *remote_refs,
const struct refspec *refspec,
- struct ref ***tail)
+ struct ref ***tail,
+ int missing_ok)
{
struct ref *ref_map, *rm;
if (refspec->pattern) {
ref_map = get_expanded_map(remote_refs, refspec);
} else {
- ref_map = get_remote_ref(remote_refs,
- refspec->src[0] ?
- refspec->src : "HEAD");
-
- ref_map->peer_ref = get_local_ref(refspec->dst);
- if (ref_map->peer_ref && refspec->force)
- ref_map->peer_ref->force = 1;
+ const char *name = refspec->src[0] ? refspec->src : "HEAD";
+
+ ref_map = get_remote_ref(remote_refs, name);
+ if (!missing_ok && !ref_map)
+ die("Couldn't find remote ref %s", name);
+ if (ref_map) {
+ ref_map->peer_ref = get_local_ref(refspec->dst);
+ if (ref_map->peer_ref && refspec->force)
+ ref_map->peer_ref->force = 1;
+ }
}
for (rm = ref_map; rm; rm = rm->next) {
* *tail is the pointer to the tail pointer of the list of results
* beforehand, and will be set to the tail pointer of the list of
* results afterward.
+ *
+ * missing_ok is usually false, but when we are adding branch.$name.merge
+ * it is Ok if the branch is not at the remote anymore.
*/
int get_fetch_map(struct ref *remote_refs, const struct refspec *refspec,
- struct ref ***tail);
+ struct ref ***tail, int missing_ok);
struct ref *get_remote_ref(struct ref *remote_refs, const char *name);