Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On Sun, May 12, 2013 at 10:02:39PM -0700, Junio C Hamano wrote: Kevin Bracey ke...@bracey.fi writes: On 12/05/2013 19:58, John Keeping wrote: With the patch below, the --ancestry-path version drops to under 2 seconds. I'm not sure if this is a good idea though. It helps me say I know nothing that isn't on the ancestry path can be patch-identical, so don't bother checking if it is but it regresses users who want the full cherry-pick check while only limiting the output. Hmm. Should an excluded commit be a valid comparator? Is it sensible/correct to show a left commit as = to a right commit that has been excluded by the revision specifiers? Doesn't sound right to me. Neither to me. OK. I'll add some tests and send a proper patch once 1.8.3 is out of the way. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On 13/05/2013 01:22, Junio C Hamano wrote: Kevin Bracey ke...@bracey.fi writes: git log --ancestry-path --left-right E...F --not $(git merge-base --all E F) which looks like we're having to repeat ourselves because it's not paying attention... You are half wrong; --left-right is about do we show the //= marker in the output?, so it is true that it does not make sense without ..., but the reverse is not true: A...B does not and should not imply --left-right. The repetition I meant is that by the definition of ancestry-path, the above would seem to be equivalent to git log --ancestry-path --left-right E F --not $(git merge-base --all E F) $(git merge-base --all E F) Anyway, revised separated-out version of the patch follows. Kevin -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
Kevin Bracey venit, vidit, dixit 13.05.2013 16:26: On 13/05/2013 01:22, Junio C Hamano wrote: Kevin Bracey ke...@bracey.fi writes: git log --ancestry-path --left-right E...F --not $(git merge-base --all E F) which looks like we're having to repeat ourselves because it's not paying attention... You are half wrong; --left-right is about do we show the //= marker in the output?, so it is true that it does not make sense without ..., but the reverse is not true: A...B does not and should not imply --left-right. The repetition I meant is that by the definition of ancestry-path, the above would seem to be equivalent to git log --ancestry-path --left-right E F --not $(git merge-base --all E F) $(git merge-base --all E F) Anyway, revised separated-out version of the patch follows. Kevin It is certainly true that git log --cherry needs much less information than what the merge base machinery provides. I've been experimenting with that in order to get the speedup which is necessary for replacing the git cherry code with calls into the revision walker using --cherry. But I can't wrap my head around the feature proposed here, sorry. Michael -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On 11/05/2013 15:23, John Keeping wrote: This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E Wouldn't --left-right --ancestry-path F...E do the job? I can't immediately see how that differs. Unfortunately, that syntax doesn't currently work - I just stumbled across this problem, and my history traversal refinements series in pu fixes it, somewhat incidentally to the main subject in there. However, without that patch, the alternative way of expressing it: --left-right --ancestry path F E --not $(git merge-base --all F E) should still work. Unless --left-right is magic for ...? If it is, then my patch is more significant than I thought. My series will also be better at optimising away D too, through a combination of my and Junio's efforts. Try it out. On this subject, is there any way to exclude a path from a log query? Is there a not operator for paths? Might be another way of doing this - disjoint histories probably have disjoint paths... Kevin -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On Sun, May 12, 2013 at 06:44:30PM +0300, Kevin Bracey wrote: On 11/05/2013 15:23, John Keeping wrote: This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E Wouldn't --left-right --ancestry-path F...E do the job? I can't immediately see how that differs. Unfortunately, that syntax doesn't currently work - I just stumbled across this problem, and my history traversal refinements series in pu fixes it, somewhat incidentally to the main subject in there. You're right (and I was wrong in my reply to Junio's parallel message) ancestry path does seem to be what I want: $ git rev-list --left-right --count master...git-gui/master 31959 5 $ git rev-list --ancestry-path --left-right --count \ master...git-gui/master 20565 $ git rev-list --ancestry-path --left-right --count \ master...git-gui/master \ --not $(git merge-base --all master git-gui/master) 20565 However, this doesn't seem to make a difference to the time taken when I add in --cherry-mark (which is why I was partially correct in the parallel thread - it doesn't have the effect on cherry-mark that I want it to): $ time git rev-list --ancestry-path --left-right --count --cherry-mark \ origin/master...git-gui/master 20565 0 real0m32.266s user0m31.522s sys 0m0.749s $ time git rev-list --left-right --count --cherry-mark \ origin/master...git-gui/master 31959 5 0 real0m32.140s user0m31.337s sys 0m0.807s This seems to be caused by the code in revision.c::limit_list() which does the cherry detection then limits to left/right and only then applies the ancestry path. I haven't looked further than that, but is there any reason not to apply the ancestry path restriction before looking for patch-identical commits? However, without that patch, the alternative way of expressing it: --left-right --ancestry path F E --not $(git merge-base --all F E) should still work. Unless --left-right is magic for ...? If it is, then my patch is more significant than I thought. Yes, --left-right only applies to symmetric differences (...). But I get the results above both on master and on pu. My series will also be better at optimising away D too, through a combination of my and Junio's efforts. Try it out. On this subject, is there any way to exclude a path from a log query? Is there a not operator for paths? Might be another way of doing this - disjoint histories probably have disjoint paths... That relates to another idea I had about optimizing the detection of patch-identical commits. If the smaller side of a symmetric difference is quite small (as it is likely to be if it's a topic branch), would it be a good idea to calculate the set of paths touched by commits on that side and then skip calculating the patch ID for any commits that touch paths outside that set. The tree comparison is a lot cheaper than doing a diff on all of the files. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On Sun, May 12, 2013 at 05:28:24PM +0100, John Keeping wrote: On Sun, May 12, 2013 at 06:44:30PM +0300, Kevin Bracey wrote: On 11/05/2013 15:23, John Keeping wrote: This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E Wouldn't --left-right --ancestry-path F...E do the job? I can't immediately see how that differs. Unfortunately, that syntax doesn't currently work - I just stumbled across this problem, and my history traversal refinements series in pu fixes it, somewhat incidentally to the main subject in there. You're right (and I was wrong in my reply to Junio's parallel message) ancestry path does seem to be what I want: $ git rev-list --left-right --count master...git-gui/master 31959 5 $ git rev-list --ancestry-path --left-right --count \ master...git-gui/master 20565 $ git rev-list --ancestry-path --left-right --count \ master...git-gui/master \ --not $(git merge-base --all master git-gui/master) 20565 However, this doesn't seem to make a difference to the time taken when I add in --cherry-mark (which is why I was partially correct in the parallel thread - it doesn't have the effect on cherry-mark that I want it to): $ time git rev-list --ancestry-path --left-right --count --cherry-mark \ origin/master...git-gui/master 20565 0 real0m32.266s user0m31.522s sys 0m0.749s $ time git rev-list --left-right --count --cherry-mark \ origin/master...git-gui/master 31959 5 0 real0m32.140s user0m31.337s sys 0m0.807s This seems to be caused by the code in revision.c::limit_list() which does the cherry detection then limits to left/right and only then applies the ancestry path. I haven't looked further than that, but is there any reason not to apply the ancestry path restriction before looking for patch-identical commits? However, without that patch, the alternative way of expressing it: --left-right --ancestry path F E --not $(git merge-base --all F E) should still work. Unless --left-right is magic for ...? If it is, then my patch is more significant than I thought. Yes, --left-right only applies to symmetric differences (...). But I get the results above both on master and on pu. No I didn't. I forgot to update my $PATH when I built on master - those results are from pu. master says: fatal: --ancestry-path given but there are no bottom commits My series will also be better at optimising away D too, through a combination of my and Junio's efforts. Try it out. On this subject, is there any way to exclude a path from a log query? Is there a not operator for paths? Might be another way of doing this - disjoint histories probably have disjoint paths... That relates to another idea I had about optimizing the detection of patch-identical commits. If the smaller side of a symmetric difference is quite small (as it is likely to be if it's a topic branch), would it be a good idea to calculate the set of paths touched by commits on that side and then skip calculating the patch ID for any commits that touch paths outside that set. The tree comparison is a lot cheaper than doing a diff on all of the files. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On Sun, May 12, 2013 at 05:28:24PM +0100, John Keeping wrote: However, this doesn't seem to make a difference to the time taken when I add in --cherry-mark (which is why I was partially correct in the parallel thread - it doesn't have the effect on cherry-mark that I want it to): $ time git rev-list --ancestry-path --left-right --count --cherry-mark \ origin/master...git-gui/master 20565 0 real0m32.266s user0m31.522s sys 0m0.749s $ time git rev-list --left-right --count --cherry-mark \ origin/master...git-gui/master 31959 5 0 real0m32.140s user0m31.337s sys 0m0.807s This seems to be caused by the code in revision.c::limit_list() which does the cherry detection then limits to left/right and only then applies the ancestry path. I haven't looked further than that, but is there any reason not to apply the ancestry path restriction before looking for patch-identical commits? With the patch below, the --ancestry-path version drops to under 2 seconds. I'm not sure if this is a good idea though. It helps me say I know nothing that isn't on the ancestry path can be patch-identical, so don't bother checking if it is but it regresses users who want the full cherry-pick check while only limiting the output. Perhaps we need --cherry-no-uninteresting to apply the first 3 hunks of the patch at runtime :-S -- 8 -- diff --git a/revision.c b/revision.c index de3b058..d721d83 100644 --- a/revision.c +++ b/revision.c @@ -837,7 +837,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs) for (p = list; p; p = p-next) { struct commit *commit = p-item; unsigned flags = commit-object.flags; - if (flags BOUNDARY) + if (flags (BOUNDARY | UNINTERESTING)) ; else if (flags SYMMETRIC_LEFT) left_count++; @@ -858,7 +858,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs) struct commit *commit = p-item; unsigned flags = commit-object.flags; - if (flags BOUNDARY) + if (flags (BOUNDARY | UNINTERESTING)) continue; /* * If we have fewer left, left_first is set and we omit @@ -879,7 +879,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs) struct patch_id *id; unsigned flags = commit-object.flags; - if (flags BOUNDARY) + if (flags (BOUNDARY | UNINTERESTING)) continue; /* * If we have fewer left, left_first is set and we omit @@ -1103,17 +1103,18 @@ static int limit_list(struct rev_info *revs) show(revs, newlist); show_early_output = NULL; } - if (revs-cherry_pick || revs-cherry_mark) - cherry_pick_list(newlist, revs); - - if (revs-left_only || revs-right_only) - limit_left_right(newlist, revs); if (bottom) { limit_to_ancestry(bottom, newlist); free_commit_list(bottom); } + if (revs-cherry_pick || revs-cherry_mark) + cherry_pick_list(newlist, revs); + + if (revs-left_only || revs-right_only) + limit_left_right(newlist, revs); + /* * Check if any commits have become TREESAME by some of their parents * becoming UNINTERESTING. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On 12/05/2013 19:33, John Keeping wrote: On Sun, May 12, 2013 at 05:28:24PM +0100, John Keeping wrote: You're right (and I was wrong in my reply to Junio's parallel message) ancestry path does seem to be what I want: $ git rev-list --ancestry-path --left-right --count \ master...git-gui/master 20565 However, this doesn't seem to make a difference to the time taken when I add in --cherry-mark (which is why I was partially correct in the parallel thread - it doesn't have the effect on cherry-mark that I want it to): This seems to be caused by the code in revision.c::limit_list() which does the cherry detection then limits to left/right and only then applies the ancestry path. I haven't looked further than that, but is there any reason not to apply the ancestry path restriction before looking for patch-identical commits? That certainly sounds like it's doing it the wrong way round. At first sight, it seems obviously suboptimal. No I didn't. I forgot to update my $PATH when I built on master - those results are from pu. master says: fatal: --ancestry-path given but there are no bottom commits Well, then it looks like we have a user for that particular syntax. Seemed a bit esoteric to me :) Although I realised after sending my mail you could also use git log --ancestry-path --left-right E...F --not $(git merge-base --all E F) which looks like we're having to repeat ourselves because it's not paying attention... I hit it because one of my optimisations relies on knowing the bottom commits, and I made absolutely sure I was using the exactly same definition of bottom as --ancestry-path. And then I found that my optimisations didn't work properly with ... I suggest we pull my patch out from the more complex optimisation series so it can proceed to next faster. It shouldn't have to wait for all my new fancy stuff - it's fixing something that appears to be a clear bug. Although Junio did have a comment about the implementation - I'll revisit it tomorrow and send a revised version separately, if everyone thinks that's sensible. On this subject, is there any way to exclude a path from a log query? Is there a not operator for paths? Might be another way of doing this - disjoint histories probably have disjoint paths... That relates to another idea I had about optimizing the detection of patch-identical commits. If the smaller side of a symmetric difference is quite small (as it is likely to be if it's a topic branch), would it be a good idea to calculate the set of paths touched by commits on that side and then skip calculating the patch ID for any commits that touch paths outside that set. The tree comparison is a lot cheaper than doing a diff on all of the files. Sounds cute. Go for it :) Kevin -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On 12/05/2013 19:58, John Keeping wrote: With the patch below, the --ancestry-path version drops to under 2 seconds. I'm not sure if this is a good idea though. It helps me say I know nothing that isn't on the ancestry path can be patch-identical, so don't bother checking if it is but it regresses users who want the full cherry-pick check while only limiting the output. Hmm. Should an excluded commit be a valid comparator? Is it sensible/correct to show a left commit as = to a right commit that has been excluded by the revision specifiers? Doesn't sound right to me. I'm not convinced that there's a valid use-case that you're regressing here. If --ancestry-path is being misused (the user's assertion that non-ancestry doesn't matter is wrong) the error of not noting culled patch-identical commits is nothing compared to the fact we're already totally omitting the non-identical ones. Kevin -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
Kevin Bracey ke...@bracey.fi writes: Although I realised after sending my mail you could also use git log --ancestry-path --left-right E...F --not $(git merge-base --all E F) which looks like we're having to repeat ourselves because it's not paying attention... You are half wrong; --left-right is about do we show the //= marker in the output?, so it is true that it does not make sense without ..., but the reverse is not true: A...B does not and should not imply --left-right. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
Kevin Bracey ke...@bracey.fi writes: On 12/05/2013 19:58, John Keeping wrote: With the patch below, the --ancestry-path version drops to under 2 seconds. I'm not sure if this is a good idea though. It helps me say I know nothing that isn't on the ancestry path can be patch-identical, so don't bother checking if it is but it regresses users who want the full cherry-pick check while only limiting the output. Hmm. Should an excluded commit be a valid comparator? Is it sensible/correct to show a left commit as = to a right commit that has been excluded by the revision specifiers? Doesn't sound right to me. Neither to me. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC/PATCH 0/2] merge-base: add --merge-child option
This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. With the --merge-child option, git merge-base will print a first-parent ancestor of the first revision given, where the commit printed is either a merge-base of the supplied revisions or a merge for which one of its parents (not the first) is a merge-base. For example, given the history: A---C---G \ B-D---F \ E we have: $ git merge-base F E B $ git merge-base --merge-child F E D $ git merge-base F G C $ git merge-base --merge-child F G C $ git log --left-right F...E F D C A E $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E The git-log case is useful because it allows us to limit the range of commits that we are examining for patch-identical changes when using --cherry. For example with git-gui in git.git I know that anything before the last merge of git-gui is not interesting: $ time git log --cherry master...git-gui/master /dev/null real0m32.731s user0m31.956s sys 0m0.664s $ time git log --cherry master...git-gui/master --not \ $(git merge-base --merge-child master git-gui/master) \ /dev/null real0m2.296s user0m2.193s sys 0m0.092s The first commit is a small prerequisite to extract a useful function from builtin/tag.c to commit.c. The second is the main change (the commit message is identical to the text before this paragraph). I'm not convinced that '--merge-child' is the right name for this but I think the functionality itself is useful. John Keeping (2): commit: add commit_list_contains function merge-base: add --merge-child option Documentation/git-merge-base.txt | 6 builtin/merge-base.c | 61 ++-- builtin/tag.c| 10 +-- commit.c | 8 ++ commit.h | 1 + t/t6010-merge-base.sh| 25 ++-- 6 files changed, 98 insertions(+), 13 deletions(-) -- 1.8.3.rc1.289.gcb3647f -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
John Keeping j...@keeping.me.uk writes: This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. With the --merge-child option, git merge-base will print a first-parent ancestor of the first revision given, where the commit printed is either a merge-base of the supplied revisions or a merge for which one of its parents (not the first) is a merge-base. The above two doe snot connect at least to me. The second paragraph seems to describe how this mysterious mode decides its output to a sufficient detail, but what the output _means_, and it is unclear how it relates to gitk/git-gui style merges. For example, given the history: A---C---G \ B-D---F \ E we have: ... $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E The git-log case is useful because it allows us to limit the range of commits that we are examining for patch-identical changes when using --cherry. Hmph, is this reinventing ancestry-path in a different way? At the low level machinery, you are finding D to show only F and E, and your goal seems to be to ignore the side ancestry A--C--G, but it is not clear if you prefer E D F(which would be what F...E would give in a history limited to ancestry-path, ignoring C) over E F. For example with git-gui in git.git I know that anything before the last merge of git-gui is not interesting: Can this be extended to find the second last such merge? Or is the last one always special? Still skeptical, but I'll let people discuss it during the feature freeze ;-). -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC/PATCH 0/2] merge-base: add --merge-child option
On Sat, May 11, 2013 at 10:54:12AM -0700, Junio C Hamano wrote: John Keeping j...@keeping.me.uk writes: This is helpful when examining branches with disjoint roots, for example because one is periodically merged into a subtree of the other. With the --merge-child option, git merge-base will print a first-parent ancestor of the first revision given, where the commit printed is either a merge-base of the supplied revisions or a merge for which one of its parents (not the first) is a merge-base. The above two doe snot connect at least to me. The second paragraph seems to describe how this mysterious mode decides its output to a sufficient detail, but what the output _means_, and it is unclear how it relates to gitk/git-gui style merges. For example, given the history: A---C---G \ B-D---F \ E we have: ... $ git log --left-right F...E --not $(git merge-base --merge-child F E) F E The git-log case is useful because it allows us to limit the range of commits that we are examining for patch-identical changes when using --cherry. Hmph, is this reinventing ancestry-path in a different way? At the low level machinery, you are finding D to show only F and E, and your goal seems to be to ignore the side ancestry A--C--G, but it is not clear if you prefer E D F(which would be what F...E would give in a history limited to ancestry-path, ignoring C) over E F. I hadn't considered ancestry-path, but I don't think it does what I want. What I want if for LEFT to be B--D--F and RIGHT to be B--E, ignoring A--C--G because I know that none of those are patch identical to anything in B--E. So what I want is more descendant-path than ancestry path in that I don't want anything that isn't a descendant of the merge base of the supplied arguments. For example with git-gui in git.git I know that anything before the last merge of git-gui is not interesting: Can this be extended to find the second last such merge? Or is the last one always special? In this implementation it only finds the last one because that's where the merge base is. Still skeptical, but I'll let people discuss it during the feature freeze ;-). I'm not convinced this is easy to explain myself, which may make it a bad idea. Perhaps a --descendant-path argument to git-log is a better way to help with this case. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html