Announcement

Collapse
No announcement yet.

Branching a Branch

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Branching a Branch

    Hi


    Id would appreciate some feedback on a topic I haven't found a lot of info on - branching from a branch.

    Basically, we have setup a repository in my workplace that uses the stable trunk approach and we currently have several feature branches that are a couple of months old.
    These branches are scheduled to be released at different times so they are currently merging their changes in a downstream fashion regularly to make sure they integrate ie. nothing is getting merge to trunk at this time.
    The approach we intend to take is to use the next complete feature branch to release to production from and then merge this to trunk so that trunk then always resembles production and is stable.

    I have to create a new feature branch and AM wondering exactly the best place to take it from ie. the trunk or the feature branch that is scheduled to be released before it.
    The reason I'm not considering taking it from trunk is that since we are not merging back to trunk until after a release, the new branch would have to merge a lot of changes from its nearest upstream branch which looks quite a bit different from trunk presently.

    Now, I'm aware that SVN just treats branches as just copies so I know I'm just copying part of the tree in the repository at a particular revision.
    What I'm concerned about are any particular historical issues of creating a branch from another ie. if I create Branch B from by making a copy of Branch A then

    ---------------------------------------------------------------------> Trunk
    | |
    ----------> Branch B |------------> New Branch??
    |
    |--------------New Branch??



    Is it quite normal practice to take a branch from a branch in SVN?
    If I took the New Branch from Branch B above then what are the implications of closing Branch B after it has been released and merged back to Trunk?


    Thanks
    Jon

  • #2
    Anyone...?

    Comment


    • #3
      What you have to consider is how you are going to merge the branches back to trunk.

      Suppose you have trunk and branch A with changes on A that are destined for trunk. It is fine to create branch B from from A and to make changes on B. Where problems will arise is if the changes on B are also destined for trunk. Since some of the A changes are also present on B it is likely that merging A and B to trunk will cause a merge conflict.

      The solution is to branch B from A and then to treat A as the destination for B. Thus B gets merged (with --reintegrate) to A creating a revision on A that consists of the B changes. That revision on A can then get merged to trunk (with --reintegrate) just like any other revision on A.

      Comment


      • #4
        Hi Philip,


        Thanks for taking the time to advise me - I really appreciate your help.

        I think I understand your explanation quite well ie. you are saying that since both A and B are both destined for Trunk, I cannot go from B to Trunk directly without the potential to get myself in a bit of a mess with conflicts.

        After Branch A has been released - I guess from your explanation that - I need to keep it alive until B has also been released, then merge B back to A with --reintegrate and then A to Trunk with --reintegrate - and only then can I delete A and B.

        Trunk
        |
        Branch A
        |
        Branch B


        Perhaps I have over-estimated the sophistication of svn:mergeinfo that was introduced in 1.5+, but can I confirm 1 thing with you please?

        First, please note that we have been merging changes made on A to B up until A had been released and had stopped 'moving'.
        I had assumed that after merging Branch A to Trunk the svn:mergeinfo on Trunk would show that a range of revisions of A had been merged into Trunk.
        Then during the (currently hypothetical) merge of B directly back to Trunk, SVN would take note that the changesets in A that had been merged to Trunk had also been merged to B based on the mergeinfo set on B.

        I thought then that SVN would not attempt to 're-merge' the changes from A that now existed in B again into Trunk?


        Sorry, one other thing:

        If I do a merge from A to Trunk with --reintegrate, I understand from the SVN docs that I cant use A anymore. So would I need to resurrect a new A in order to push B's changes to it and then again do a --reintegrate of A to Trunk with B's changes in it?



        cheers
        Jon
        Last edited by jonjack; 11-06-2011, 08:37 AM.

        Comment


        • #5
          You do not have to merge back to branch A to get branch B back to the trunk. If you want to merge it as smoothly as possible, you should do two things:

          1. Make sure all of branch-A changes are merged into branch-B.
          2. Do a record-only merge from trunk to branch-B in order to block the branch-A to trunk delivery. This prevents the duplicate merge of the branch-A content. So if the branch-A content reintegrated in trunk to create rev 1000, then the blocking merge into branch-B would be: svn merge --record-only -c 1000 ^/trunk

          Then you are all set to merge the rest of trunk into branch-B and reintegrate it into trunk.

          Comment


          • #6
            Originally posted by Steve V View Post
            You do not have to merge back to branch A to get branch B back to the trunk. If you want to merge it as smoothly as possible, you should do two things:

            1. Make sure all of branch-A changes are merged into branch-B.
            2. Do a record-only merge from trunk to branch-B in order to block the branch-A to trunk delivery. This prevents the duplicate merge of the branch-A content. So if the branch-A content reintegrated in trunk to create rev 1000, then the blocking merge into branch-B would be: svn merge --record-only -c 1000 ^/trunk

            Then you are all set to merge the rest of trunk into branch-B and reintegrate it into trunk.
            #


            Thanks for the advice.

            Comment


            • #7
              That's clever, but it doesn't quite work. The problem is changes made to A after B is created (or after the last merge from A to B). Such changes get merged to trunk when A is reintegrated, that's what is wanted. But those changes get reverse merged when B is reintegrated, and that is not wanted. It's not obvious, I did have to write a script to work it out, see attached.

              The reliable way to merge A and B to trunk is to merge one branch through the other and only reintegrate one of A or B to trunk. Either:
              - catchup merge trunk to A
              - reintegrate merge A to trunk
              - keepalive merge A
              - catchup merge A to B
              - reintegrate merge B to A
              - reintegrate merge A to trunk (merging B changes to trunk)
              or
              - catchup trunk to B
              - reintegrate B to trunk
              - keepalive B
              - catchup A to B
              - catchup trunk to B
              - reintegrate B to trunk (merging A changes to trunk)
              Attached Files

              Comment


              • #8
                Originally posted by philip View Post
                That's clever, but it doesn't quite work. The problem is changes made to A after B is created (or after the last merge from A to B). Such changes get merged to trunk when A is reintegrated, that's what is wanted. But those changes get reverse merged when B is reintegrated, and that is not wanted. It's not obvious, I did have to write a script to work it out, see attached.

                The reliable way to merge A and B to trunk is to merge one branch through the other and only reintegrate one of A or B to trunk. Either:
                - catchup merge trunk to A
                - reintegrate merge A to trunk
                - keepalive merge A
                - catchup merge A to B
                - reintegrate merge B to A
                - reintegrate merge A to trunk (merging B changes to trunk)
                or
                - catchup trunk to B
                - reintegrate B to trunk
                - keepalive B
                - catchup A to B
                - catchup trunk to B
                - reintegrate B to trunk (merging A changes to trunk)

                Hell, my brains too small!
                Philip thanks for taking the time to comment and provide more guidance, and the script - I am going to follow your advice.
                However, I still don't get one thing on the reverse merge issue you raised - as Steve said - as long as branch A's changes have all been merged across to B (ie. all changesets in A that were reintegrated to trunk have also been merged to B) - when B gets re-integrated to trunk as per Steve's method - how can A's changes get reversed? They will still be merged to trunk as part of the branch B re-integration right?


                cheers for all the help
                Jon

                Comment


                • #9
                  Reintegrate is special type of merge. Essentially it is a request to make the destination look like the source with the assumption that everything on the destination as far as the catchup revision has been merged to the source. The "fake" keepalive merge, the record-only merge from trunk to B, is a lie because some of the revisions covered by that merge are not present on B. When reintegrate encounters the differences created by those missing changes it treats them like any other difference between B and trunk: it generates a diff to make trunk look like B.
                  Last edited by philip; 11-11-2011, 08:58 AM. Reason: Fix my confusion: keepalive, not catchup

                  Comment


                  • #10
                    I am having the same requirement. I tried some sample scenarios and found that the merge info is also getting updated. So could you plz confirm whether the following approach will work for the same.
                    1. Create branch B from branch A
                    2. Make modifications in both A and B
                    3. Merge branch A to Trunk and delete it
                    4. Get all changes from Trunk to B which will get all changes of branch A
                    5. Merge B to trunk

                    Thanks,
                    S.K.Ashok

                    Comment

                    Working...
                    X