Feature branch workflow
What is a feature branch workflow?
The feature branch workflow is the simplest workflow that involves creating and merging branches.
In the feature branch workflow, when a user needs to commit substantial changes
to the repository, the user initially makes their changes on a separate
dedicated feature branch. That is, the user first creates a dedicated branch,
then makes and commits changes to that dedicated branch. Periodically, the user
syncs that dedicated branch with the trunk. And finally, the user merges that
branch with its changes back into the trunk.
With this workflow, users can benefit from using branches for experimentation
or for collaboration in a larger team. Importantly, this workflow provides an
opportunity for other teammates to review any changes before they are merged
into the trunk, to ensure that the trunk contains only finished and approved
work.
Example scenario
To illustrate this workflow, let’s continue using
the same scenario
as described for the trunk-based workflow. That is, the steps below assume that
you have already checked out a working copy from a conventional single-project
repository to your computer, and this working copy contains a file README.txt
received from the repository.
Step 1: Create a new branch
To create a new branch, do the following:
-
On the command line, navigate into your working copy directory:
C:\Users\Alex> cd my_work_dirC:\Users\Alex\my_work_dir> -
Create a new feature branch by copying
trunk:C:\Users\Alex\my_work_dir> svn copy "^/trunk" "^/branches/my_feature" -m "Create branch my_feature."When you run an
svn copycommand from the working copy, you can use relative URLs, as a shorthand notation for absolute repository URLs. That is, you can start the URL with the caret symbol (^) and then provide a URL relative to the repository’s root.The working copy already knows the absolute URL of the repository’s root directory (e.g.
https://svn.example.com/MyRepo). Therefore,"^/trunk"in the command above will be automatically interpreted as the full repository URL:https://svn.example.com/MyRepo/trunk.
Relevant best practices
The following best practices are relevant on this step:
- A
branch must be a full copy of the trunk. As in the example above,
where the new
my_featuredirectory is a copy of the entiretrunkdirectory. Do not create a new branch from an individual file or from a subdirectory contained in thetrunk. - Create
a branch by making a remote URL to URL copy,
as in the example above. Both arguments in the
svn copymust be repository URLs (or their shorthand versions like"^/trunk"). Do not specify a local path as the first argument (the source) of thesvn copyoperation. Similarly, if you are using the TortoiseSVN GUI client, do not select the ‘Create copy in the repository from: Working copy’ option.
Step 2: Switch the working copy to the newly created branch
Although you have created a new branch on Step 1 of this workflow, your working
copy still reflects the trunk, until you switch to your new branch.
To see what branch the working copy is currently on, run svn info inside your
working copy. Look for the Relative URL.
From the root of your working copy, switch this working copy to the newly
created my_feature branch:
C:\Users\Alex\my_work_dir> svn switch "^/branches/my_feature"
After running this command, this working copy now reflects the my_feature
branch. You can see it for yourself with the svn info command.
While the working copy stays on this branch, any commits you make from this
working copy will affect the my_feature branch, but won’t affect the trunk.
Relevant best practices
The following best practices are relevant on this step:
- Do
not switch subtrees in the working copy. To switch the entire
working copy to another branch (for example to the
my_featurebranch), you must run the switch operation from the root of your working copy. - Be aware that switching preserves your uncommitted changes. Switching might result in a conflict if your working copy has uncommitted changes. Such conflicts occur when the uncommitted local changes overlap with the changes received through the switch operation.
Step 3: Make and commit changes
After Step 2, your working copy is now switched to reflect the my_feature
branch.
Working on a feature branch is essentially the same as working on the trunk,
as described in the trunk-based development workflow.
The difference is that commits you make will now go to the my_feature branch,
which is isolated from the changes that occur on the trunk.
-
If you switched the working copy to this
my_featurebranch long ago, then before making changes it is recommended that you update the working copy. This makes sure that the working copy reflects the latest state of this branch. To do that, runsvn updatefrom the root of your working copy:C:\Users\Alex\my_work_dir> svn updateIf you are the only one working on this branch, you can skip this update. Updating is needed only if multiple people (or you from multiple working copies) are working on this same feature branch.
-
Make any desired changes in your working copy.
For example, you can edit the files contained in the working copy. This substep is essentially the same as Step 2: Make changes in the working copy in the trunk-based development workflow. For more details about making changes in the working copy, see the Make Your Changes, Review Your Changes and Fix Your Mistakes sections in the book Version Control with Subversion.
-
Commit your changes:
C:\Users\Alex\my_work_dir> svn commit -m "My descriptive log message."The changes are committed to the
my_featurebranch.If you are the only one working on this branch, any local changes you make in your working copy will always be relative to the latest contents of this branch in the repository. And so the commit will normally always succeed.
However, if the commit fails and states that the committed files are already out of date, see What if the file being committed is out of date?
Your working copy can stay on the my_feature branch as long as you need. You
can make and commit as many changes as you need to this my_feature branch.
Relevant best practices
The following best practices are relevant on this step:
-
Always tell Subversion when you rename or move an item in the working copy. If you want to rename or move a file or directory within the working copy, rename and move it explicitly with
svn move. That is, you should usesvn moveor its equivalent in the Subversion GUI, to tell Subversion about this renaming or relocation. For example:C:\Users\Alex\my_work_dir> svn move README.txt RENAMED_README.txtIf you rename or move an item to a new location without this, to Subversion it will look as if that previously existing file had gone missing from the working copy, and a new unrelated unversioned file was created in the working copy.
Step 4: Keep your feature branch in sync with trunk
A periodic sync merge prevents your feature branch from lagging too far
behind from what is happening in the trunk. The goal of this sync is to make
this feature branch’s later reintegration into the trunk easier. It is up to you
how often you want to do such syncs.
Let us assume that your working copy is still on the my_feature branch (to
which you switched on Step 2
in this workflow).
To see what branch the working copy is currently on, run the svn info command
in
the working copy.
-
Make sure that your working copy has no uncommitted changes. To do that, run
svn statusfrom the root of your working copy:C:\Users\Alex\my_work_dir> svn statussvn statusmust output nothing, meaning that there aren’t any uncommitted changes in the working copy. If there are any uncommitted changes, you must commit them first. -
Make sure that the files and directories in your working copy are all at the same revision. To do that, run
svn updatefrom the root of your working copy:C:\Users\Alex\my_work_dir> svn update -
Merge
trunkinto your working copy by running the following command from the root of your working copy:C:\Users\Alex\my_work_dir> svn merge "^/trunk"This command merges all the changes that have occurred on
trunksince this branch split off fromtrunkand that have not yet been merged to this branch. The revisions that need to be merged are determined automatically, therefore this is also known as an automatic merge.In TortoiseSVN’s Merge wizard, you can do an automatic merge like that either by leaving the specific range option selected and the field next to it empty, or by selecting the all revisions option.
-
Review the changes that have been merged in.
If there are any conflicts, you need to resolve them, to be able to commit the merge. For more details on conflicts, see the Conflicts page. For details on how to resolve them, see the Handling conflicts chapter. Typically, you should resolve conflicts in the working copy. Sometimes, you might instead decide to cancel the merge by reverting all its changes, and deal with the cause of the conflicts in another way. For example, you may decide to cancel the sync merge, make some changes on the
trunkand then redo the sync merge.If you don’t want to commit the results of the merge for any reason, you can completely (recursively) revert all the changes made by the merge inside your working copy. At any point before you commit this merge, running the following command from the root of the working copy effectively cancels the merge:
svn revert --recursive .If the working copy does not contain any merged changes (besides the automatic modification of the mergeinfo property), because there was nothing to sync from the
trunk, then it is recommended that you cancel (revert) this sync merge completely, to revert the local mergeinfo change. It does not make sense to commit a sync that is accidentally empty and contains only the modified mergeinfo. -
Commit the merged changes to the feature branch. To do that, run
svn commitfrom the root of your working copy:C:\Users\Alex\my_work_dir> svn commit -m "On my_feature: synced the branch with trunk."
If your work on the my_feature branch is not yet finished, return to
Step 3.
Relevant best practices
The following best practices are relevant on this step:
- Merge into a clean and updated working copy. Before a merge, the working copy must contain no uncommitted changes and all the files in the working copy must be at the same revision. This was achieved by means of the first two substeps of Step 4 above.
- Merge
the source branch in full. Run the merge from the root
of your working copy. For example, the command above merges the entire
trunkbranch into the root of your working copy, which holds the entiremy_featurebranch. - Make sure you have sufficient repository permissions. Be sure you have Read access to all of the merge source and Read/Write access to all of the merge target.
- Avoid the ‘2-URL merge’ also called ‘Merge two different trees’. On the command line, avoid using the advanced ‘2-URL merge’, where more than one URL is specified in the merge command. If you use the TortoiseSVN GUI client, avoid the ‘Merge two different trees’ option.
- Do not revert the automatic changes in the svn:mergeinfo property on the root directory of your working copy. One exception is if you are completely (recursively) reverting all the changes received via this merge in the working copy.
- Do not make unrelated changes during a merge. When your working copy contains the results of a merge, avoid making unrelated changes, other than those required to resolve conflicts.
- Commit the merge in full. To ensure that you commit everything, commit from the root of your working copy. Do not commit files separately when committing a merge.
Step 5: Merge (reintegrate) your feature branch into trunk
Once you are satisfied with your work on the my_feature branch, you may want
to merge the my_feature branch back into the trunk. You can do this as follows:
-
While your working copy is still on the feature branch, you must do a final sync merge. That is, perform all the actions from Step 4: Keep your feature branch in sync with trunk one more time, right before performing the remaining actions below. This final sync guarantees that the steps below will go smoothly.
-
After the final sync merge, make sure that your working copy has no uncommitted changes. Running
svn statusfrom the root of your working copy must print nothing:C:\Users\Alex\my_work_dir> svn status -
Switch your working copy to
trunk:C:\Users\Alex\my_work_dir> svn switch "^/trunk" -
Merge your feature branch into the working copy:
C:\Users\Alex\my_work_dir> svn merge "^/branches/my_feature" -
Commit the merged changes to the
trunk:C:\Users\Alex\my_work_dir> svn commit -m "Merged the my_feature branch."If you don’t want to commit the results of the merge, you can completely (recursively) revert all the changes that the merge made inside your working copy. At any point before you commit this merge, running the following command from the root of the working copy effectively cancels the merge:
svn revert --recursive .
Relevant best practices
The following best practices are relevant on this step:
- The feature branch should be fully synced before reintegration. Right before a reintegration merge, do a final sync merge, as mentioned on the substep 1 of this Step 5.
- Do
not switch subtrees in the working copy. As shown in the substep 3 of
this Step 5, to switch the entire working copy to
trunk, make sure to run the switch operation from the root of your working copy. - Merge into a clean and updated working copy. Before a merge, the working copy must contain no uncommitted changes and all the files in the working copy must be at the same revision. This was achieved by the substeps 2 and 3 of Step 5. A switch from the root of the working copy (just like an update) ensures that all the contents of the working copy are from the same revision.
- Merge
the source branch in full. Run the merge
from the root of your working copy. For example, the command above merges the
entire
my_featurebranch into the root of your working copy, which holds the entiretrunk. Never merge individual files or parts of branches. - Make sure you have sufficient repository permissions. Be sure you have Read access to all of the merge source and Read/Write access to all of the merge target.
- Avoid the ‘2-URL merge’ also called ‘Merge two different trees’. On the command line, avoid using the advanced ‘2-URL merge’, where more than one URL is specified in the merge command. If you use the TortoiseSVN GUI client, avoid the ‘Merge two different trees’ option.
- Never resolve conflicts during a reintegrate merge. If a reintegrate merge results in any conflicts, cancel this merge by reverting all changes. Resolve these conflicts on the feature branch via another sync merge, then repeat the reintegrate merge.
- Do not revert the automatic changes in the svn:mergeinfo property on the root directory of your working copy. Unless you are reverting all the changes in the working copy completely.
- Do not make unrelated changes during a merge. When your working copy contains the results of a merge, avoid making unrelated changes, other than those required to resolve conflicts.
- Thorough review is needed for a reintegrate merge. If you are not satisfied with the merged changes, cancel this merge by reverting all changes. Make the necessary corrections on the feature branch, then repeat the reintegrate merge.
- Commit the merge in full. To ensure that you commit everything, commit from the root of your working copy. Do not commit files separately when committing a merge.