Reimplement commit 4b7f53da on top of the new simplify-merges
infrastructure, tightening the condition to only consider root parents;
the original version incorrectly dropped parents that were TREESAME to
anything.
Original log message follows.
The merge simplification rule stated in 6546b59 (revision traversal:
show full history with merge simplification, 2008-07-31) still
treated merge commits too specially. Namely, in a history with this
shape:
---o---o---M
/
x---x---x
where three 'x' were on a history completely unrelated to the main
history 'o' and do not touch any of the paths we are following, we
still said that after simplifying all of the parents of M, 'x'
(which is the leftmost 'x' that rightmost 'x simplifies down to) and
'o' (which would be the last commit on the main history that touches
the paths we are following) are independent from each other, and
both need to be kept.
That is incorrect; when the side branch 'x' never touches the paths,
it should be removed to allow M to simplify down to the last commit
on the main history that touches the paths.
Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Kevin Bracey <kevin@bracey.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Kevin Bracey reports that the change regresses a case shown in the
user manual.
Trading one fix with another breakage is not worth it. Just keep
the test to document the existing breakage, and revert the change
for now.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The --simplify-merges logic did not cull irrelevant parents from a
merge that is otherwise not interesting with respect to the paths
we are following.
This touches a fairly core part of the revision traversal
infrastructure; even though I think this change is correct, please
report immediately if you find any unintended side effect.
* jc/remove-treesame-parent-in-simplify-merges:
simplify-merges: drop merge from irrelevant side branch
The merge simplification rule stated in 6546b59 (revision traversal:
show full history with merge simplification, 2008-07-31) still
treated merge commits too specially. Namely, in a history with this
shape:
---o---o---M
/
x---x---x
where three 'x' were on a history completely unrelated to the main
history 'o' and do not touch any of the paths we are following, we
still said that after simplifying all of the parents of M, 'x'
(which is the leftmost 'x' that rightmost 'x simplifies down to) and
'o' (which would be the last commit on the main history that touches
the paths we are following) are independent from each other, and
both need to be kept.
That is incorrect; when the side branch 'x' never touches the paths,
it should be removed to allow M to simplify down to the last commit
on the main history that touches the paths.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
In a topic branch workflow, you often want to find the latest commit that
merged a side branch that touched a particular area of the system, so that
a new topic branch to work on that area can be forked from that commit.
For example, I wanted to find an appropriate fork-point to queue Luke's
changes related to git-p4 in contrib/fast-import/.
"git log --first-parent" traverses the first-parent chain, and "-m --stat"
shows the list of paths touched by commits including merge commits. We
could ask the question this way:
# What is the latest commit that touched that path?
$ git log --first-parent --oneline -m --stat master |
sed -e '/^ contrib\/fast-import\/git-p4 /q' | tail
The above finds that 8cbfc11 (Merge branch 'pw/p4-view-updates',
2012-01-06) was such a commit.
But a more natural way to spell this question is this:
$ git log --first-parent --oneline -m --stat -1 master -- \
contrib/fast-import/git-p4
Unfortunately, this does not work. It finds ecb7cf9 (git-p4: rewrite view
handling, 2012-01-02). This commit is a part of the merged topic branch
and is _not_ on the first-parent path from the 'master':
$ git show-branch 8cbfc11ecb7cf9
! [8cbfc11] Merge branch 'pw/p4-view-updates'
! [ecb7cf9] git-p4: rewrite view handling
--
- [8cbfc11] Merge branch 'pw/p4-view-updates'
+ [8cbfc11^2] git-p4: view spec documentation
++ [ecb7cf9] git-p4: rewrite view handling
The problem is caused by the merge simplification logic when it inspects
the merge commit 8cbfc11. In this case, the history leading to the tip of
'master' did not touch git-p4 since 'pw/p4-view-updates' topic forked, and
the result of the merge is simply a copy from the tip of the topic branch
in the view limited by the given pathspec. The merge simplification logic
discards the history on the mainline side of the merge, and pretends as if
the sole parent of the merge is its second parent, i.e. the tip of the
topic. While this simplification is correct in the general case, it is at
least surprising if not outright wrong when the user explicitly asked to
show the first-parent history.
Here is an attempt to fix this issue, by not allowing us to compare the
merge result with anything but the first parent when --first-parent is in
effect, to avoid the history traversal veering off to the side branch.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This makes the algorithm more honest about what it is doing.
We start from an already limited, topo-sorted list, and postprocess
it by simplifying the irrelevant merges away.
Signed-off-by: Junio C Hamano <gitster@pobox.com>