bool cvs_same_branch(const cvs_number *a, const cvs_number *b) /* are two specified CVS revisions on the same branch? */ { cvs_number t; int i; int n; if (a->c & 1) { t = *a; t.n[t.c++] = 0; return cvs_same_branch(&t, b); } if (b->c & 1) { t = *b; t.n[t.c++] = 0; return cvs_same_branch(a, &t); } if (a->c != b->c) return false; /* * Everything on x.y is trunk */ if (a->c == 2) return true; n = a->c; for (i = 0; i < n - 1; i++) { int an, bn; an = a->n[i]; bn = b->n[i]; /* * deal with n.m.0.p branch numbering */ if (i == n - 2) { if (an == 0) an = a->n[i+1]; if (bn == 0) bn = b->n[i+1]; } if (an != bn) return false; } return true; }
static rev_ref * rev_list_find_branch (rev_list *rl, cvs_number *number) { cvs_number n; rev_ref *h; if (number->c < 2) return NULL; n = *number; h = NULL; while (n.c >= 2) { for (h = rl->heads; h; h = h->next) { if (cvs_same_branch (&h->number, &n)) { break; } } if (h) break; n.c -= 2; } return h; }
static void rev_list_set_refs (rev_list *rl, cvs_file *cvs) { rev_ref *h; cvs_symbol *s; rev_commit *c; /* * Locate a symbolic name for this head */ for (s = cvs->symbols; s; s = s->next) { c = NULL; if (cvs_is_head (&s->number)) { for (h = rl->heads; h; h = h->next) { if (cvs_same_branch (&h->commit->file->number, &s->number)) break; } if (h) { if (!h->name) { h->name = s->name; h->degree = cvs_number_degree (&s->number); } else h = rev_list_add_head (rl, h->commit, s->name, cvs_number_degree (&s->number)); } else { cvs_number n; n = s->number; while (n.c >= 4) { n.c -= 2; c = rev_find_cvs_commit (rl, &n); if (c) break; } if (c) h = rev_list_add_head (rl, c, s->name, cvs_number_degree (&s->number)); } if (h) h->number = s->number; } else { c = rev_find_cvs_commit (rl, &s->number); if (c) tag_commit(c, s->name); } } /* * Fix up unnamed heads */ for (h = rl->heads; h; h = h->next) { cvs_number n; rev_commit *c; if (h->name) continue; for (c = h->commit; c; c = c->parent) { if (c->nfiles) break; } if (!c) continue; n = c->file->number; /* convert to branch form */ n.n[n.c-1] = n.n[n.c-2]; n.n[n.c-2] = 0; h->number = n; h->degree = cvs_number_degree (&n); /* compute name after patching parents */ } /* * Link heads together in a tree */ for (h = rl->heads; h; h = h->next) { cvs_number n; if (h->number.c >= 4) { n = h->number; n.c -= 2; h->parent = rev_list_find_branch (rl, &n); if (!h->parent && ! cvs_is_vendor (&h->number)) fprintf (stderr, "Warning: %s: branch %s has no parent\n", cvs->name, h->name); } if (h->parent && !h->name) { char name[1024]; char rev[CVS_MAX_REV_LEN]; cvs_number_string (&h->number, rev); fprintf (stderr, "Warning: %s: unnamed branch %s from %s\n", cvs->name, rev, h->parent->name); sprintf (name, "%s-UNNAMED-BRANCH", h->parent->name); h->name = atom (name); } } }