git-fetch: do not fail when remote branch disappears
When the branch named with branch.$name.merge is not covered by the fetch configuration for the remote repository named with branch.$name.remote, we automatically add that branch to the set of branches to be fetched. However, if the remote repository does not have that branch (e.g. it used to exist, but got removed), this is not a reason to fail the git-fetch itself. The situation however will be noticed if git-fetch was called by git-pull, as the resulting FETCH_HEAD would not have any entry that is marked for merging. Acked-By: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
071a887766
commit
9ad7c5ae8a
@ -48,15 +48,21 @@ static void add_merge_config(struct ref **head,
|
||||
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;
|
||||
}
|
||||
@ -75,7 +81,7 @@ static struct ref *get_ref_map(struct transport *transport,
|
||||
|
||||
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;
|
||||
}
|
||||
@ -88,7 +94,7 @@ static struct ref *get_ref_map(struct transport *transport,
|
||||
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 */
|
||||
@ -97,7 +103,7 @@ static struct ref *get_ref_map(struct transport *transport,
|
||||
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;
|
||||
@ -110,11 +116,13 @@ static struct ref *get_ref_map(struct transport *transport,
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
20
remote.c
20
remote.c
@ -857,7 +857,7 @@ struct ref *get_remote_ref(struct ref *remote_refs, const char *name)
|
||||
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);
|
||||
}
|
||||
@ -889,20 +889,24 @@ static struct ref *get_local_ref(const char *name)
|
||||
|
||||
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");
|
||||
const char *name = 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;
|
||||
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) {
|
||||
|
5
remote.h
5
remote.h
@ -67,9 +67,12 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
|
||||
* *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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user