return CONTINUE;
if (max_age != -1 && (commit->date < max_age)) {
stop_traversal=1;
- return merge_order?CONTINUE:STOP;
+ return CONTINUE;
}
if (max_count != -1 && !max_count--)
return STOP;
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
p = add_object(obj, p, name);
- for (entry = tree->entries ; entry ; entry = entry->next) {
+ entry = tree->entries;
+ tree->entries = NULL;
+ while (entry) {
+ struct tree_entry_list *next = entry->next;
if (entry->directory)
p = process_tree(entry->item.tree, p, entry->name);
else
p = process_blob(entry->item.blob, p, entry->name);
+ free(entry);
+ entry = next;
}
return p;
}
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
}
while (objects) {
- printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name);
+ /* An object with name "foo\n0000000000000000000000000000000000000000"
+ * can be used confuse downstream git-pack-objects very badly.
+ */
+ const char *ep = strchr(objects->name, '\n');
+ if (ep) {
+ printf("%s %.*s\n", sha1_to_hex(objects->item->sha1),
+ (int) (ep - objects->name),
+ objects->name);
+ }
+ else
+ printf("%s %s\n", sha1_to_hex(objects->item->sha1), objects->name);
objects = objects->next;
}
}
if (parse_tree(tree) < 0)
die("bad tree %s", sha1_to_hex(obj->sha1));
entry = tree->entries;
+ tree->entries = NULL;
while (entry) {
+ struct tree_entry_list *next = entry->next;
if (entry->directory)
mark_tree_uninteresting(entry->item.tree);
else
mark_blob_uninteresting(entry->item.blob);
- entry = entry->next;
+ free(entry);
+ entry = next;
}
}
{
struct commit_list *parents = commit->parents;
- if (tree_objects)
- mark_tree_uninteresting(commit->tree);
while (parents) {
struct commit *commit = parents->item;
commit->object.flags |= UNINTERESTING;
continue;
return 0;
}
-
- /*
- * Ok, go back and mark all the edge trees uninteresting,
- * since otherwise we can have situations where a parent
- * that was marked uninteresting (and we never even had
- * to look at) had lots of objects that we don't want to
- * include.
- *
- * NOTE! This still doesn't mean that the object list is
- * "correct", since we may end up listing objects that
- * even older commits (that we don't list) do actually
- * reference, but it gets us to a minimal list (or very
- * close) in practice.
- */
- if (!tree_objects)
- return 1;
-
- while (orig) {
- struct commit *commit = orig->item;
- if (!parse_commit(commit) && commit->tree)
- mark_tree_uninteresting(commit->tree);
- orig = orig->next;
- }
return 1;
}
return best;
}
+static void mark_edges_uninteresting(struct commit_list *list)
+{
+ for ( ; list; list = list->next) {
+ struct commit_list *parents = list->item->parents;
+
+ for ( ; parents; parents = parents->next) {
+ struct commit *commit = parents->item;
+ if (commit->object.flags & UNINTERESTING)
+ mark_tree_uninteresting(commit->tree);
+ }
+ }
+}
+
static struct commit_list *limit_list(struct commit_list *list)
{
struct commit_list *newlist = NULL;
struct commit *commit = pop_most_recent_commit(&list, SEEN);
struct object *obj = &commit->object;
+ if (max_age != -1 && (commit->date < max_age))
+ obj->flags |= UNINTERESTING;
if (unpacked && has_sha1_pack(obj->sha1))
obj->flags |= UNINTERESTING;
if (obj->flags & UNINTERESTING) {
break;
continue;
}
+ if (min_age != -1 && (commit->date > min_age))
+ continue;
p = &commit_list_insert(commit, p)->next;
}
+ if (tree_objects)
+ mark_edges_uninteresting(newlist);
if (bisect_list)
newlist = find_bisection(newlist);
return newlist;
}
if (!strncmp(arg, "--max-age=", 10)) {
max_age = atoi(arg + 10);
+ limited = 1;
continue;
}
if (!strncmp(arg, "--min-age=", 10)) {
min_age = atoi(arg + 10);
+ limited = 1;
continue;
}
if (!strcmp(arg, "--header")) {
struct commit *exclude = NULL;
struct commit *include = NULL;
*dotdot = 0;
+ if (!*next)
+ next = "HEAD";
exclude = get_commit_reference(arg, UNINTERESTING);
include = get_commit_reference(next, 0);
if (exclude && include) {
handle_one_commit(include, &list);
continue;
}
- *next = '.';
+ *dotdot = '.';
}
if (*arg == '^') {
flags = UNINTERESTING;
}
save_commit_buffer = verbose_header;
+ track_object_refs = 0;
if (!merge_order) {
sort_by_date(&list);