Both sides previous revision
Previous revision
Next revision
|
Previous revision
|
dev:branching [2009/08/25 18:24] msjulie revert |
dev:branching [2022/05/06 16:07] (current) |
======Working with branches====== | ======Working with branches====== |
| |
| **//OBSOLETE//** |
| |
If you would like to play in developing something new, which may potentially break the software, create a new branch to play with. | These instructions have been superseded by [[dev:Using git]]. |
| |
=====1 Creating a new branch===== | **//OBSOLETE//** |
| |
| NOTE: The rosegarden svn URL on sourceforge has changed. This page has only been partially updated to reflect that. Usually it is simply a matter of replacing all |
| |
| https://<user>@rosegarden.svn.sourceforge.net/svnroot/rosegarden |
| |
| with |
| |
| svn+ssh://<user>@svn.code.sf.net/p/rosegarden/code |
| |
| Keep this in mind while reading this page... |
| |
| ===== When to branch? ===== |
| To branch or not to branch? |
| |
| The decision whether to branch or not is not really something that follows a strict formula, but you should consider doing your work in a branch if it: |
| |
| * involves disabling a lot of code in order to work through a problem step by step until it is finally solved |
| * is an experimental idea that might not be an improvement, or might not be workable after all |
| * is something big and new that might require design modification before everyone can agree on including it in trunk/ |
| * is anything likely to interfere with another developer's work while you tinker with it |
| * if you ever plan to commit code in a broken, non-working state during your development process |
| |
| Of these, the only really critical and absolute rule is that you must always exercise all possible caution to try to avoid breaking trunk/, and if you ever anticipate committing half-working code, you should almost certainly do this in a branch. |
| =====Moving existing code into a branch===== |
| |
| The best practice is to think everything out before you begin, realize that you will need to work in a branch, create that branch, and do all your work in there from the beginning. |
| |
| In reality, it is very common for a developer to begin some project without thinking all of this through for one reason or another. Perhaps what was supposed to be simple has turned out to be much more complicated than expected. Maybe a quick hour of code to knock something out is going to turn into a week or more before all the unexpected problems can be sorted out. Sometimes, you will even begin working from and committing to trunk/ without realizing that your work really should have been done in a branch first, and someone will ask you to branch and complete your work there; merging it after whatever controversy is resolved to everyone's satisfaction. |
| |
| This is simple to deal with, if this every happens to you. Simply take a patch of your current working copy before you proceed with creating a branch and checking it out. |
| |
Create a new branch by copying the trunk. For example, for a branch called my_branch, do the following (as a single one-line command): | |
<code> | <code> |
svn copy https://<user>@rosegarden.svn.sourceforge.net/svnroot/rosegarden/trunk/rosegarden \ | svn diff > <patch_my_branch> |
https://<user>@rosegarden.svn.sourceforge.net/svnroot/rosegarden/branches/<my_branch> | |
</code> | </code> |
You can see what branches already exist (so as to get ideas for a new name, perhaps) using | |
| //Note:// Replace <patch_my_branch> with a real filename of your choosing |
| |
| To avoid causing yourself problems down the line, now that you have taken this patch to use later, you should revert these changes from your working copy of trunk/ before continuing. |
<code> | <code> |
svn ls https://<user>@rosegarden.svn.sourceforge.net/svnroot/rosegarden/branches/ | patch -R -p0 < <patch_my_branch> |
</code> | </code> |
//Note//: Replace <user> with your sforge username and <my_branch> with the branch you are working. | |
| |
=====2 Checking out a branch===== | You can double check that everything worked properly by running |
| |
<code> | <code> |
svn co https://rosegarden.svn.sourceforge.net:/svnroot/rosegarden/branches/<my_branch> | svn diff |
</code> | </code> |
| |
The full command to checkout <my_branch> using username is: | This should produce no output. |
| |
| //Note// This technique works very well if all of your modifications were to files that were already under version control. If you have already started adding new files, but have not yet put any of them under version control, they will not be included in your patch, and you will need to keep up with them and move them into your working copy of your new branch later on. Unfortunately, svn diff is of no help in this situation. |
| =====Creating a new branch===== |
| |
| Whether you are beginning completely from scratch, or you are creating a branch out of existing work you began in trunk/, the next step in this process is to create the branch itself in the Subversion repository. |
| |
| Create a new branch by copying trunk/. For example, for a branch called <my_branch>, do the following (as a single one-line command): |
| <code> |
| svn copy svn+ssh://<user>@svn.code.sf.net/p/rosegarden/code/trunk/rosegarden \ |
| svn+ssh://<user>@svn.code.sf.net/p/rosegarden/code/branches/<my_branch> |
| </code> |
| You can see what branches already exist (so as to get ideas for a new name, perhaps) using |
| <code> |
| svn ls http://svn.code.sf.net/p/rosegarden/code/branches/ |
| </code> |
| |
| (Or you can browse the online Subversion repository at http://sourceforge.net/p/rosegarden/code/) |
| |
| //Note//: Replace <user> with your SourceForge username and <my_branch> with your branch name. |
| |
| =====Checking out a branch===== |
<code> | <code> |
svn co <my_branch> | svn co <my_branch> |
</code> | </code> |
//Note//: Replace Replace <user> with your sforge username and <my_branch> with your branch name. | |
| The full command to checkout my_branch using username is: |
| <code> |
| svn checkout svn+ssh://<user>@svn.code.sf.net/p/rosegarden/code/branches/<my_branch> <my_branch> |
| </code> |
| //Note//: Replace <user> with your SourceForge username and <my_branch> with your branch name. |
| |
After the checkout completes, take note of the revision number for later, so you don't have to dig it back up when it comes time to merge. The last message from Subversion will tell you this piece of information, for example: | After the checkout completes, take note of the revision number for later, so you don't have to dig it back up when it comes time to merge. The last message from Subversion will tell you this piece of information, for example: |
</code> | </code> |
| |
=====3 Committing changes to the branch===== | =====Applying your patch===== |
| |
| If you took a patch of the work you began in trunk/ then now is the time to apply that patch to your new working copy of your new branch. Simply use |
| |
| <code> |
| patch -p0 < <patch_my_branch> |
| </code> |
| |
| //Note:// Be sure not to use the **-R** option in the patch command this time. Replace <patch_my_branch> with the real filename you selected earlier. |
| |
| If you created any files that were not yet under version control, and were not included in that patch, now is the time to move them across into this directory. |
| |
| Now you are ready to commit the beginning of your new branch, and get to work in here! |
| |
| =====Committing changes to the branch===== |
| |
Working with branches is as easy as working with the trunk. Commit the changes from the root directory of the branch. | Working with branches is as easy as working with the trunk. Commit the changes from the root directory of the branch. |
<code> | <code> |
cd my_branch | cd <my_branch> |
svn commit -m "Text which describes the updates." | svn commit -m "Text which describes the updates." |
</code> | </code> |
| |
=====4 Merging changes from a branch to trunk===== | =====Merging changes from a branch to trunk===== |
| |
For most branches, you want to keep the merge as simple as possible, and only do this once. Chris Cannam recommends ignoring trunk/ until you are ready to merge, and then doing the merge starting by taking a temporary working copy of trunk/ to get started: | For most branches, you want to keep the merge as simple as possible, and only do this once. Chris Cannam recommends ignoring trunk/ until you are ready to merge, and then doing the merge starting by taking a temporary working copy of trunk/ to get started: |
</code> | </code> |
| |
=====5 Merging changes from trunk to the branch===== | =====Merging changes from trunk to the branch===== |
| |
If you are going to be working on the branch for a long time, you may wish to reduce the number of conflicts you may eventually have to resolve by periodically merging from trunk/ into your branch, and then merging the branch back at the end of its lifecycle. | If you are going to be working on the branch for a long time, you may wish to reduce the number of conflicts you may eventually have to resolve by periodically merging from trunk/ into your branch, and then merging the branch back at the end of its life cycle. |
| |
You may check the Last Changed revision of the branch with command | You may check the Last Changed revision of the branch with command |
Note that such a committing does not work if you had conflicts, therefore, resolve conflicts before committing changes. | Note that such a committing does not work if you had conflicts, therefore, resolve conflicts before committing changes. |
| |
=====6 Resolving conflicts===== | =====Resolving conflicts===== |
| |
| A conflict occurs when you try to update your working copy from a repository that has conflicting changes in it. This can happen during the normal course of development, when two different people happen to work in the same place. (One common circumstance is that developer C commits broken changes, and both developers A and B rush in with two slightly different, conflicting fixes.) |
| |
| During a merge, this happens when your branch changes some part of the code that also changed in trunk/, and Subversion cannot decide how to put all the pieces together. |
| |
| When you experience a conflict (such as the real conflict upon which I'm basing this example), recent versions of Subversion will prompt you what to do: |
| |
In the case of a conflict, there will be 'C' in the place of the file which contained conflicts. | |
<code> | <code> |
C foo.c | Conflict discovered in 'data/rc/rosegardenui.rc'. |
| Select: (p) postpone, (df) diff-full, (e) edit, |
| (h) help for more options: |
</code> | </code> |
Such a file will be split into several parts. | |
| Chris recommends that you just choose **p** to postpone conflict resolution. (For binary conflicts, you will also get **tf** and **mf** for "theirs full" and "mine full" respectively. Which to choose will depend entirely on the circumstances.) |
<code> | <code> |
foo.c | (h) help for more options: p |
foo.c.r8115 | --- Merging r10774 through r10874 into 'data/rc': |
foo.c.r8119 | C data/rc/rosegardenui.rc |
foo.c.working | |
</code> | </code> |
After you have resolved conflicts, remove the extra files and commit the changes. | |
| After the conflict, you wind up with several files, similar to these: |
| |
| | file | description | |
| |rosegardenui.rc | original file with alternatives written in | |
| |rosegardenui.rc.merge-left.r10773 | changes from the left revision (-r[left]:[right]) | |
| |rosegardenui.rc.merge-right.r10874 | changes from the right revision (-r[left]:[right]) | |
| |rosegardenui.rc.working | your previous working copy | |
| |
| Chris works with the plain .c file, which is the original file with the conflicts given in an "alternatives" diff-like form, such as this excerpt: |
<code> | <code> |
rm foo.c.* | <Action name="file_revert"/> |
svn commit -m "merge from trunk" | </enable> |
| </State> |
| |
| <<<<<<< .working |
| <State name="have_project_packager"> |
| <enable> |
| <Action name="file_import_project"/> |
| <Action name="file_export_project"/> |
| </enable> |
| </State> |
| |
| ======= |
| >>>>>>> .merge-right.r10874 |
| <State name="have_segments"> |
| <enable> |
| <Action name="move"/> |
</code> | </code> |
| |
=====7 Closing a branch===== | In this case, I apparently removed some code from part of the file that simultaneously changed in trunk/ and Subversion got confused. I can't remember what I did where, or who did what, so while Chris recommends working only with the plain .c file, I have found I can't figure out what I'm looking at in this case. |
| |
| I decided to have a look with Kompare. |
| |
| <code> |
| kompare rosegardenui.rc.merge-left.r10773 rosegardenui.rc.merge-right.r10874 |
| </code> |
| |
| {{:dev:kompare.jpeg|}} |
| |
| I find the visual presentation easier for getting a real sense of what's going on, although the particular example I happened to have chosen to present here (because it was the first one I had at hand) is not particularly good. This conflict is easy to resolve. |
| |
| In any case, once you have discovered what is going on to your satisfaction, edit the file until you're happy with it, then run |
| |
| <code> |
| svn resolved <filename> |
| </code> |
| |
| to tell Subversion that you have resolved the conflict. |
| |
| Test and commit. |
| |
| =====Closing a branch===== |
| |
When a branch is finished with, we usually either delete it if it was very short-lived and uninteresting, | When a branch is finished with, we usually either delete it if it was very short-lived and uninteresting, |
</code> | </code> |
| |
| =====Example of a planned and focused branch ===== |
| |
| * [[dev:notation_toolbar_2|Notation Toolbar Branch]] |