On Thu, Jun 22, 2017 at 05:52:35PM -0400, Jeff King wrote:
> Which really makes me feel like this patch is going in the right
> direction, as it makes all of this behave conceptually like:
>
> while read old new etc ...
> do
> git show $new
> done <.git/logs/$ref
>
> which is simple to explain and is what I'd expect (and is certainly the
> direction we went with the "diff uses real parents" commit).
>
> We just need to hit the simplify_commit() code path here.
So here's a patch on top of what I posted before that pushes the reflog
check into the loop (it just decides whether to pull from the reflogs or
from the commit queue at the top of the loop).
I was surprised to find, though, that simplify_commit() does not
actually do the pathspec limiting! It's done by
try_to_simplify_commit(), which is part of add_parents_to_list(). I
hacked around it in the later part of the loop by calling
try_to_simplify myself and checking the TREESAME flag. But I have a
feeling I'm missing something about how the traversal is supposed to
work.
This does behave sensibly with "--no-merges" and "--merges", as well as
pathspec limiting.
diff --git a/revision.c b/revision.c
index 675247cd9..203468ddf 100644
--- a/revision.c
+++ b/revision.c
@@ -3112,19 +3112,19 @@ static void track_linear(struct rev_info *revs, struct
commit *commit)
static struct commit *get_revision_1(struct rev_info *revs)
{
- if (revs->reflog_info) {
- struct commit *commit = next_reflog_entry(revs->reflog_info);
- if (commit) {
- commit->object.flags &= ~(ADDED | SEEN | SHOWN);
- return commit;
- }
- }
+ while (1) {
+ struct commit *commit;
- if (!revs->commits)
- return NULL;
+ if (revs->reflog_info)
+ commit = next_reflog_entry(revs->reflog_info);
+ else
+ commit = pop_commit(&revs->commits);
- do {
- struct commit *commit = pop_commit(&revs->commits);
+ if (!commit)
+ return NULL;
+
+ if (revs->reflog_info)
+ commit->object.flags &= ~(ADDED | SEEN | SHOWN);
/*
* If we haven't done the list limiting, we need to look at
@@ -3135,7 +3135,8 @@ static struct commit *get_revision_1(struct rev_info
*revs)
if (revs->max_age != -1 &&
(commit->date < revs->max_age))
continue;
- if (add_parents_to_list(revs, commit, &revs->commits,
NULL) < 0) {
+ if (!revs->reflog_info &&
+ add_parents_to_list(revs, commit, &revs->commits,
NULL) < 0) {
if (!revs->ignore_missing_links)
die("Failed to traverse parents of
commit %s",
oid_to_hex(&commit->object.oid));
@@ -3151,10 +3152,14 @@ static struct commit *get_revision_1(struct rev_info
*revs)
default:
if (revs->track_linear)
track_linear(revs, commit);
+ if (revs->reflog_info) {
+ try_to_simplify_commit(revs, commit);
+ if (commit->object.flags & TREESAME)
+ continue;
+ }
return commit;
}
- } while (revs->commits);
- return NULL;
+ }
}
/*