Re: Rephrasing: question about merging branches
Derek Robert Price [EMAIL PROTECTED] wrote on 11/06/2003 04:37:03 PM: I see it now, and I thought that the conflicts you now say don't occur were the ones you objected to in the first place. Not at all. The conflicts that troubled me were happening because I was double-merging (when bringing B back to the trunk, merging from 1-4 instead of 2-4), _until_ I used the technique laid out in that email. The conflicts in question are what you describe, here: If A branched first, then 2-4 will attempt to remerge changes made to the trunk between the base of A and the base of B, causing the same sort of spurious conflicts you were attempting to avoid. And that did not seem to be true. It seemed to me that those changes are not merged twice - as I said, The changes between the start of A and the start of B are not in A, and they are inherent in B. So I am wondering if I tested it wrong and am thinking about it wrong? Regardless, some of what you said in that email was correct and some wasn't, but I don't think you can solve the general case without saving a merge history for each revision of each file. If individual files can't merge, and only whole branches can, I confess I don't understand why that is true, unless by saying the general case we are actually discussing something different than I imagine. One other thing I was wondering about was what I found when experimenting with the approach you suggest (using multiple merges): that conflicts arise during the interim steps, making the process unworkable. I am interested in single-step merges both because it _seems_ possible generally to construct one appropriate to a given case, and because they appear to me to avoid the issues of conflicts during interim merge steps. It isn't. The existing GCA algorithm is merely a convenience to avoid typing a start-revision in the most common case (merging from a branch to its parent) and I think it actually confuses more people than it Let me clarify what I mean a bit more. I want to generalize the process of finding a merge start point based on merge and branch information. I think the CVS GCA system is an interesting approach when working with branch information alone. If I understand it correctly, it is analogous to walking backwards up the ancestry of the source branch, searching for the most recent branch point on any common parent, of the souce or the destination branch (whichever is older). What I am experimenting with is the notion that if you add merge information to the mix, this approach still works. I am gathering that you don't think it will; but I guess what I am wondering, in that case, is, how will it fail? ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David Wood wrote: |Derek Robert Price [EMAIL PROTECTED] wrote on 11/05/2003 12:43:14 PM: | |Greatest Common Ancestor, or GCA, is a term that refers to the RCS |revision structure and always means the more recent revision two |revisions have in common, often a branch point, but in the case of a |branch of a branch and the trunk, note that the GCA is on the trunk, not |the base revision of the branch, but the base revision of its parent. | | |So in other words, you are saying: in the case where the branch (child) of |a branch (parent) merges back to the trunk (grandparent), the GCA is on |the grandparent, at the point where the parent begins. Right? Yes. And if the example was a child merging to the great grandparent, the GCA would be where the parent begins. The GCA is the most recent ancestor the two revisions have in common. |If someone were to solve this problem and submit a patch that |implemented the solution including documentation and tests cases which |addressed these sorts of issues and any others that arose, believe me, I |would be one of the first to vote that CVS incorporate the code. | | |I am hopeful that someone will be me. | |My initial approach has been to use a wrapper which executes branches |and merges, generating and applying tags in addition to branching and |merging, and maintaining extra state data in a database. I believe that |the tool has all of the necessary information available; the question now |is using it to determine the correct merge start point in a general way. | |I only intend to support whole branch merges, and I have been under the |impression that I can focus solely on eliminating over- and under-merging. The way to avoid only processing this for whole branch merges is to track individual commits as change sets. For example, store that the sum of changesets for file1 1.2 - 1.2.4.7 have been merged into the trunk. Then later, if a merge is attempted from 1.1 through 1.2.4.103.2.17, CVS could notice that the changesets above lay in the path and merge 1.1 - 1.2 1.2.4.7 - 1.2.4.103.2.17 as two separate merges. If 1.2.4.103.2.1 - 1.2.4.103.2.10 has already been merged as well, then that could be subtracted as well, leaving CVS with three merges: ~1.1 -1.2 ~1.2.4.7 - 1.2.4.103 ~1.2.4.103.2.10 - 1.2.4.103.2.17 and so on. |I believe cases such as your examples, where it is desirable to double |merge, or to deliberately eliminate part of the merge, cannot be handled |in a general way - although perhaps you will disagree? No, I don't think there is a general way to handle this. Or, at least the general way is to allow the user to pass a switch or somesuch to override the smart behavior so the merge can be reapplied. Note that this requires that CVS report when it skips portions of a requested merge so that the user will know this is necessary. |My cursory examination of CVS's GCA algorithm leaves me with the |impression that it relies on properties of the revision numbering system, |which if true makes it abundantly clear why there is no simple path to |making CVS smarter about GCA, even if it did have the information about |merge activity that it needed. No, this would not make CVS smarter about GCA. This would make CVS smarter about merging. Please do not misuse the term GCA this way. GCA has a well-defined meaning and well-established usage in CVS and the algorithm we are discussing has little to do with determining the ancestor, except possibly for determining an implicit start point for a merge request, which is exactly how the GCA is used currently. Derek - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- If nature has made any one thing less susceptible than all others of exclusive property, it is the action of the thinking power called an idea, which an individual may exclusively possess as long as he keeps it to himself; but the moment it is divulged, it forces itself into the possession of everyone, and the receiver cannot dispossess himself of it. Its peculiar character, too, is that no one possesses the less, because every other possesses the whole of it. He who receives an idea from me, receives instruction himself without lessening mine; as he who lights his taper at mine, receives light without darkening me. That ideas should freely spread from one to another over the globe, for the moral and mutual instruction of man, and improvement of his condition, seems to have been peculiarly and benevolently designed by nature, when she made them, like fire, expansible over all space, without lessening their density at any point, and like the air in which we breathe, move, and have our physical being, incapable of confinement or exclusive appropriation. Inventions then cannot, in nature, be a subject of property. - Thomas Jefferson -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape -
Re: Rephrasing: question about merging branches
Derek Robert Price [EMAIL PROTECTED] wrote on 11/06/2003 08:57:22 AM: The way to avoid only processing this for whole branch merges is to track individual commits as change sets. For example, store that the sum of changesets for file1 1.2 - 1.2.4.7 have been merged into the trunk. Then later, if a merge is attempted from 1.1 through 1.2.4.103.2.17, CVS could notice that the changesets above lay in the path and merge 1.1 - 1.2 1.2.4.7 - 1.2.4.103.2.17 as two separate merges. If 1.2.4.103.2.1 - 1.2.4.103.2.10 has already been merged as well, then that could be subtracted as well, leaving CVS with three merges: ~1.1 -1.2 ~1.2.4.7 - 1.2.4.103 ~1.2.4.103.2.10 - 1.2.4.103.2.17 and so on. I'm curious, do you think that multi-step merges will be required for the general case? Did you see my response to your original email? You had thought that multiple merges were necessary for that example, but when I studied it it didn't look that way. http://mail.gnu.org/archive/html/info-cvs/2003-11/msg00053.html Isn't it possible that, if I do whole branch merges, I can handle everything with single merge operations... subject to caveats: No, I don't think there is a general way to handle this. Or, at least the general way is to allow the user to pass a switch or somesuch to override the smart behavior so the merge can be reapplied. Note that this requires that CVS report when it skips portions of a requested merge so that the user will know this is necessary. Certainly that switch is assumed. But say for the sake of argument that it is all or nothing. In other words, if you want to use the smart merges, you have to follow the smart merge rules. That merely means doing some things a bit differently; for instance, if you want to use merge as a tool in more unconventional ways (I want to re-merge this branch because changes from it were accidentally deleted), you have to find other solutions. In the case of this example, I'd envision using the conventional merge operations to easily simulate undoing the mistake without additional complexity. |My cursory examination of CVS's GCA algorithm leaves me with the |impression that it relies on properties of the revision numbering system, |which if true makes it abundantly clear why there is no simple path to |making CVS smarter about GCA, even if it did have the information about |merge activity that it needed. No, this would not make CVS smarter about GCA. This would make CVS smarter about merging. Please do not misuse the term GCA this way. GCA has a well-defined meaning and well-established usage in CVS and the algorithm we are discussing has little to do with determining the ancestor, except possibly for determining an implicit start point for a merge request, which is exactly how the GCA is used currently. I will be careful not to confuse the term GCA with any new, more automated system for determining merge start points. I meant to draw the comparison only because what I envisioned for such a new system seemed functionally very similar to the existing CVS GCA algorithm (in function, of course, not in implementation). Or am I wrong even in this? ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David Wood wrote: |Derek Robert Price [EMAIL PROTECTED] wrote on 11/06/2003 08:57:22 AM: | |The way to avoid only processing this for whole branch merges is to |track individual commits as change sets. For example, store that the |sum of changesets for file1 1.2 - 1.2.4.7 have been merged into the |trunk. Then later, if a merge is attempted from 1.1 through |1.2.4.103.2.17, CVS could notice that the changesets above lay in the |path and merge 1.1 - 1.2 1.2.4.7 - 1.2.4.103.2.17 as two separate |merges. | |If 1.2.4.103.2.1 - 1.2.4.103.2.10 has already been merged as well, then |that could be subtracted as well, leaving CVS with three merges: | |~1.1 -1.2 |~1.2.4.7 - 1.2.4.103 |~1.2.4.103.2.10 - 1.2.4.103.2.17 | |and so on. | | |I'm curious, do you think that multi-step merges will be required for the |general case? For the most general case, yes. A record of all diffs that have been merged to a location, and multi-step merges would be necessary. What would you like a smart CVS to do in this case: ~ /-t1t2--A ~-- ~ \-B ~cvs co -r B project ~cvs up -jt1 -jt2 ~cvs ci ~cvs up -jA |Did you see my response to your original email? You had thought that |multiple merges were necessary for that example, but when I studied it it |didn't look that way. | |http://mail.gnu.org/archive/html/info-cvs/2003-11/msg00053.html | |Isn't it possible that, if I do whole branch merges, I can handle |everything with single merge operations... subject to caveats: I see it now, and I thought that the conflicts you now say don't occur were the ones you objected to in the first place. Regardless, some of what you said in that email was correct and some wasn't, but I don't think you can solve the general case without saving a merge history for each revision of each file. ||My cursory examination of CVS's GCA algorithm leaves me with the ||impression that it relies on properties of the revision numbering | |system, | ||which if true makes it abundantly clear why there is no simple path to ||making CVS smarter about GCA, even if it did have the information about ||merge activity that it needed. | | |No, this would not make CVS smarter about GCA. This would make CVS |smarter about merging. Please do not misuse the term GCA this way. |GCA has a well-defined meaning and well-established usage in CVS and |the algorithm we are discussing has little to do with determining the |ancestor, except possibly for determining an implicit start point for a |merge request, which is exactly how the GCA is used currently. | | |I will be careful not to confuse the term GCA with any new, more |automated system for determining merge start points. I meant to draw the |comparison only because what I envisioned for such a new system seemed |functionally very similar to the existing CVS GCA algorithm (in function, |of course, not in implementation). | |Or am I wrong even in this? It isn't. The existing GCA algorithm is merely a convenience to avoid typing a start-revision in the most common case (merging from a branch to its parent) and I think it actually confuses more people than it helps since it always does _something_, even in the not so common cases, or at least it certainly would confuse more people than it helped if some sort of autotagging of the base occurred when a branch was created (Steve Cameron's .base, .parent, .trunk patch would be a nice alternative to autotagging if someone could fix it and we could commit it). As things stand, GCA as a start point is the occassionally the best you can do if you aren't meticulous about tagging your branch base. Regardless, its use in the most common case doesn't make it a smart system. It is still very dumb, and in fact, if you pass CVS a single static tag rather than a branch, it will still happily compute the GCA with the destination of the merge. This can occassionallly be useful if you know what you are doing, but it isn't very smart, on CVS's part, and if you don't know what you are doing it can cause confusion. Derek - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- I will not fake my way through life. I will not fake my way through life. I will not fake my way through life... ~ - Bart Simpson on chalkboard, _The Simpsons_ -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/qr7+LD1OTBfyMaQRAgr1AKCh3mVAn3mEFY9+87cvMyAAmG1aKwCgvhJu pXkEav4/qeHTZT70grI7j4c= =bisw -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
Is it just me, or is this getting way too complex to be usable except by CVS experts? I thought I was comfortable with the issues surrounding branches and merges, even though we are not using branches yet here. But I don't understand half of what you folks are saying. Worse: in my understanding this isn't even a particularly complex case. Let me see if I have this right. You want to merge changes made on a branch back into the main development stream, then merge that with the changes on another branch. Surely **everyone** will need to do this, sooner or later? Andy Jones. At 03:37 am 5/11/03, David Wood wrote: I am not sure about something. |If branch A and branch B in your example don't branch form the same |point on the trunk, a merge from point 2 to point 4 into the trunk might |still not do what you want. If branch B branched first, then 2-4 may |back out changes made to the trunk between the base of B and the base of |A. If A branched first, then 2-4 will attempt to remerge changes made |to the trunk between the base of A and the base of B, causing the same |sort of spurious conflicts you were attempting to avoid. Assume B is branched first. A merges to the trunk. Then A merges to B. Then B merges to the trunk as well. I think the trick here is what happens when A merges to B. If you do that merge like this: (in B's working dir): cvs update -j branchA_CREATED -j 3 (3 == where A merges to B) then you are correct. This merge will be missing changes from between the start of B and A - ALREADY! In other words, with respect to B, part of A was left out, since it was created before branchA_CREATED - on the trunk. But I think this is really the wrong way to merge A into B. The right way is to do it would be to say: cvs update -j branchB_CREATED -j 3 Then branch B does indeed end up incorporating everything from branch A. In other words, the changes on the trunk after B was created until A starts, and then all then all the changes in A. So when doing that kind of merge, always use the newest common ancestor (in this case, the start of B). Now let's look at your other scenario. When A is created before B, everything else being equal, I did not receive spurious conflicts doing that last merge in a single step (2-4, Jamie's way) after all! You say there should be, because that I am remerging changes made to the trunk between the base of A and the base of B. But I can't see where the redundancy should come from. The changes between the start of A and the start of B are not in A, and they are inherent in B. So goes my theory. Perhaps we are making different assumptions? |The only clean way to do this in the general case is to tag branch B |before and after your merge from A at point 3 and merge B back into the |trunk as two merges: | |~cvs up -j 1 -j pre-3 |~cvs up -j post-3 -j 4 ... Oops, yes, you are correct. What I said was correct if point 2 3 were the same (at point 2 all of branch A was merge to both the trunk and branch B). A clean merge to the trunk without conflicts from a repeated merge with distinct points 2 3 would require the two commands I listed above and a third merge: ~cvs up -j 2 -j 3 So if I understand you all correctly, a generalized merge formula would be: cvs update -j start-of-branchB -j pre-3' cvs update -j 2 -j 3 cvs update -j post-3' -j 4 in that order? What if branchB had made changes that would conflict with branchA's changes, and the merge from A to B is to correct that conflict and bring B into sync _before_ it merges with the trunk? Following this pattern, I will still get that conflict between B and the trunk on the first command - even though those conflicts had already been resolved post-3'. Nothing subsequent would work without manually duplicating the conflict resolution already present in B... ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
Please correct me if I'm wrong. I _think_ this is the greatest common ancestor problem. And finding one is actually something CVS does for you - on the first mege (with a single -j). Which is usually OK in cases where a branch immediately dies (i.e. becomes dormant) afterwards. The problem is that CVS does not remember that a merge took place. After a merge, the map of ancestry that was built by branch operations is no longer correct. And from that point on, CVS relies on _you_ to find the GCA. [EMAIL PROTECTED] wrote on 11/05/2003 03:55:38 AM: Is it just me, or is this getting way too complex to be usable except by CVS experts? I thought I was comfortable with the issues surrounding branches and merges, even though we are not using branches yet here. But I don't understand half of what you folks are saying. Worse: in my understanding this isn't even a particularly complex case. Let me see if I have this right. You want to merge changes made on a branch back into the main development stream, then merge that with the changes on another branch. Surely **everyone** will need to do this, sooner or later? Andy Jones. At 03:37 am 5/11/03, David Wood wrote: I am not sure about something. |If branch A and branch B in your example don't branch form the same |point on the trunk, a merge from point 2 to point 4 into the trunk might |still not do what you want. If branch B branched first, then 2-4 may |back out changes made to the trunk between the base of B and the base of |A. If A branched first, then 2-4 will attempt to remerge changes made |to the trunk between the base of A and the base of B, causing the same |sort of spurious conflicts you were attempting to avoid. Assume B is branched first. A merges to the trunk. Then A merges to B. Then B merges to the trunk as well. I think the trick here is what happens when A merges to B. If you do that merge like this: (in B's working dir): cvs update -j branchA_CREATED -j 3 (3 == where A merges to B) then you are correct. This merge will be missing changes from between the start of B and A - ALREADY! In other words, with respect to B, part of A was left out, since it was created before branchA_CREATED - on the trunk. But I think this is really the wrong way to merge A into B. The right way is to do it would be to say: cvs update -j branchB_CREATED -j 3 Then branch B does indeed end up incorporating everything from branch A. In other words, the changes on the trunk after B was created until A starts, and then all then all the changes in A. So when doing that kind of merge, always use the newest common ancestor (in this case, the start of B). Now let's look at your other scenario. When A is created before B, everything else being equal, I did not receive spurious conflicts doing that last merge in a single step (2-4, Jamie's way) after all! You say there should be, because that I am remerging changes made to the trunk between the base of A and the base of B. But I can't see where the redundancy should come from. The changes between the start of A and the start of B are not in A, and they are inherent in B. So goes my theory. Perhaps we are making different assumptions? |The only clean way to do this in the general case is to tag branch B |before and after your merge from A at point 3 and merge B back into the |trunk as two merges: | |~cvs up -j 1 -j pre-3 |~cvs up -j post-3 -j 4 ... Oops, yes, you are correct. What I said was correct if point 2 3 were the same (at point 2 all of branch A was merge to both the trunk and branch B). A clean merge to the trunk without conflicts from a repeated merge with distinct points 2 3 would require the two commands I listed above and a third merge: ~cvs up -j 2 -j 3 So if I understand you all correctly, a generalized merge formula would be: cvs update -j start-of-branchB -j pre-3' cvs update -j 2 -j 3 cvs update -j post-3' -j 4 in that order? What if branchB had made changes that would conflict with branchA's changes, and the merge from A to B is to correct that conflict and bring B into sync _before_ it merges with the trunk? Following this pattern, I will still get that conflict between B and the trunk on the first command - even though those conflicts had already been resolved post-3'. Nothing subsequent would work without manually duplicating the conflict resolution already present in B... ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David Wood wrote: |Please correct me if I'm wrong. I _think_ this is the greatest common |ancestor problem. And finding one is actually something CVS does for you |- on the first mege (with a single -j). Which is usually OK in cases where |a branch immediately dies (i.e. becomes dormant) afterwards. | |The problem is that CVS does not remember that a merge took place. After |a merge, the map of ancestry that was built by branch operations is no |longer correct. And from that point on, CVS relies on _you_ to find the |GCA. No. The GCA has not changed and CVS determines it correctly. You simply no longer wish to merge from the GCA forward because some of those changes were already merged to your destination (from another branch and at your own request - CVS did nothing wrong) and you wish to avoid conflicts. Derek - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- 82. Hold a hard drive to your ear -- listen to the C. -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/qRlZLD1OTBfyMaQRAktRAKCetmTi7rGBJ87mND6lK1RzAy+3PwCfZxRn 0puk73j1ydoalv5iv11ph/M= =4TK0 -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
Derek Robert Price [EMAIL PROTECTED] wrote on 11/05/2003 10:38:02 AM: No. The GCA has not changed and CVS determines it correctly. You simply no longer wish to merge from the GCA forward because some of those changes were already merged to your destination (from another branch and at your own request - CVS did nothing wrong) and you wish to avoid conflicts. I am not saying CVS is doing anything wrong; I think it is following its design precisely. I think my problem may be with terminology. If I merge from a child to the trunk, and then I later merge it again, what is the greatest common ancestor on that second merge? Still the beginning of the child? Or is it now point of the first merge? It sounds like you are saying the former - following the strict CVS definition for GCA, that is right. But what about an alternate definition of ancestry based on both branches _and_ merges? Right now to do that second merge I have to tell CVS where to start - it no longer uses its GCA algorithm to figure that out for me. But I am telling it the new common ancestor myself - the point of the previous merge (as opposed to the point of the branch). Isn't this an analogous process to CVS' current GCA? ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
On Wed, Nov 05, 2003 at 08:55:38AM +, Andy Jones wrote: Is it just me, or is this getting way too complex to be usable except by CVS experts? I thought I was comfortable with the issues surrounding branches and merges, even though we are not using branches yet here. But I don't understand half of what you folks are saying. Worse: in my understanding this isn't even a particularly complex case. Let me see if I have this right. You want to merge changes made on a branch back into the main development stream, then merge that with the changes on another branch. Surely **everyone** will need to do this, sooner or later? I think this is actually a somewhat complicated case. An easier one would be having two branches off the trunk and periodically merging them both down to the trunk. I think it's the merge A to B and then B to the trunk that generates the complexity, especially if A and B didn't branch from the same point. More generally, maybe it's the branch-to-branch merge that creates the complexity . . . Handling multiple merges of a single branch down to the mainline is actually quite easy (and more common), execept you have to keep track of the merge points with tags. Andy Jones. Thanks, Jamie Wellnitz At 03:37 am 5/11/03, David Wood wrote: I am not sure about something. |If branch A and branch B in your example don't branch form the same |point on the trunk, a merge from point 2 to point 4 into the trunk might |still not do what you want. If branch B branched first, then 2-4 may |back out changes made to the trunk between the base of B and the base of |A. If A branched first, then 2-4 will attempt to remerge changes made |to the trunk between the base of A and the base of B, causing the same |sort of spurious conflicts you were attempting to avoid. Assume B is branched first. A merges to the trunk. Then A merges to B. Then B merges to the trunk as well. I think the trick here is what happens when A merges to B. If you do that merge like this: (in B's working dir): cvs update -j branchA_CREATED -j 3 (3 == where A merges to B) then you are correct. This merge will be missing changes from between the start of B and A - ALREADY! In other words, with respect to B, part of A was left out, since it was created before branchA_CREATED - on the trunk. But I think this is really the wrong way to merge A into B. The right way is to do it would be to say: cvs update -j branchB_CREATED -j 3 Then branch B does indeed end up incorporating everything from branch A. In other words, the changes on the trunk after B was created until A starts, and then all then all the changes in A. So when doing that kind of merge, always use the newest common ancestor (in this case, the start of B). Now let's look at your other scenario. When A is created before B, everything else being equal, I did not receive spurious conflicts doing that last merge in a single step (2-4, Jamie's way) after all! You say there should be, because that I am remerging changes made to the trunk between the base of A and the base of B. But I can't see where the redundancy should come from. The changes between the start of A and the start of B are not in A, and they are inherent in B. So goes my theory. Perhaps we are making different assumptions? |The only clean way to do this in the general case is to tag branch B |before and after your merge from A at point 3 and merge B back into the |trunk as two merges: | |~cvs up -j 1 -j pre-3 |~cvs up -j post-3 -j 4 ... Oops, yes, you are correct. What I said was correct if point 2 3 were the same (at point 2 all of branch A was merge to both the trunk and branch B). A clean merge to the trunk without conflicts from a repeated merge with distinct points 2 3 would require the two commands I listed above and a third merge: ~cvs up -j 2 -j 3 So if I understand you all correctly, a generalized merge formula would be: cvs update -j start-of-branchB -j pre-3' cvs update -j 2 -j 3 cvs update -j post-3' -j 4 in that order? What if branchB had made changes that would conflict with branchA's changes, and the merge from A to B is to correct that conflict and bring B into sync _before_ it merges with the trunk? Following this pattern, I will still get that conflict between B and the trunk on the first command - even though those conflicts had already been resolved post-3'. Nothing subsequent would work without manually duplicating the conflict resolution already present in B... ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David Wood [EMAIL PROTECTED] writes: Derek Robert Price [EMAIL PROTECTED] wrote on 11/05/2003 10:38:02 AM: No. The GCA has not changed and CVS determines it correctly. You simply no longer wish to merge from the GCA forward because some of those changes were already merged to your destination (from another branch and at your own request - CVS did nothing wrong) and you wish to avoid conflicts. I am not saying CVS is doing anything wrong; I think it is following its design precisely. I think my problem may be with terminology. If I merge from a child to the trunk, and then I later merge it again, what is the greatest common ancestor on that second merge? Still the beginning of the child? Or is it now point of the first merge? If you want to remember the last point at which you did the merge, then you can create a tag for that point. Take a look at the cvs.cvshome.org repository and the cvs1-11-x-branch-last-merge label which we move each time we merge a change from the cvs1-11-x-branch into the trunk. It sounds like you are saying the former - following the strict CVS definition for GCA, that is right. But what about an alternate definition of ancestry based on both branches _and_ merges? Right now to do that second merge I have to tell CVS where to start - it no longer uses its GCA algorithm to figure that out for me. But I am telling it the new common ancestor myself - the point of the previous merge (as opposed to the point of the branch). Isn't this an analogous process to CVS' current GCA? I believe you are describing something different. There is nothing preventing you from renaming the old branch to something else, branching from your current location, and then merging your old-branch changes forward into your new branch. Then the GCA remains correct and cvs does the book-keeping for you. Time 1: cvs tag -b branchA cvs tag -b branchB ... commits to branchA and branchB Time 2: cvs checkout cvs up -jbranchA ... resolve conflicts Time 2': cvs commit cvs tag -b branchAA ... commits to branchA no longer allowed, ... commits continue to branchAA and branchB Time 3: cvs checkout -r branchAA cvs tag -b branchBB cvs checkout -r branchBB cvs up -jbranchB Time 3': cvs commit ... commits to branchB no longer allowed, ... commits continue to branchAA and branchBB Time 4: cvs checkout cvs up -jbranchBB Time 4': cvs commit ... commits to branchBB no longer allowed Now, at such time as branchAA needs to be merged into the trunk, you will have some conflicts to handle, but I believe you can see that your methodology of wanting to use the GCA can be accomodated using cvs, just perhaps not in the manner you might like. Original picture: branchA 23 /-\-\ 1 / \ \ 4' trunk --* \ -* \2' \/ \---*--/-- branchB 3' 4 Revised picture: 3' 4 /-*--* branchBB branchA 2 3/ \ /-\ /--*--- branchAA \ 1 / \/ \4' trunk --*--* \2' \---* branchB 3' Enjoy! -- Mark -BEGIN PGP SIGNATURE- Version: GnuPG v1.2.3 (FreeBSD) iD8DBQE/qTUg3x41pRYZE/gRArcRAKDT9tS5FiNec/f+AjjcAayDLUmDJgCfaRvw WZ/E5Q3T0oxlB2weUIToHwI= =BB7V -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David Wood wrote: |Derek Robert Price [EMAIL PROTECTED] wrote on 11/05/2003 10:38:02 AM: | |No. The GCA has not changed and CVS determines it correctly. You |simply no longer wish to merge from the GCA forward because some of |those changes were already merged to your destination (from another |branch and at your own request - CVS did nothing wrong) and you wish to |avoid conflicts. | | |I am not saying CVS is doing anything wrong; I think it is following its |design precisely. I think my problem may be with terminology. | |If I merge from a child to the trunk, and then I later merge it again, |what is the greatest common ancestor on that second merge? Still the |beginning of the child? Or is it now point of the first merge? | |It sounds like you are saying the former - following the strict CVS |definition for GCA, that is right. But what about an alternate definition |of ancestry based on both branches _and_ merges? | |Right now to do that second merge I have to tell CVS where to start - it |no longer uses its GCA algorithm to figure that out for me. But I am |telling it the new common ancestor myself - the point of the previous |merge (as opposed to the point of the branch). Isn't this an analogous |process to CVS' current GCA? Greatest Common Ancestor, or GCA, is a term that refers to the RCS revision structure and always means the more recent revision two revisions have in common, often a branch point, but in the case of a branch of a branch and the trunk, note that the GCA is on the trunk, not the base revision of the branch, but the base revision of its parent. CVS determines GCA when you only specify one revision in a merge as a convenience for the common case, merging from a branch into its parent. This does not mean that the first revision of a merge specification should always be called a GCA. Yes, it would be convenient if CVS were smart enough to track what data has already been merged to various locations and attempt to intellegently exclude these data sets in following merges. This has been suggested many times in the past. In practice, CVS does not currently keep track of the necessary data and even if it did, the problem is a very hard one. There _are_ reasons a user could wish to specify a merge twice. They accidentally copied old files over the new ones which had contained the merge; another developer removed the merge changes by hand and committed in conjunction with code you do not want removed. etc.Basically, CVS would have a hard time tracking what you manually did to its merge result. If someone were to solve this problem and submit a patch that implemented the solution including documentation and tests cases which addressed these sorts of issues and any others that arose, believe me, I would be one of the first to vote that CVS incorporate the code. Derek - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- Rick: How long was it we had, honey? Elsa: I didn't count the days. Rick: Well I did, every one of them. Mostly I remember the last one. The wow finish. The guy standing on the station platform in the rain with a comical look on his face because his insides had been kicked out. - Humphrey Bogart Ingrid Bergman, _Casablanca_ -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/qTaxLD1OTBfyMaQRAt3BAKDeIjDhRp+rajEaTD30chF3aykn3gCgvYr7 +61vwUYOZrfW7PEdgl9AoQE= =8AGB -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Derek Robert Price wrote: | Greatest Common Ancestor, or GCA, is a term that refers to the RCS | revision structure and always means the *more* recent revision two | revisions have in common, often a branch point, but in the case of a | branch of a branch and the trunk, note that the GCA is on the trunk, not | the base revision of the branch, but the base revision of its parent. Er, *more* above should read most. Derek - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- The only difference between me and a madman is that I am not mad. ~-- Salvador Dali -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/qUKrLD1OTBfyMaQRAhS1AJ9Cp5685KI5PBzxKSA9h0ayvfq5gACgwFsO 5uUJCsQvHN3H/UsfBEN8JJI= =5lDm -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
Derek Robert Price [EMAIL PROTECTED] wrote on 11/05/2003 12:43:14 PM: Greatest Common Ancestor, or GCA, is a term that refers to the RCS revision structure and always means the more recent revision two revisions have in common, often a branch point, but in the case of a branch of a branch and the trunk, note that the GCA is on the trunk, not the base revision of the branch, but the base revision of its parent. So in other words, you are saying: in the case where the branch (child) of a branch (parent) merges back to the trunk (grandparent), the GCA is on the grandparent, at the point where the parent begins. Right? CVS determines GCA when you only specify one revision in a merge as a convenience for the common case, merging from a branch into its parent. This does not mean that the first revision of a merge specification should always be called a GCA. Yes, it would be convenient if CVS were smart enough to track what data has already been merged to various locations and attempt to intellegently exclude these data sets in following merges. This has been suggested many times in the past. In practice, CVS does not currently keep track of the necessary data and even if it did, the problem is a very hard one. There _are_ reasons a user could wish to specify a merge twice. They accidentally copied old files over the new ones which had contained the merge; another developer removed the merge changes by hand and committed in conjunction with code you do not want removed. etc.Basically, CVS would have a hard time tracking what you manually did to its merge result. If someone were to solve this problem and submit a patch that implemented the solution including documentation and tests cases which addressed these sorts of issues and any others that arose, believe me, I would be one of the first to vote that CVS incorporate the code. I am hopeful that someone will be me. My initial approach has been to use a wrapper which executes branches and merges, generating and applying tags in addition to branching and merging, and maintaining extra state data in a database. I believe that the tool has all of the necessary information available; the question now is using it to determine the correct merge start point in a general way. I only intend to support whole branch merges, and I have been under the impression that I can focus solely on eliminating over- and under-merging. I believe cases such as your examples, where it is desirable to double merge, or to deliberately eliminate part of the merge, cannot be handled in a general way - although perhaps you will disagree? My cursory examination of CVS's GCA algorithm leaves me with the impression that it relies on properties of the revision numbering system, which if true makes it abundantly clear why there is no simple path to making CVS smarter about GCA, even if it did have the information about merge activity that it needed. ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Rephrasing: question about merging branches
Let me try to put it another way. I have a parent branch, and it has two child branches. If I want one child to merge to the parent, and then to the other child, how does that other child later merge to the parent as well? Is it (on the parent): update -j first_child_merge_point -j second child If so, what happens to changes from before the first_child_merge_point? -David ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
Sorry for the ascii graphic in advance . . . If you have (* indicates merge point): branchA and branchB originated from trunk at point 1. branchA merged to trunk at point 2 on branchA and 2' on trunk. branchA then merged to branchB at point 3 on branchA and 3' on branchB. Now, we want to merge branchB (point 4) to the trunk (4'). branchA 23 /-\-\ 1 / \ \ 4' trunk --* \ -* \2' \/ \---*--/-- branchB 3' 4 I think you want the common ancestor of the current branchB tip and trunk tip. That would be point2 on branchA. (This is assuming you did a full merges, not just a few changes, from A-trunk and A-B.) So assuming you put tags down to keep track of the merge points, you might try (on the trunk): cvs update -j point2 -j point4 It looks like my point2 is your first child merge point and second child is the tip of branchB (where you put a tag before the merge). Which changes before the first child merge point are you wondering about? Thanks, Jamie Wellnitz [EMAIL PROTECTED] On Tue, Nov 04, 2003 at 11:06:44AM -0500, David Wood wrote: Let me try to put it another way. I have a parent branch, and it has two child branches. If I want one child to merge to the parent, and then to the other child, how does that other child later merge to the parent as well? Is it (on the parent): update -j first_child_merge_point -j second child If so, what happens to changes from before the first_child_merge_point? -David ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
I would say your ascii graphic is admirable! What you are saying matches what I'm seeing in tests, and I think I get it now. I believe my problem has been a silly confusion with the way update -j -j works. I understand a merge between 1 and 4 (and for that matter, a reverse-merge between 4 and 1) well enough. Essentially, I mistakenly envisioned a merge between 3' and 4 - rather than 2 and 4. Hence my fear about loss or mistreatment of changes before the child-to-child merge. I think what all this means is that branchB is now essentially merging against branchA (having received common chagnes by, and resolved conflicts with) branchA... and the merge delta with the trunk must now use branchA (at point 2) as a reference point in order to correctly reflect changes against the trunk. It is potentially confusing, but you have made it seem very simple. Thank you! -David Jamie Wellnitz [EMAIL PROTECTED] wrote on 11/04/2003 11:50:35 AM: Sorry for the ascii graphic in advance . . . If you have (* indicates merge point): branchA and branchB originated from trunk at point 1. branchA merged to trunk at point 2 on branchA and 2' on trunk. branchA then merged to branchB at point 3 on branchA and 3' on branchB. Now, we want to merge branchB (point 4) to the trunk (4'). branchA 23 /-\-\ 1 / \ \ 4' trunk --* \ -* \2' \/ \---*--/-- branchB 3' 4 I think you want the common ancestor of the current branchB tip and trunk tip. That would be point2 on branchA. (This is assuming you did a full merges, not just a few changes, from A-trunk and A-B.) So assuming you put tags down to keep track of the merge points, you might try (on the trunk): cvs update -j point2 -j point4 It looks like my point2 is your first child merge point and second child is the tip of branchB (where you put a tag before the merge). Which changes before the first child merge point are you wondering about? Thanks, Jamie Wellnitz [EMAIL PROTECTED] On Tue, Nov 04, 2003 at 11:06:44AM -0500, David Wood wrote: Let me try to put it another way. I have a parent branch, and it has two child branches. If I want one child to merge to the parent, and then to the other child, how does that other child later merge to the parent as well? Is it (on the parent): update -j first_child_merge_point -j second child If so, what happens to changes from before the first_child_merge_point? -David ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 If branch A and branch B in your example don't branch form the same point on the trunk, a merge from point 2 to point 4 into the trunk might still not do what you want. If branch B branched first, then 2-4 may back out changes made to the trunk between the base of B and the base of A. If A branched first, then 2-4 will attempt to remerge changes made to the trunk between the base of A and the base of B, causing the same sort of spurious conflicts you were attempting to avoid. The only clean way to do this in the general case is to tag branch B before and after your merge from A at point 3 and merge B back into the trunk as two merges: ~cvs up -j 1 -j pre-3 ~cvs up -j post-3 -j 4 Please note that I am using numeric tags in the above example, per the ascii art below, despite the fact that tags that start with a number are invalid. Derek Get CVS support at http://ximbiot.com! David Wood wrote: |I would say your ascii graphic is admirable! | |What you are saying matches what I'm seeing in tests, and I think I get it |now. | |I believe my problem has been a silly confusion with the way update -j -j |works. | |I understand a merge between 1 and 4 (and for that matter, a reverse-merge |between 4 and 1) well enough. | |Essentially, I mistakenly envisioned a merge between 3' and 4 - rather |than 2 and 4. Hence my fear about loss or mistreatment of changes before |the child-to-child merge. | |I think what all this means is that branchB is now essentially merging |against branchA (having received common chagnes by, and resolved conflicts |with) branchA... and the merge delta with the trunk must now use branchA |(at point 2) as a reference point in order to correctly reflect changes |against the trunk. | |It is potentially confusing, but you have made it seem very simple. Thank |you! | |-David | |Jamie Wellnitz [EMAIL PROTECTED] wrote on 11/04/2003 11:50:35 |AM: | |Sorry for the ascii graphic in advance . . . | |If you have (* indicates merge point): | |branchA and branchB originated from trunk at point 1. |branchA merged to trunk at point 2 on branchA and 2' on trunk. |branchA then merged to branchB at point 3 on branchA and 3' on branchB. |Now, we want to merge branchB (point 4) to the trunk (4'). | | branchA 23 |/-\-\ | 1 / \ \ 4' |trunk --* \ -* | \2' \/ |\---*--/-- | branchB 3' 4 | |I think you want the common ancestor of the current branchB tip and |trunk tip. That would be point2 on branchA. (This is assuming you |did a full merges, not just a few changes, from A-trunk and A-B.) |So assuming you put tags down to keep track of the merge points, you |might try (on the trunk): | |cvs update -j point2 -j point4 | |It looks like my point2 is your first child merge point and second |child is the tip of branchB (where you put a tag before the merge). | |Which changes before the first child merge point are you wondering |about? | |Thanks, |Jamie Wellnitz |[EMAIL PROTECTED] | |On Tue, Nov 04, 2003 at 11:06:44AM -0500, David Wood wrote: | |Let me try to put it another way. | |I have a parent branch, and it has two child branches. If I want one | |child | |to merge to the parent, and then to the other child, how does that | |other | |child later merge to the parent as well? | |Is it (on the parent): update -j first_child_merge_point -j second | |child | |If so, what happens to changes from before the | |first_child_merge_point? | |-David | - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- I know of no safe depository of the ultimate powers of the society but the people themselves, and if we think them not enlightened enough to exercise that control with a wholesome discretion, the remedy is not to take it from them, but to inform their discretion. - Thomas Jefferson, 1820. -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/p+98LD1OTBfyMaQRAkYYAJsFs2zGGAUbt4iA5k/o3GxATtu9ZgCfcngq sDzUwcIwQzAV5U0g6Tjo05w= =0iYB -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
On Tue, Nov 04, 2003 at 01:27:09PM -0500, Derek Robert Price wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 If branch A and branch B in your example don't branch form the same point on the trunk, a merge from point 2 to point 4 into the trunk might still not do what you want. If branch B branched first, then 2-4 may back out changes made to the trunk between the base of B and the base of A. If A branched first, then 2-4 will attempt to remerge changes made to the trunk between the base of A and the base of B, causing the same sort of spurious conflicts you were attempting to avoid. The only clean way to do this in the general case is to tag branch B before and after your merge from A at point 3 and merge B back into the trunk as two merges: ~cvs up -j 1 -j pre-3 ~cvs up -j post-3 -j 4 If you do this, are you missing the changes between points 2 and 3 on branchA that should (I think) end up merged to the trunk? Please note that I am using numeric tags in the above example, per the ascii art below, despite the fact that tags that start with a number are invalid. Derek Thanks, Jamie Get CVS support at http://ximbiot.com! David Wood wrote: |I would say your ascii graphic is admirable! | |What you are saying matches what I'm seeing in tests, and I think I get it |now. | |I believe my problem has been a silly confusion with the way update -j -j |works. | |I understand a merge between 1 and 4 (and for that matter, a reverse-merge |between 4 and 1) well enough. | |Essentially, I mistakenly envisioned a merge between 3' and 4 - rather |than 2 and 4. Hence my fear about loss or mistreatment of changes before |the child-to-child merge. | |I think what all this means is that branchB is now essentially merging |against branchA (having received common chagnes by, and resolved conflicts |with) branchA... and the merge delta with the trunk must now use branchA |(at point 2) as a reference point in order to correctly reflect changes |against the trunk. | |It is potentially confusing, but you have made it seem very simple. Thank |you! | |-David | |Jamie Wellnitz [EMAIL PROTECTED] wrote on 11/04/2003 11:50:35 |AM: | |Sorry for the ascii graphic in advance . . . | |If you have (* indicates merge point): | |branchA and branchB originated from trunk at point 1. |branchA merged to trunk at point 2 on branchA and 2' on trunk. |branchA then merged to branchB at point 3 on branchA and 3' on branchB. |Now, we want to merge branchB (point 4) to the trunk (4'). | | branchA 23 |/-\-\ | 1 / \ \ 4' |trunk --* \ -* | \2' \/ |\---*--/-- | branchB 3' 4 | |I think you want the common ancestor of the current branchB tip and |trunk tip. That would be point2 on branchA. (This is assuming you |did a full merges, not just a few changes, from A-trunk and A-B.) |So assuming you put tags down to keep track of the merge points, you |might try (on the trunk): | |cvs update -j point2 -j point4 | |It looks like my point2 is your first child merge point and second |child is the tip of branchB (where you put a tag before the merge). | |Which changes before the first child merge point are you wondering |about? | |Thanks, |Jamie Wellnitz |[EMAIL PROTECTED] | |On Tue, Nov 04, 2003 at 11:06:44AM -0500, David Wood wrote: | |Let me try to put it another way. | |I have a parent branch, and it has two child branches. If I want one | |child | |to merge to the parent, and then to the other child, how does that | |other | |child later merge to the parent as well? | |Is it (on the parent): update -j first_child_merge_point -j second | |child | |If so, what happens to changes from before the | |first_child_merge_point? | |-David | - -- ~*8^) Email: [EMAIL PROTECTED] Get CVS support at http://ximbiot.com! - -- I know of no safe depository of the ultimate powers of the society but the people themselves, and if we think them not enlightened enough to exercise that control with a wholesome discretion, the remedy is not to take it from them, but to inform their discretion. - Thomas Jefferson, 1820. -BEGIN PGP SIGNATURE- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org iD8DBQE/p+98LD1OTBfyMaQRAkYYAJsFs2zGGAUbt4iA5k/o3GxATtu9ZgCfcngq sDzUwcIwQzAV5U0g6Tjo05w= =0iYB -END PGP SIGNATURE- ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs
Re: Rephrasing: question about merging branches
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jamie Wellnitz wrote: |On Tue, Nov 04, 2003 at 01:27:09PM -0500, Derek Robert Price wrote: | |-BEGIN PGP SIGNED MESSAGE- |Hash: SHA1 | |If branch A and branch B in your example don't branch form the same |point on the trunk, a merge from point 2 to point 4 into the trunk might |still not do what you want. If branch B branched first, then 2-4 may |back out changes made to the trunk between the base of B and the base of |A. If A branched first, then 2-4 will attempt to remerge changes made |to the trunk between the base of A and the base of B, causing the same |sort of spurious conflicts you were attempting to avoid. | |The only clean way to do this in the general case is to tag branch B |before and after your merge from A at point 3 and merge B back into the |trunk as two merges: | |~cvs up -j 1 -j pre-3 |~cvs up -j post-3 -j 4 | | |If you do this, are you missing the changes between points 2 and 3 on |branchA that should (I think) end up merged to the trunk? Oops, yes, you are correct. What I said was correct if point 2 3 were the same (at point 2 all of branch A was merge to both the trunk and branch B). A clean merge to the trunk without conflicts from a repeated merge with distinct points 2 3 would require the two commands I listed above and a third merge: ~cvs up -j 2 -j 3 Derek |Please note that I am using numeric tags in the above example, per the |ascii art below, despite the fact that tags that start with a number are |invalid. | |Derek | | |Thanks, |Jamie | |Get CVS support at http://ximbiot.com! | | |David Wood wrote: | ||I would say your ascii graphic is admirable! || ||What you are saying matches what I'm seeing in tests, and I think I get it ||now. || ||I believe my problem has been a silly confusion with the way update -j -j ||works. || ||I understand a merge between 1 and 4 (and for that matter, a reverse-merge ||between 4 and 1) well enough. || ||Essentially, I mistakenly envisioned a merge between 3' and 4 - rather ||than 2 and 4. Hence my fear about loss or mistreatment of changes before ||the child-to-child merge. || ||I think what all this means is that branchB is now essentially merging ||against branchA (having received common chagnes by, and resolved conflicts ||with) branchA... and the merge delta with the trunk must now use branchA ||(at point 2) as a reference point in order to correctly reflect changes ||against the trunk. || ||It is potentially confusing, but you have made it seem very simple. Thank ||you! || ||-David || ||Jamie Wellnitz [EMAIL PROTECTED] wrote on 11/04/2003 11:50:35 ||AM: || ||Sorry for the ascii graphic in advance . . . || ||If you have (* indicates merge point): || ||branchA and branchB originated from trunk at point 1. ||branchA merged to trunk at point 2 on branchA and 2' on trunk. ||branchA then merged to branchB at point 3 on branchA and 3' on branchB. ||Now, we want to merge branchB (point 4) to the trunk (4'). || || branchA 23 ||/-\-\ || 1 / \ \ 4' ||trunk --* \ -* || \2' \/ ||\---*--/-- || branchB 3' 4 || ||I think you want the common ancestor of the current branchB tip and ||trunk tip. That would be point2 on branchA. (This is assuming you ||did a full merges, not just a few changes, from A-trunk and A-B.) ||So assuming you put tags down to keep track of the merge points, you ||might try (on the trunk): || ||cvs update -j point2 -j point4 || ||It looks like my point2 is your first child merge point and second ||child is the tip of branchB (where you put a tag before the merge). || ||Which changes before the first child merge point are you wondering ||about? || ||Thanks, ||Jamie Wellnitz ||[EMAIL PROTECTED] || ||On Tue, Nov 04, 2003 at 11:06:44AM -0500, David Wood wrote: || ||Let me try to put it another way. || ||I have a parent branch, and it has two child branches. If I want one || ||child || ||to merge to the parent, and then to the other child, how does that || ||other || ||child later merge to the parent as well? || ||Is it (on the parent): update -j first_child_merge_point -j second || ||child || ||If so, what happens to changes from before the || ||first_child_merge_point? || ||-David || | |- -- |~*8^) | |Email: [EMAIL PROTECTED] | |Get CVS support at http://ximbiot.com! |- -- |I know of no safe depository of the ultimate powers of the society but |the people themselves, and if we think them not enlightened enough to |exercise that control with a wholesome discretion, the remedy is not to |take it from them, but to inform their discretion. | | - Thomas Jefferson, 1820. |-BEGIN PGP SIGNATURE- |Version: GnuPG v1.0.7 (GNU/Linux) |Comment: Using GnuPG with Netscape - http://enigmail.mozdev.org |
Re: Rephrasing: question about merging branches
I am not sure about something. |If branch A and branch B in your example don't branch form the same |point on the trunk, a merge from point 2 to point 4 into the trunk might |still not do what you want. If branch B branched first, then 2-4 may |back out changes made to the trunk between the base of B and the base of |A. If A branched first, then 2-4 will attempt to remerge changes made |to the trunk between the base of A and the base of B, causing the same |sort of spurious conflicts you were attempting to avoid. Assume B is branched first. A merges to the trunk. Then A merges to B. Then B merges to the trunk as well. I think the trick here is what happens when A merges to B. If you do that merge like this: (in B's working dir): cvs update -j branchA_CREATED -j 3 (3 == where A merges to B) then you are correct. This merge will be missing changes from between the start of B and A - ALREADY! In other words, with respect to B, part of A was left out, since it was created before branchA_CREATED - on the trunk. But I think this is really the wrong way to merge A into B. The right way is to do it would be to say: cvs update -j branchB_CREATED -j 3 Then branch B does indeed end up incorporating everything from branch A. In other words, the changes on the trunk after B was created until A starts, and then all then all the changes in A. So when doing that kind of merge, always use the newest common ancestor (in this case, the start of B). Now let's look at your other scenario. When A is created before B, everything else being equal, I did not receive spurious conflicts doing that last merge in a single step (2-4, Jamie's way) after all! You say there should be, because that I am remerging changes made to the trunk between the base of A and the base of B. But I can't see where the redundancy should come from. The changes between the start of A and the start of B are not in A, and they are inherent in B. So goes my theory. Perhaps we are making different assumptions? |The only clean way to do this in the general case is to tag branch B |before and after your merge from A at point 3 and merge B back into the |trunk as two merges: | |~cvs up -j 1 -j pre-3 |~cvs up -j post-3 -j 4 ... Oops, yes, you are correct. What I said was correct if point 2 3 were the same (at point 2 all of branch A was merge to both the trunk and branch B). A clean merge to the trunk without conflicts from a repeated merge with distinct points 2 3 would require the two commands I listed above and a third merge: ~cvs up -j 2 -j 3 So if I understand you all correctly, a generalized merge formula would be: cvs update -j start-of-branchB -j pre-3' cvs update -j 2 -j 3 cvs update -j post-3' -j 4 in that order? What if branchB had made changes that would conflict with branchA's changes, and the merge from A to B is to correct that conflict and bring B into sync _before_ it merges with the trunk? Following this pattern, I will still get that conflict between B and the trunk on the first command - even though those conflicts had already been resolved post-3'. Nothing subsequent would work without manually duplicating the conflict resolution already present in B... ___ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs