Exemple #1
0
static void
rev_commit_dump (FILE *f, char *title, rev_commit *c, rev_commit *m)
{
    fprintf (f, "\n%s\n", title);
    while (c) {
	int	i;

	fprintf (f, "%c0x%x %s\n", c == m ? '>' : ' ',
		(int) c, ctime_nonl (&c->date));
	for (i = 0; i < c->nfiles; i++) {
	    fprintf (f, "\t%s", ctime_nonl (&c->files[i]->date));
	    dump_number_file (f, c->files[i]->name, &c->files[i]->number);
	    fprintf (f, "\n");
	}
	fprintf (f, "\n");
	c = c->parent;
    }
}
Exemple #2
0
static void dot_commit_graph(git_commit *c, rev_ref *branch)
{
    rev_file	*f;

    printf("\"");
    if (branch)
	dot_ref_name(stdout, branch);
//    if (c->tail)
//	printf("*** TAIL");
    printf("\\n");
    printf("%s\\n", ctime_nonl(&c->date));
    dump_log(stdout, c->log);
    printf("\\n");
    if (difffiles) {
	rev_diff    *diff = git_commit_diff(c->parent, c);
	rev_file_list   *fl;

	for (fl = diff->add; fl; fl = fl->next) {
	    if (!rev_file_list_has_filename(diff->del, fl->file->file_name)) {
		printf("+");
		dump_number(fl->file->file_name, &fl->file->number);
		printf("\\n");
	    }
	}
	for (fl = diff->add; fl; fl = fl->next) {
	    if (rev_file_list_has_filename(diff->del, fl->file->file_name)) {
		printf("|");
		dump_number(fl->file->file_name, &fl->file->number);
		printf("\\n");
	    }
	}
	for (fl = diff->del; fl; fl = fl->next) {
	    if (!rev_file_list_has_filename(diff->add, fl->file->file_name)) {
		printf("-");
		dump_number(fl->file->file_name, &fl->file->number);
		printf("\\n");
	    }
	}
	rev_diff_free(diff);
    } else {
	int		i, j;
	for (i = 0; i < c->ndirs; i++) {
	    rev_dir *dir = c->dirs[i];
	    for (j = 0; j < dir->nfiles; j++) {
		 f = dir->files[j];
		 dump_number(f->file_name, &f->number);
		 printf("\\n");
	    }
	}
    }
    printf("%p", c);
    printf("\"");
}
Exemple #3
0
/*
 * Merge a set of per-file branches into a global branch
 */
