revision traversal: --remove-empty fix.
[git.git] / revision.c
index 713f27e..03085ff 100644 (file)
@@ -282,6 +282,7 @@ static int same_tree_as_empty(struct tree *t1)
 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;
@@ -296,31 +297,43 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
        while ((parent = *pp) != NULL) {
                struct commit *p = parent->item;
 
-               if (p->object.flags & UNINTERESTING) {
-                       pp = &parent->next;
-                       continue;
-               }
-
                parse_commit(p);
                switch (compare_tree(p->tree, commit->tree)) {
                case 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 TREE_NEW:
-                       if (revs->remove_empty_trees && same_tree_as_empty(p->tree)) {
-                               *pp = parent->next;
-                               continue;
+                       if (revs->remove_empty_trees &&
+                           same_tree_as_empty(p->tree)) {
+                               /* We are adding all the specified paths from
+                                * this parent, so the parents of it is
+                                * not interesting, but the difference between
+                                * this parent and us still is interesting.
+                                */
+                               p->object.flags |= UNINTERESTING;
                        }
                /* fallthrough */
                case TREE_DIFFERENT:
+                       tree_changed = 1;
                        pp = &parent->next;
                        continue;
                }
                die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
        }
-       commit->object.flags |= TREECHANGE;
+       if (tree_changed)
+               commit->object.flags |= TREECHANGE;
 }
 
 static void add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)