Disable --follow in `git log` to avoid loading duplicate commit data in infinite scroll
git
doesn't work properly when --follow
and --skip
are specified together. We could even be omitting commits in the Web log as a result.
Here are the gory details. Let's say you ran:
git log -n=5 --skip=2 README
This is the working case since it omits --follow
. This is what happens:
-
git
starts atHEAD
and traverses down the tree until it finds the top-most commit relevant to README. - Once this is found, this commit is returned via
get_revision_1()
. - If the
skip_count
is positive, decrement and repeat step 2. Otherwise go onto step 4. -
show_log()
gets called with that commit. - Repeat step 1 until we have all five entries.
That's exactly what we want. What happens when you use --follow
? You have to understand how step 1 is performed:
- When you specify a pathspec on the command-line (e.g. README), a flag
prune
gets set here. - If the
prune
flag is active,get_commit_action()
determines whether the commit should be scanned for matching paths. - In the case of
--follow
, however,prune
is disabled here. - As a result, a commit is never scanned for matching paths and therefore never pruned.
HEAD
will always get returned as the first commit, even if it's not relevant to the README. - Making matters worse, the
--skip
in the example above would actually skip a every other entry afterHEAD
N times. If README were changed in these skipped commits, we would actually miss information!
Since git uses a matching algorithm to determine whether a file was renamed, I
believe git
needs to generate a diff of each commit to do this and traverse
each commit one-by-one to do this. I think that's the rationale for disabling
the prune
functionality since you can't just do a simple string comparison.
Closes #4181 (closed), #4229 (closed), #3574 (closed), #2410 (closed)