revision: propagate flag bits from tags to pointees

With the previous fix 895c5ba3 (revision: do not peel tags used in range notation, 2013-09-19), handle_revision_arg() that processes command line arguments for the "git log" family of commands no longer directly places the object pointed by the tag in the pending object array when it sees a tag object. We used to place pointee there after copying the flag bits like UNINTERESTING and SYMMETRIC_LEFT. This change meant that any flag that is relevant to later history traversal must now be propagated to the pointed objects (most often these are commits) while starting the traversal, which is partly done by handle_commit() that is called from prepare_revision_walk(). We did propagate UNINTERESTING, but did not do so for others, most notably SYMMETRIC_LEFT. This caused "git log --left-right v1.0..." (where "v1.0" is a tag) to start losing the "leftness" from the commit the tag points at. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jan 15, 2014 at 12:26 UTC a74352867e689d50ee9c368f24d4a64392e27a35
2 files changed +13 -6
revision.c
+2 -6
@@ -273,6 +273,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
273 return NULL;
274 die("bad object %s", sha1_to_hex(tag->tagged->sha1));
275 }
276 + object->flags |= flags;
277 }
278
279 /*
@@ -284,7 +285,6 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
285 if (parse_commit(commit) < 0)
286 die("unable to parse commit %s", name);
287 if (flags & UNINTERESTING) {
287 - commit->object.flags |= UNINTERESTING;
288 mark_parents_uninteresting(commit);
289 revs->limited = 1;
290 }
@@ -302,7 +302,6 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
302 if (!revs->tree_objects)
303 return NULL;
304 if (flags & UNINTERESTING) {
305 - tree->object.flags |= UNINTERESTING;
305 mark_tree_contents_uninteresting(tree);
306 return NULL;
307 }
@@ -314,13 +313,10 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
313 * Blob object? You know the drill by now..
314 */
315 if (object->type == OBJ_BLOB) {
317 - struct blob *blob = (struct blob *)object;
316 if (!revs->blob_objects)
317 return NULL;
320 - if (flags & UNINTERESTING) {
321 - blob->object.flags |= UNINTERESTING;
318 + if (flags & UNINTERESTING)
319 return NULL;
323 - }
320 add_pending_object(revs, object, "");
321 return NULL;
322 }
t/t6000-rev-list-misc.sh
+11
@@ -62,4 +62,15 @@ test_expect_success 'propagate uninteresting flag down correctly' '
62 test_cmp expect actual
63 '
64
65 +test_expect_success 'symleft flag bit is propagated down from tag' '
66 + git log --format="%m %s" --left-right v1.0...master >actual &&
67 + cat >expect <<-\EOF &&
68 + > two
69 + > one
70 + < another
71 + < that
72 + EOF
73 + test_cmp expect actual
74 +'
75 +
76 test_done