+ int retval;
+ void *tree;
+ struct tree_desc empty, real;
+
+ if (!t1)
+ return 0;
+
+ tree = read_object_with_reference(t1->object.sha1, tree_type, &real.size, NULL);
+ if (!tree)
+ return 0;
+ real.buf = tree;
+
+ empty.buf = "";
+ empty.size = 0;
+
+ tree_difference = 0;
+ retval = diff_tree(&empty, &real, "", &revs->pruning);
+ free(tree);
+
+ return retval >= 0 && !tree_difference;
+}
+
+static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
+{
+ struct commit_list **pp, *parent;
+ int tree_changed = 0;
+
+ if (!commit->tree)
+ return;
+
+ if (!commit->parents) {
+ if (!rev_same_tree_as_empty(revs, commit->tree))
+ commit->object.flags |= TREECHANGE;
+ return;
+ }
+
+ pp = &commit->parents;
+ while ((parent = *pp) != NULL) {
+ struct commit *p = parent->item;
+
+ parse_commit(p);
+ switch (rev_compare_tree(revs, p->tree, commit->tree)) {
+ case REV_TREE_SAME:
+ if (p->object.flags & UNINTERESTING) {
+ /* Even if a merge with an uninteresting
+ * side branch brought the entire change
+ * we are interested in, we do not want
+ * to lose the other branches of this
+ * merge, so we just keep going.
+ */
+ pp = &parent->next;
+ continue;
+ }
+ parent->next = NULL;
+ commit->parents = parent;
+ return;
+
+ case REV_TREE_NEW:
+ if (revs->remove_empty_trees &&
+ rev_same_tree_as_empty(revs, p->tree)) {
+ /* We are adding all the specified
+ * paths from this parent, so the
+ * history beyond this parent is not
+ * interesting. Remove its parents
+ * (they are grandparents for us).
+ * IOW, we pretend this parent is a
+ * "root" commit.
+ */
+ parse_commit(p);
+ p->parents = NULL;
+ }
+ /* fallthrough */
+ case REV_TREE_DIFFERENT:
+ tree_changed = 1;
+ pp = &parent->next;
+ continue;
+ }
+ die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
+ }
+ if (tree_changed)
+ commit->object.flags |= TREECHANGE;
+}
+
+static void add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
+{
+ 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
+ * set.
+ *
+ * Normally we haven't parsed the parent
+ * yet, so we won't have a parent of a parent
+ * here. However, it may turn out that we've
+ * reached this commit some other way (where it
+ * wasn't uninteresting), in which case we need
+ * to mark its parents recursively too..
+ */
+ if (commit->object.flags & UNINTERESTING) {
+ while (parent) {
+ struct commit *p = parent->item;
+ parent = parent->next;
+ parse_commit(p);
+ p->object.flags |= UNINTERESTING;
+ if (p->parents)
+ mark_parents_uninteresting(p);
+ if (p->object.flags & SEEN)
+ continue;
+ p->object.flags |= SEEN;
+ insert_by_date(p, list);
+ }
+ return;
+ }
+
+ /*
+ * Ok, the commit wasn't uninteresting. Try to
+ * simplify the commit history and find the parent
+ * that has no differences in the path set if one exists.
+ */
+ if (revs->prune_fn)
+ revs->prune_fn(revs, commit);
+
+ if (revs->no_walk)