예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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);
	}
    }
}