зеркало из https://github.com/microsoft/git.git
Making pathspec limited log play nicer with --first-parent
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 that8cbfc11
(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 findsecb7cf9
(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-branch8cbfc11
ecb7cf9
! [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 commit8cbfc11
. 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 commit is contained in:
Родитель
04f6785a08
Коммит
36ed1913e1
10
revision.c
10
revision.c
|
@ -368,7 +368,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
|
|||
static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
{
|
||||
struct commit_list **pp, *parent;
|
||||
int tree_changed = 0, tree_same = 0;
|
||||
int tree_changed = 0, tree_same = 0, nth_parent = 0;
|
||||
|
||||
/*
|
||||
* If we don't do pruning, everything is interesting
|
||||
|
@ -396,6 +396,14 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
|
|||
while ((parent = *pp) != NULL) {
|
||||
struct commit *p = parent->item;
|
||||
|
||||
/*
|
||||
* Do not compare with later parents when we care only about
|
||||
* the first parent chain, in order to avoid derailing the
|
||||
* traversal to follow a side branch that brought everything
|
||||
* in the path we are limited to by the pathspec.
|
||||
*/
|
||||
if (revs->first_parent_only && nth_parent++)
|
||||
break;
|
||||
if (parse_commit(p) < 0)
|
||||
die("cannot simplify commit %s (because of %s)",
|
||||
sha1_to_hex(commit->object.sha1),
|
||||
|
|
|
@ -86,5 +86,6 @@ check_result 'I H E C B A' --full-history --date-order -- file
|
|||
check_result 'I E C B A' --simplify-merges -- file
|
||||
check_result 'I B A' -- file
|
||||
check_result 'I B A' --topo-order -- file
|
||||
check_result 'H' --first-parent -- another-file
|
||||
|
||||
test_done
|
||||
|
|
Загрузка…
Ссылка в новой задаче