static void
rev_branch_merge (rev_ref **branches, int nbranch,
		  rev_ref *branch, rev_list *rl)
{
	int nlive;
	int n;
	rev_commit *prev = NULL;
	rev_commit *head = NULL, **tail = &head;
	rev_commit **commits;
	rev_commit *commit;
	rev_commit *latest;
	rev_commit **p;
	int lazy = 0;
	time_t start = 0;

	ALLOC((commits = calloc (nbranch, sizeof (rev_commit *))), "rev_branch_merge");
	nlive = 0;

//	printf("rev_branch_merge: nbranch=%d\n", nbranch);
	
	for (n = 0; n < nbranch; n++) {
		rev_commit *c;
		/*
		 * Initialize commits to head of each branch
		 */
		c = commits[n] = branches[n]->commit;
		/*
		* Compute number of branches with remaining entries
		*/
		if (!c)
			continue;
		if (branches[n]->tail) {
			c->tailed = 1;
			continue;
		}
		nlive++;
		while (c && !c->tail) {
			if (!start || time_compare(c->date, start) < 0)
			    {
//				printf("  1:setting start=%ld:%s (from %s)\n", start, ctime_nonl(&start), c->file->name);
				start = c->date;
			    }
			c = c->parent;
		}
		if (c && (c->file || c->date != c->parent->date)) {
			if (!start || time_compare(c->date, start) < 0) {
//				printf("  2:setting start=%ld:%s (from %s)\n", start, ctime_nonl(&start), c->file->name);
				start = c->date;
			}
		}
	}

	for (n = 0; n < nbranch; n++) {
		rev_commit *c = commits[n];

#if 0
		printf("Doing commit %p: @ %ld\n", c, c->date);
		if (c->file) printf("  %s\n", c->file->name);
#endif
		
		if (!c->tailed)
			continue;
		if (!start || time_compare(start, c->date) >= 0)
			continue;
		if (c->file) {
		    /*
		      This case can occur if files have been added to
		      a branch since it's creation.
		    */
			printf(	"Warning: %s too late date %s through branch %s (%ld:%ld=%ld)\n",
				c->file->name, ctime_nonl(&c->date), branch->name, start, c->date, start-c->date);
			continue;
		}
		commits[n] = NULL;
	}
	/*
	 * Walk down branches until each one has merged with the
	 * parent branch
	 */
	while (nlive > 0 && nbranch > 0) {
		for (n = 0, p = commits, latest = NULL; n < nbranch; n++) {
			rev_commit *c = commits[n];
			if (!c)
				continue;
			*p++ = c;
			if (c->tailed)
				continue;
			if (!latest || time_compare(latest->date, c->date) < 0)
				latest = c;
		}
		nbranch = p - commits;

		/*
		 * Construct current commit
		 */
		if (!lazy) {
			commit = rev_commit_build (commits, latest, nbranch);
			if (rev_mode == ExecuteGit)
				lazy = 1;
		} else {
			commit = create_tree(latest);
		}

		/*
		 * Step each branch
		 */
		nlive = 0;
		for (n = 0; n < nbranch; n++) {
			rev_commit *c = commits[n];
			rev_commit *to;
			/* already got to parent branch? */
			if (c->tailed)
				continue;
			/* not affected? */
			if (c != latest && !rev_commit_match(c, latest)) {
				if (c->parent || c->file)
					nlive++;
				continue;
			}
			to = c->parent;
			/* starts here? */
			if (!to)
				goto Kill;

			if (c->tail) {
				/*
				 * Adding file independently added on another
				 * non-trunk branch.
				 */
				if (!to->parent && !to->file)
					goto Kill;
				/*
				 * If the parent is at the beginning of trunk
				 * and it is younger than some events on our
				 * branch, we have old CVS adding file
				 * independently
				 * added on another branch.
				 */
				if (start && time_compare(start, to->date) < 0)
					goto Kill;
				/*
				 * XXX: we still can't be sure that it's
				 * not a file added on trunk after parent
				 * branch had forked off it but before
				 * our branch's creation.
				 */
				to->tailed = 1;
			} else if (to->file) {
				nlive++;
			} else {
				/*
				 * See if it's recent CVS adding a file
				 * independently added on another branch.
				 */
				if (!to->parent)
					goto Kill;
				if (to->tail && to->date == to->parent->date)
					goto Kill;
				nlive++;
			}
			if (to->file)
				set_commit(to);
			else
				delete_commit(c);
			commits[n] = to;
			continue;
Kill:
			delete_commit(c);
			commits[n] = NULL;
		}

		*tail = commit;
		tail = &commit->parent;
		prev = commit;
	}
    /*
     * Connect to parent branch
     */
    nbranch = rev_commit_date_sort (commits, nbranch);
    if (nbranch && branch->parent )
    {
	rev_ref	*lost;
	int	present;

//	present = 0;
	for (present = 0; present < nbranch; present++)
	    if (commits[present]->file) {
		/*
		 * Skip files which appear in the repository after
		 * the first commit along the branch
		 */
		if (prev && commits[present]->date > prev->date &&
		    commits[present]->date == rev_commit_first_date (commits[present]))
		{
		    fprintf (stderr, "Warning: file %s appears after branch %s date\n",
			     commits[present]->file->name, branch->name);
		    continue;
		}
		break;
	    }
	if (present == nbranch)
	    *tail = NULL;
	else if ((*tail = rev_commit_locate_one (branch->parent,
						 commits[present])))
	{
	    if (prev && time_compare ((*tail)->date, prev->date) > 0) {
		fprintf (stderr, "Warning: branch point %s -> %s later than branch\n",
			 branch->name, branch->parent->name);
		fprintf (stderr, "\ttrunk(%3d):  %s %s", n,
			 ctime_nonl (&commits[present]->date),
			 commits[present]->file ? " " : "D" );
		if (commits[present]->file)
		    dump_number_file (stderr,
				      commits[present]->file->name,
				      &commits[present]->file->number);
		fprintf (stderr, "\n");
		fprintf (stderr, "\tbranch(%3d): %s  ", n,
			 prev->file?ctime_nonl (&prev->file->date):"no file");
		if (prev->file) {
		    dump_number_file (stderr,
				  prev->file->name,
				  &prev->file->number);
		}
		fprintf (stderr, "\n");
	    }
	} else if ((*tail = rev_commit_locate_date (branch->parent,
						  commits[present]->date)))
	    fprintf (stderr, "Warning: branch point %s -> %s matched by date\n",
		     branch->name, branch->parent->name);
	else {
	    fprintf (stderr, "Error: branch point %s -> %s not found.",
		     branch->name, branch->parent->name);

	    if ((lost = rev_branch_of_commit (rl, commits[present])))
		fprintf (stderr, " Possible match on %s.", lost->name);
	    fprintf (stderr, "\n");
	}
	if (*tail) {
	    if (prev)
		prev->tail = 1;
	} else 
	    *tail = rev_commit_build (commits, commits[0], nbranch);
    }
    for (n = 0; n < nbranch; n++)
	if (commits[n])
	    commits[n]->tailed = 0;
    free (commits);
    branch->commit = head;
}