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:
-
gitstarts atHEADand 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_countis 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
prunegets set here. - If the
pruneflag is active,get_commit_action()determines whether the commit should be scanned for matching paths. - In the case of
--follow, however,pruneis disabled here. - As a result, a commit is never scanned for matching paths and therefore never pruned.
HEADwill always get returned as the first commit, even if it's not relevant to the README. - Making matters worse, the
--skipin the example above would actually skip a every other entry afterHEADN 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)