threads / discuss / 11646

Merging using only fast-forward

Subject: Merging using only fast-forward

## tl;dr

15 messages between Jan 16, 2008 and Jan 21, 2008.

replies: 14people: 3as markdown or json

Sverre Hvammen Johansen· Jan 16, 2008, 15:54 UTC · lore
Hi,

I have a work flow where A is only allowed to rebase and B is only allowed to fast-forward. They both fetch from each other and rebase/merge using pull. On A I can use the configuration branch.<name>.rebase but it does not seem to be an option to enforce a fast-forward on B.

If there are changes on both A and B that have not yet been integrated (by A doing a pull (fetch/rebase)) I want a pull (fetch/merge) on B to fail.

It would be useful with a configuration ala branch.<name>.fast-forward or an option --ff-only to git-merge so I could use the configuration branch.<name>.mergeoptions.

Is there any other way to achieve this?

Thanks for a great tool. I am using git with accurev where B is the integrator between git and accurev (commits flow in both directions). I imagine this could be useful in other environments as well.

-- 
Sverre Hvammen Johansen
Randal L. Schwartz· Jan 16, 2008, 16:27 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

>>>>> "Sverre" == Sverre Hvammen Johansen <hvammen@gmail.com> writes:

Sverre> If there are changes on both A and B that have not yet been integrated Sverre> (by A doing a pull (fetch/rebase)) I want a pull (fetch/merge) on B to Sverre> fail.

Junio implemented a 7-line patch on the IRC channel (calling parts of it "for randal" or something, I believe :) to do precisely this.

Perhaps you can test it, and submit it as if it were your idea. I, for one, would use it as well. I'm doing ugly things with parsing the output of git-status right now to achieve the same thing.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Junio C Hamano· Jan 16, 2008, 20:31 UTC · re: Randal L. Schwartz · lore

Re: Merging using only fast-forward

merlyn@stonehenge.com (Randal L. Schwartz) writes:
Show 6 quoted lines
> Junio implemented a 7-line patch on the IRC channel (calling parts of it
> "for randal" or something, I believe :) to do precisely this.
>
> Perhaps you can test it, and submit it as if it were your idea.  I, for one,
> would use it as well.  I'm doing ugly things with parsing the output of
> git-status right now to achieve the same thing.
The mechanism itself is simple.  
	http://git.pastebin.com/m156a1856
A sane integration is a different story.

We have --ff and --no-ff options to merge. How should this new option --ff-only mesh with them? Perhaps we would want to have an option --ff that takes three values?

	--ff=never
        --ff=normal
        --ff=only

and have the first one be synonym for existing --no-ff, the second one to be a synonym for not giving anything (or giving --ff explicitly), and the third one to be this new mode of operation?

Sverre Hvammen Johansen· Jan 16, 2008, 22:38 UTC · re: Junio C Hamano · lore

Re: Merging using only fast-forward

On Jan 16, 2008 12:31 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 13 quoted lines
> A sane integration is a different story.
>
> We have --ff and --no-ff options to merge.  How should this new
> option --ff-only mesh with them?  Perhaps we would want to have
> an option --ff that takes three values?
>
>         --ff=never
>         --ff=normal
>         --ff=only
>
> and have the first one be synonym for existing --no-ff, the second
> one to be a synonym for not giving anything (or giving --ff
> explicitly), and the third one to be this new mode of operation?

Thanks for the patch. I can probably look into it tonight and do the suggested integration and test it out, I keep you posted.

-- 
Sverre Hvammen Johansen
Junio C Hamano· Jan 16, 2008, 22:49 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

"Sverre Hvammen Johansen" <hvammen@gmail.com> writes:
Show 17 quoted lines
> On Jan 16, 2008 12:31 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> A sane integration is a different story.
>>
>> We have --ff and --no-ff options to merge.  How should this new
>> option --ff-only mesh with them?  Perhaps we would want to have
>> an option --ff that takes three values?
>>
>>         --ff=never
>>         --ff=normal
>>         --ff=only
>>
>> and have the first one be synonym for existing --no-ff, the second
>> one to be a synonym for not giving anything (or giving --ff
>> explicitly), and the third one to be this new mode of operation?
>
> Thanks for the patch.  I can probably look into it tonight and do the
> suggested integration and test it out, I keep you posted.

Well, no, I did not _suggest_ that particular integration. I do not even know what the right answer is to these questions. The UI that pastebin patch implements, which uses totally separate flags, may turn out to be the right approach. If you want to carry the torch forward on this topic, that's great. It is very much appreciated. But one of the things included in that work includes thinking and deciding which UI is better between the patch in the pastebin and the one that tries to introduce a unified --ff=<value> option. I simply do not know the answer, and prefer not having to think about it during a pre-release feature freeze.

