Skip to content

Commit

Permalink
git-fetch: do not fail when remote branch disappears
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Oct 28, 2007
1 parent 071a887 commit 9ad7c5a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
24 changes: 16 additions & 8 deletions builtin-fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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 */
Expand All @@ -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;
Expand All @@ -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;
}
}
Expand Down
22 changes: 13 additions & 9 deletions remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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");

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) {
Expand Down
5 changes: 4 additions & 1 deletion remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 9ad7c5a

Please sign in to comment.