if (!t1)
return 0;
- tree = read_object_with_reference(t1->object.sha1, "tree", &real.size, NULL);
+ tree = read_object_with_reference(t1->object.sha1, tree_type, &real.size, NULL);
if (!tree)
return 0;
real.buf = tree;
{
struct commit_list *parent = commit->parents;
+ if (commit->object.flags & ADDED)
+ return;
+ commit->object.flags |= ADDED;
+
/*
* If the commit is uninteresting, don't try to
* prune parents - we want the maximal uninteresting
continue;
p = &commit_list_insert(commit, p)->next;
}
+ if (revs->boundary) {
+ /* mark the ones that are on the result list first */
+ for (list = newlist; list; list = list->next) {
+ struct commit *commit = list->item;
+ commit->object.flags |= TMP_MARK;
+ }
+ for (list = newlist; list; list = list->next) {
+ struct commit *commit = list->item;
+ struct object *obj = &commit->object;
+ struct commit_list *parent;
+ if (obj->flags & UNINTERESTING)
+ continue;
+ for (parent = commit->parents;
+ parent;
+ parent = parent->next) {
+ struct commit *pcommit = parent->item;
+ if (!(pcommit->object.flags & UNINTERESTING))
+ continue;
+ pcommit->object.flags |= BOUNDARY;
+ if (pcommit->object.flags & TMP_MARK)
+ continue;
+ pcommit->object.flags |= TMP_MARK;
+ p = &commit_list_insert(pcommit, p)->next;
+ }
+ }
+ for (list = newlist; list; list = list->next) {
+ struct commit *commit = list->item;
+ commit->object.flags &= ~TMP_MARK;
+ }
+ }
revs->commits = newlist;
}
}
if (!strncmp(arg, "--max-age=", 10)) {
revs->max_age = atoi(arg + 10);
- revs->limited = 1;
- continue;
- }
- if (!strncmp(arg, "--min-age=", 10)) {
- revs->min_age = atoi(arg + 10);
- revs->limited = 1;
continue;
}
if (!strncmp(arg, "--since=", 8)) {
revs->max_age = approxidate(arg + 8);
- revs->limited = 1;
continue;
}
if (!strncmp(arg, "--after=", 8)) {
revs->max_age = approxidate(arg + 8);
- revs->limited = 1;
+ continue;
+ }
+ if (!strncmp(arg, "--min-age=", 10)) {
+ revs->min_age = atoi(arg + 10);
continue;
}
if (!strncmp(arg, "--before=", 9)) {
revs->min_age = approxidate(arg + 9);
- revs->limited = 1;
continue;
}
if (!strncmp(arg, "--until=", 8)) {
revs->min_age = approxidate(arg + 8);
- revs->limited = 1;
continue;
}
if (!strcmp(arg, "--all")) {
}
if (!strcmp(arg, "--topo-order")) {
revs->topo_order = 1;
- revs->limited = 1;
continue;
}
if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
- revs->limited = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--parents")) {
+ revs->parents = 1;
continue;
}
if (!strcmp(arg, "--dense")) {
revs->remove_empty_trees = 1;
continue;
}
- if (!strncmp(arg, "--no-merges", 11)) {
+ if (!strcmp(arg, "--no-merges")) {
revs->no_merges = 1;
continue;
}
+ if (!strcmp(arg, "--boundary")) {
+ revs->boundary = 1;
+ continue;
+ }
if (!strcmp(arg, "--objects")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
}
if (!strcmp(arg, "--unpacked")) {
revs->unpacked = 1;
- revs->limited = 1;
continue;
}
*unrecognized++ = arg;
dotdot = strstr(arg, "..");
if (dotdot) {
unsigned char from_sha1[20];
- char *next = dotdot + 2;
+ const char *next = dotdot + 2;
+ const char *this = arg;
*dotdot = 0;
if (!*next)
next = "HEAD";
- if (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {
+ if (dotdot == arg)
+ this = "HEAD";
+ if (!get_sha1(this, from_sha1) &&
+ !get_sha1(next, sha1)) {
struct commit *exclude;
struct commit *include;
- exclude = get_commit_reference(revs, arg, from_sha1, flags ^ UNINTERESTING);
+ exclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
include = get_commit_reference(revs, next, sha1, flags);
if (!exclude || !include)
die("Invalid revision range %s..%s", arg, next);
/* If we didn't have a "--", all filenames must exist */
for (j = i; j < argc; j++) {
if (lstat(argv[j], &st) < 0)
- die("'%s': %s", arg, strerror(errno));
+ die("'%s': %s", argv[j], strerror(errno));
}
revs->prune_data = get_pathspec(revs->prefix, argv + i);
break;
add_one_commit(commit, revs);
}
+ if (revs->topo_order || revs->unpacked)
+ revs->limited = 1;
+
if (revs->prune_data) {
diff_tree_setup_paths(revs->prune_data);
revs->prune_fn = try_to_simplify_commit;
- revs->limited = 1;
}
return left;
revs->topo_getter);
}
-static int rewrite_one(struct commit **pp)
+static int rewrite_one(struct rev_info *revs, struct commit **pp)
{
for (;;) {
struct commit *p = *pp;
+ if (!revs->limited)
+ add_parents_to_list(revs, p, &revs->commits);
if (p->object.flags & (TREECHANGE | UNINTERESTING))
return 0;
if (!p->parents)
}
}
-static void rewrite_parents(struct commit *commit)
+static void rewrite_parents(struct rev_info *revs, struct commit *commit)
{
struct commit_list **pp = &commit->parents;
while (*pp) {
struct commit_list *parent = *pp;
- if (rewrite_one(&parent->item) < 0) {
+ if (rewrite_one(revs, &parent->item) < 0) {
*pp = parent->next;
continue;
}
do {
struct commit *commit = revs->commits->item;
- if (commit->object.flags & (UNINTERESTING|SHOWN))
- goto next;
+ revs->commits = revs->commits->next;
+
+ /*
+ * If we haven't done the list limiting, we need to look at
+ * the parents here. We also need to do the date-based limiting
+ * that we'd otherwise have done in limit_list().
+ */
+ if (!revs->limited) {
+ if ((revs->unpacked &&
+ has_sha1_pack(commit->object.sha1)) ||
+ (revs->max_age != -1 &&
+ (commit->date < revs->max_age)))
+ continue;
+ add_parents_to_list(revs, commit, &revs->commits);
+ }
+ if (commit->object.flags & SHOWN)
+ continue;
+ if (!(commit->object.flags & BOUNDARY) &&
+ (commit->object.flags & UNINTERESTING))
+ continue;
if (revs->min_age != -1 && (commit->date > revs->min_age))
- goto next;
- if (revs->max_age != -1 && (commit->date < revs->max_age))
- return NULL;
- if (revs->no_merges && commit->parents && commit->parents->next)
- goto next;
+ continue;
+ if (revs->no_merges &&
+ commit->parents && commit->parents->next)
+ continue;
if (revs->prune_fn && revs->dense) {
if (!(commit->object.flags & TREECHANGE))
- goto next;
- rewrite_parents(commit);
+ continue;
+ if (revs->parents)
+ rewrite_parents(revs, commit);
}
- /* More to go? */
- if (revs->max_count)
- pop_most_recent_commit(&revs->commits, SEEN);
commit->object.flags |= SHOWN;
return commit;
-next:
- pop_most_recent_commit(&revs->commits, SEEN);
} while (revs->commits);
return NULL;
}