Coming up with a 7-liner quick-and-dirty solution is one thing. It was easy (although I haven't tested it, so it may not work at all!). But if we want to mainline it, we need to think carefully how the new feature integrates well with what we already have. That's all I wanted to say.

Sverre Hvammen Johansen· Jan 17, 2008, 06:53 UTC · re: Junio C Hamano · lore

Re: Merging using only fast-forward

On Jan 16, 2008 12:31 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> merlyn@stonehenge.com (Randal L. Schwartz) writes:
>
> > Junio implemented a 7-line patch on the IRC channel (calling parts of it
> > "for randal" or something, I believe :) to do precisely this.
>
> The mechanism itself is simple.
>
>         http://git.pastebin.com/m156a1856

I know that the patch you wrote is not good. However, it is a good starting point.

We need to consider cases where the branch we are merging with is an ancestor or an descendant of HEAD. The patch only take descendants into account. There may also be more than one branch we are merging with. All these cases must be considered. In the case of an octopus, the cases are slightly more complicated.

I have a patch that work for all cases except for some octopus cases. I have written a few test case. All existing tests succeeds.

I will not be able to work on this for a few days, but I expect to have a working patch some time this weekend.

I have not looked at the documentation but assume it should not be to hard to add some documentation as well.

-- 
Sverre Hvammen Johansen
Sverre Hvammen Johansen· Jan 18, 2008, 06:58 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

On Jan 16, 2008 10:53 PM, Sverre Hvammen Johansen <hvammen@gmail.com> wrote:
Show 5 quoted lines
> We need to consider cases where the branch we are merging with is an
> ancestor or an descendant of HEAD.  The patch only take descendants
> into account.  There may also be more than one branch we are merging
> with.  All these cases must be considered.  In the case of an octopus, the
> cases are slightly more complicated.

I have been testing octopus merges and figured it is not very smart with respect to fast forward. I would like it to do a fast forward whenever it makes sense to do that. Consider the following:

     -- c1 -- A
   /              /  \
c0 -- c2 --      C
   \              \  /
     -- c3 -- B

A is a merge between c1 and c2, B is a merge between c2 and c3, and C is a merge between A and B.

c1 merged with A does a fast forward to A, A merged with C does a fast forward to C, but an octopus merge of c1 with A and C does not fast forward to C. I would expect it to fast forward to C. The commit graph above have several other cases where an octopus merge can be reduced to a fast forward or a recursive merge.

I suggest a separate pass before we choose merge strategy. Remove commits that can be fast forwarded to any of the other commits from the equation and fast forward the current branch if possible. The remaining commits are then taken into consideration. This may reduce the number of commits and thus result in a fast forward or another merge strategy.

I intend to make the patch for the option --ff-only as simple as possible, where it will fail where more than two commits are involved. If the above suggested pass is implemented it should also take affect for --ff-only.

Does this make sense?
-- 
Sverre Hvammen Johansen
Junio C Hamano· Jan 18, 2008, 21:25 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

"Sverre Hvammen Johansen" <hvammen@gmail.com> writes:
> I have been testing octopus merges and figured it is not very smart with
> respect to fast forward.

Octopus is designed to be simple and stupid. Its sole purpose is to bind more than two _independent_ development tracks, and by definition if they are totally independent, like A and B and C all forked from the current tip of our HEAD, it should make a new commit that is children of A and B and C. If B and C are not independent (e.g. C is a descendant of B), you should not be using Octopus to begin with.

The thing is, Octopus makes the bisection (not the internal processing of "git bisect", but the whole experience with "git bisect" which is measured by the number of commits you may have to test to find the one bad commit) less efficient, especially when the branches that are merged are not independent topics.

So keep it simple, and do not use Octopus if there is no justification other than "it looks cool" you can come up with.

I do not mind a patch to git-merge-octopus to discurage its use even more by detecting the casen where some of the merged branches are not independent and refusing to work, but that is a post 1.5.4 topic.

Sverre Hvammen Johansen· Jan 19, 2008, 10:28 UTC · re: Junio C Hamano · lore

Re: Merging using only fast-forward

On Jan 18, 2008 1:25 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> ...
> So keep it simple, and do not use Octopus if there is no
> justification other than "it looks cool" you can come up with.
>
> I do not mind a patch to git-merge-octopus to discurage its use
> even more by detecting the casen where some of the merged
> branches are not independent and refusing to work, but that is
> a post 1.5.4 topic.

Instead of refusing to work, such merge commits can be fast forwarded, recorded as a "normal" commit with two children, or an octopus with fewer children than those specified by the user.

The more I think about this is that --ff-only should really be specified as a merge strategy (single) and not as an special case of --ff. All merge strategies can then take any number of commits, but will only succeed if the commits can be reduced down to two or fewer for resolve/recursive and one for single.

Commit reduction is simpler for single than the other merge strategies.

I suggest we keep it simple and implement this new feature as a merge strategy and the commit reduction is only done for fast-forward.

I will create a good number of test cases so we should be comfortable with this new feature.

A later patch will implement the commit reduction for the other merge strategies. --no-ff will then have the meaning: No fast forward of any commit. All commits specified by the user will be recorded.

-- 
Sverre Hvammen Johansen
Sverre Hvammen Johansen· Jan 19, 2008, 10:38 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

On Jan 19, 2008 2:28 AM, Sverre Hvammen Johansen <hvammen@gmail.com> wrote:
> I suggest we keep it simple and implement this new feature as a merge
> strategy and the commit reduction is only done for fast-forward.
s/fast-forward/single/
-- 
Sverre Hvammen Johansen
Junio C Hamano· Jan 19, 2008, 10:43 UTC · re: Sverre Hvammen Johansen · lore

Re: Merging using only fast-forward

"Sverre Hvammen Johansen" <hvammen@gmail.com> writes:
Show 5 quoted lines
> The more I think about this is that --ff-only should really be
> specified as a merge strategy (single) and not as an special case of
> --ff.  All merge strategies can then take any number of commits, but
> will only succeed if the commits can be reduced down to two or fewer
> for resolve/recursive and one for single.
Interesting.

At one end of the spectrum, we have these crazy people who want git to record something that is not a merge at all as a merge with --no-ff. At the other end of the spectrum, we have these other crazy people who want git to outsmart them by allowing them to throw random set of commits as potential parents, remove duplicates and figure out how many real parents the resulting merge should have (including the case that it may not even have any).

I'll have to think about it, but it sounds like a promising idea.

Sverre Hvammen Johansen· Jan 19, 2008, 12:39 UTC · re: Junio C Hamano · lore

Re: Merging using only fast-forward

On Jan 19, 2008 2:43 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> At one end of the spectrum, we have these crazy people who want
> git to record something that is not a merge at all as a merge
> with --no-ff.  At the other end of the spectrum, we have these
> other crazy people who want git to outsmart them by allowing
> them to throw random set of commits as potential parents,
> remove duplicates and figure out how many real parents the
> resulting merge should have (including the case that it may not
> even have any).
I guess the most common use case would be where you have at least
three developers and they randomly fetch and merge between each other.
 They usually are not aware of where each other are and everyone
avoids octopus.  They end up with more merge commits than needed
simply because they sometime pick the wrong order.  If they instead
had git find the real parents they would get fewer merge commits.
-- 
Sverre Hvammen Johansen
Sverre Hvammen Johansen· Jan 21, 2008, 06:26 UTC · re: Junio C Hamano · lore

Re: Merging using only fast-forward

On Jan 19, 2008 2:43 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> At one end of the spectrum, we have these crazy people who want
> git to record something that is not a merge at all as a merge
> with --no-ff.  At the other end of the spectrum, we have these
> other crazy people who want git to outsmart them by allowing
> them to throw random set of commits as potential parents,
> remove duplicates and figure out how many real parents the
> resulting merge should have (including the case that it may not
> even have any).

I am currently working on a patch for this. I have some new tests for this but more is needed and there is no documentation.

The only case that currently is not working is the case where I need to fast forward head and then do a merge. Do I need to update the files in the working directory twice (once after the fast forward and then once by the merge) or can I somehow get lets say git-merge-recursive to do this part for me?

The patch I have that handles the above failing case by not fast forwarding HEAD, but instead use it together with the other real_heads work (all tests succeed).

-- 
Sverre Hvammen Johansen
Sverre Hvammen Johansen· Jan 19, 2008, 12:30 UTC · lore

Re: Merging using only fast-forward

On Jan 19, 2008 2:43 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
> At one end of the spectrum, we have these crazy people who want
> git to record something that is not a merge at all as a merge
> with --no-ff.  At the other end of the spectrum, we have these
> other crazy people who want git to outsmart them by allowing
> them to throw random set of commits as potential parents,
> remove duplicates and figure out how many real parents the
> resulting merge should have (including the case that it may not
> even have any).
I guess the most common use case would be where you have at least
three developers and they randomly fetch and merge between each other.
 They usually are not aware of where each other are and everyone
avoids octopus.  They end up with more merge commits than needed
simply because they sometime pick the wrong order.  If they instead
had git find the real parents they would get fewer merge commits.
-- 
Sverre Hvammen Johansen

← back to recent threads