More discussion about change tracking and "Combined commit" versus all separate commits in one merge
Posted by Andy Singleton on 2011-10-13 05:44
Here is a thread where we discuss whether to track ALL changes that were included in a merge separately, or commit them as a batch, with a note about where they came from in our merge history file. In summary:
On Thu, 2011-10-06, Andy Singleton wrote:
> There is only one other issue. I don't think that "undo" a changeset
> is an operation that we should use in a merge. It has a moderate to
> high probability of losing something that is important to the user. If
> I go and merge something specific, there is a moderate to high
> probability that I want to work on it. If I work on the code I get,
> then we can't "undo" the merge of that code without losing something
> that really is important to me.
Yes; I used the term "undo" in a very loose sense to describe something
that a user could achieve if necessary, with or without tool assistance.
I agree that "undo a change" in this sense should not be an operation in
a merge algorithm. I would not propose to implement that kind of merge
that I described, only to mention it as something the user could do
manually if he/she really wanted to.
- Julian
> On 10/6/2011 4:47 AM, Julian Foad wrote:
> > On Wed, 2011-10-05, Andy Singleton wrote:
> >> I like it. It's an efficient way to use the repository. It doesn't
> >> really work when you are doing foreign merges. You could work around
> >> some of those problems if you let the client roam around and connect to
> >> whatever servers it has permission to connect to.
> > Ah, I get your line of thinking now. After merging from a foreign
> > repository with a scheme that records all the original component changes
> > of the incoming merge as separable changes in the target repository, you
> > can then do arbitrary further branching and merging in the local
> > (target) repository without contacting the foreign repo.
> >
> > ForeignRepo contains:
> > BranchA
> > r4 an original change
> > r5 an original change
> >
> > LocalRepo contains:
> > BranchB
> > r700... merge of change ForeignRepo:BranchA:4
> > and change ForeignRepo:BranchA:5
> > BranchC
> > r800... merge of change ForeignRepo:BranchA:4
> >
> > Now merge "all" changes from BranchB to BranchC.
> > -> system extracts "ForeignRepo:BranchA:5" from BranchB.
> >
> > In contrast, with a scheme that commits the incoming merge as one single
> > change, even if it records metadata about the logical origins of that
> > change, you are more restricted in what further merging you can do
> > without contacting the foreign repo.
> >
> > ForeignRepo contains: as above
> >
> > LocalRepo contains:
> > BranchB
> > r700 merge of changes ForeignRepo:BranchA:{4-5}
> > BranchC
> > r800 merge of changes ForeignRepo:BranchA:{4}
> >
> > Now merge "all" changes from BranchB to BranchC.
> > -> system knows it needs "ForeignRepo:BranchA:5", and has to contact
> > ForeignRepo to retrieve that delta.
> >
> > In this combined-commit scheme the user does still have options for
> > attempting an off-line merge of the A:5 part of B:700 onto C, but not
> > nicely. One option is to undo C:800 and then merge B:700 into C; that
> > is a poor option because then the user will have to re-do conflict
> > resolutions on BranchC for the A:4 change, which he/she had already done
> > before.
> >
> > So, if contacting the foreign repo in cases like this isn't a
> > show-stopper, the combined-commit scheme is the way to go.
> >
> > - Julian
> >
> >
> >> We don't have to
> >> cover all cases, just MORE cases.
> >>
> >> On 10/5/2011 10:56 AM, Julian Foad wrote:
> >>> On Wed, 2011-10-05 at 15:46 +0100, Philip Martin wrote:
> >>>> Philip Martin<philip.martin@wandisco.com> writes:
> >>>>
> >>>>> Perhaps we don't need to split every merge into the smallest possible
> >>>>> commits. Your example:
> >>>>>
> >>>>> A has changes 4,5,6,7,8
> >>>>> B has merged A:4,5,6
> >>>>> C has merged A:6,7,8
> >>>>>
> >>>>> When I try to merge B into C the current merge tracking only looks to
> >>>>> see which B revisions are merged or not, it doesn't look through B to A.
> >>>>> Even if we don't split merges into multiple commits better tracking
> >>>>> would allow many more merges to "work".
> >>>>>
> >>>>> If A:5,6 had been merged/committed as a single revision on B then that
> >>>>> revision is a candidate to be merged to C, because it contains A:5 which
> >>>>> is not on C, but cannot be merged because it also contains A:6 which is
> >>>>> already on C. Then the user would be able to choose: reverse merge A:5
> >>>>> so that the B revision can be merged, or explicitly merge A:6 so that
> >>>>> the B revision becomes a no-op, or force the merge and handle any
> >>>>> conflict.
> >>>> It's possible that Subversion itself, rather than the user, chould do
> >>>> this automatically. When asked to merge B into C Subversion could
> >>>> choose to pull some changes from A to handle the case where a B revision
> >>>> is partial present on C. This would be a recursive algorithm, the A
> >>>> change might also be partially present on C leading Subversion to look
> >>>> at further branches.
> >>> This is the best solution I can imagine. It sounds like it both
> >>> achieves what's wanted (automatically pulling whatever changes the
> >>> target branch "doesn't have" and also fits into Subversion's overall
> >>> architecture.
> >>>
> >>> - Julian
> >>>
> >>>
> >>>> This would lose any conflict resolution in B that applied to the change
> >>>> pulled directly from A. Any conflict resolution in B could be either a
> >>>> help or a hinderance when pulling the A change to C, I don't know which
> >>>> is the more likely.
> >>>
> >>
> >
>
- Andy recommended committing every change separately, so that in future merges we can pick out only the changes we don't have.
- Julian recommends committing merges as a "combined commit", but making a note in our merge history file about what was included. Future merges can read the notes and get individual changesets from the repository if needed.
- Andy agrees that the "combined commit" is a good idea. However, it makes foreign merge more difficult. Some foreign merge operations will need access to the foreign repository, or they won't cover some merge cases.
On Thu, 2011-10-06, Andy Singleton wrote:
> There is only one other issue. I don't think that "undo" a changeset
> is an operation that we should use in a merge. It has a moderate to
> high probability of losing something that is important to the user. If
> I go and merge something specific, there is a moderate to high
> probability that I want to work on it. If I work on the code I get,
> then we can't "undo" the merge of that code without losing something
> that really is important to me.
Yes; I used the term "undo" in a very loose sense to describe something
that a user could achieve if necessary, with or without tool assistance.
I agree that "undo a change" in this sense should not be an operation in
a merge algorithm. I would not propose to implement that kind of merge
that I described, only to mention it as something the user could do
manually if he/she really wanted to.
- Julian
> On 10/6/2011 4:47 AM, Julian Foad wrote:
> > On Wed, 2011-10-05, Andy Singleton wrote:
> >> I like it. It's an efficient way to use the repository. It doesn't
> >> really work when you are doing foreign merges. You could work around
> >> some of those problems if you let the client roam around and connect to
> >> whatever servers it has permission to connect to.
> > Ah, I get your line of thinking now. After merging from a foreign
> > repository with a scheme that records all the original component changes
> > of the incoming merge as separable changes in the target repository, you
> > can then do arbitrary further branching and merging in the local
> > (target) repository without contacting the foreign repo.
> >
> > ForeignRepo contains:
> > BranchA
> > r4 an original change
> > r5 an original change
> >
> > LocalRepo contains:
> > BranchB
> > r700... merge of change ForeignRepo:BranchA:4
> > and change ForeignRepo:BranchA:5
> > BranchC
> > r800... merge of change ForeignRepo:BranchA:4
> >
> > Now merge "all" changes from BranchB to BranchC.
> > -> system extracts "ForeignRepo:BranchA:5" from BranchB.
> >
> > In contrast, with a scheme that commits the incoming merge as one single
> > change, even if it records metadata about the logical origins of that
> > change, you are more restricted in what further merging you can do
> > without contacting the foreign repo.
> >
> > ForeignRepo contains: as above
> >
> > LocalRepo contains:
> > BranchB
> > r700 merge of changes ForeignRepo:BranchA:{4-5}
> > BranchC
> > r800 merge of changes ForeignRepo:BranchA:{4}
> >
> > Now merge "all" changes from BranchB to BranchC.
> > -> system knows it needs "ForeignRepo:BranchA:5", and has to contact
> > ForeignRepo to retrieve that delta.
> >
> > In this combined-commit scheme the user does still have options for
> > attempting an off-line merge of the A:5 part of B:700 onto C, but not
> > nicely. One option is to undo C:800 and then merge B:700 into C; that
> > is a poor option because then the user will have to re-do conflict
> > resolutions on BranchC for the A:4 change, which he/she had already done
> > before.
> >
> > So, if contacting the foreign repo in cases like this isn't a
> > show-stopper, the combined-commit scheme is the way to go.
> >
> > - Julian
> >
> >
> >> We don't have to
> >> cover all cases, just MORE cases.
> >>
> >> On 10/5/2011 10:56 AM, Julian Foad wrote:
> >>> On Wed, 2011-10-05 at 15:46 +0100, Philip Martin wrote:
> >>>> Philip Martin<philip.martin@wandisco.com> writes:
> >>>>
> >>>>> Perhaps we don't need to split every merge into the smallest possible
> >>>>> commits. Your example:
> >>>>>
> >>>>> A has changes 4,5,6,7,8
> >>>>> B has merged A:4,5,6
> >>>>> C has merged A:6,7,8
> >>>>>
> >>>>> When I try to merge B into C the current merge tracking only looks to
> >>>>> see which B revisions are merged or not, it doesn't look through B to A.
> >>>>> Even if we don't split merges into multiple commits better tracking
> >>>>> would allow many more merges to "work".
> >>>>>
> >>>>> If A:5,6 had been merged/committed as a single revision on B then that
> >>>>> revision is a candidate to be merged to C, because it contains A:5 which
> >>>>> is not on C, but cannot be merged because it also contains A:6 which is
> >>>>> already on C. Then the user would be able to choose: reverse merge A:5
> >>>>> so that the B revision can be merged, or explicitly merge A:6 so that
> >>>>> the B revision becomes a no-op, or force the merge and handle any
> >>>>> conflict.
> >>>> It's possible that Subversion itself, rather than the user, chould do
> >>>> this automatically. When asked to merge B into C Subversion could
> >>>> choose to pull some changes from A to handle the case where a B revision
> >>>> is partial present on C. This would be a recursive algorithm, the A
> >>>> change might also be partially present on C leading Subversion to look
> >>>> at further branches.
> >>> This is the best solution I can imagine. It sounds like it both
> >>> achieves what's wanted (automatically pulling whatever changes the
> >>> target branch "doesn't have" and also fits into Subversion's overall
> >>> architecture.
> >>>
> >>> - Julian
> >>>
> >>>
> >>>> This would lose any conflict resolution in B that applied to the change
> >>>> pulled directly from A. Any conflict resolution in B could be either a
> >>>> help or a hinderance when pulling the A change to C, I don't know which
> >>>> is the more likely.
> >>>
> >>
> >
>
Home / Developer API / Tour / Get a Project - Solutions for Bug & Issue Tracking, Collaboration Tools, Subversion Hosting, Git Hosting
Subversion newmerge is powered by Assembla.
0 Comments