Subversion is an open source version control system, it manages files and directories over time. It is like an ordinary file server, which records each and every change made to it.
The central repository has all the data in predefined format i.e. a tree structure , this allows the user to see all the changes made to it any time. And also user can recover any previous version of that project code.
This tutorials explains everything you need to know about SVN merge. This explains the basics of merging, how to merge two branches, how to merge with trunk, and reintegrating a branch using examples.
1. SVN Repository Layout
Before we jump into merge commands, let us review the repository layout. On a very high-level, the following is the tree structure layout SVN uses to store data.
When you do a svn list on the repository, you’ll see this structure as shown below.
# svn list http://192.168.101.1/Repository/ branch/ tags/ trunk/
A branch contains copy of the trunk files and directories. Multiple users will have their own copies in this directory as shown below.
# svn list http://192.168.101.1/Repository/branch/ john/ raj/ laura/ jason/
Tags can also be referred as milestone. This is a check-point to indicate that our project has reached a certain point. You can use this to mark various releases.
# svn list http://192.168.101.1/Repository/tags SYS_310_RETAG/ SAT_313/ RELEASE_3_0_0_SYSTEM/ RELEASE_3_1_0_SYSTEM/ RELEASE_3_1_1_SYSTEM/
Trunk is the main folder containing all the data. This is the main line of development as shown below.
# svn list http://192.168.101.1/Repository/trunk C-Control-Center/ KSS/
If you are new to SVN, the most frequently used SVN command might give you a jump-start.
Merge Two Branches
Let us first understand the need of merging.
Suppose user A and user B are working on a same project. A is working on feature A , editing file1.c. B is working on feature B, editing file2.c. After one week, user B might be ready with the work, and ready to merge and compile the code.
In this case, we will be merging two branches (i.e your working copy and other branch). You need to reflect B’s changes to the file2.c in your working copy.
2. Merge Range of Revision, Working Copy and Other Branch
In this case, you need to specify the range of revisions to be merged. If in the past you merged till release 102, then in the merge command your starting revision point needs to be 103 as shown below.
# svn merge http://192.168.101.1/Repository/branch/KSS/BUILD/SERVER/conf/kss -r103:HEAD U src/Client.cpp U src/Stub.h U src/Ims.h A src/Soap.cpp A src/Soap.h U src/ims.h U src/Soap.hpp U src/Makefile.
The output log shows files with their status:
- ‘U’ means this file has been updated i.e. the working copy changes is retained and B’s changes has been added to the local working copy.
- ‘A’ means any file added to the B’s working copy folder has been added to you working copy folder.
This seems quite easy, but sometimes it’s not. Let us check what problems one can encounter during merging process, as shown in the example below.
# svn merge http://192.168.101.1/Repository/branch/user/KSS/BUILD/SERVER/conf/kss -r103:HEAD U src/Client.cpp U src/Stub.h C src/Ims.h C src/Soap.cpp A src/Soap.h U src/ims.h U src/Soap.hpp U src/Makefile.
In the above output log, the ‘C’ status before file Ims.h , Soap.cpp means CONFLICT.
This is a case of file conflict, it means in this file both user A and user B have modified same lines of code. In this case, SVN doesn’t know which version of file it should keep.
You need to resolve this conflict issue. i.e. Manually open both files and see which version you want to keep, and only then merge will be completed.
3. Merge Changes of Two Branches to Your Branch
Suppose there is user ‘C’ who wants to compile the complete project. User C needs to get the changes done by ‘A’ and ‘B’ in his local working copy, by executing the following command from C’s working copy folder:
# svn merge http://192.168.101.1/Repository/branch/user/HSS/BUILD/SERVER/uma/ http://192.168.101.1/Repository/branch/user2/HSS/BUILDSERVER/uma/ A modules/test/pass A modules/test/pass/testgrp.txt U modules/test/pass/testmust.txt U modules/test/pass/negnum.txt U firstname.lastname@example.org U modules/test/pass/testfalse.txt U email@example.com
The difference of two branches will be applied to the target branch. If target branch (third argument) is not provided, then default target will be the current directory.
4. Merge a Specific Revision of Trunk with Working Copy
Let us first understand the significance of this. Suppose there is a function in your branch that depends on another function and the other function was implemented by user ‘B’, and B has merged this code to trunk in version892.
In this case, you can take changes specific to this function (version892) as shown below.
# svn merge -c 892 http://192.168.101.1/Repository/branch/user/KSS/BUILD/PROV_ONLY/ --- merging r892 into '.': U src/META-INF/wsdl/DSA.wsdl U src/META-INF/wsdl/1.0.wsdl U src/META-INF/wsdl/xml.xsd U src/META-INF/wsdl/tension.xsd
5. Undo Changes Caused by Previous Merge
If you want to undo any changes caused by previous merge operation, just add ‘-’ sign before version no in previous command.
For example, if you want to reverse the changes caused by version 892, do the following:
# svn merge -c -892 http://192.168.101.1/Repository/branch/user/KSS/BUILD/PROV_ONLY/ Reverse-merging r892 into '.': U src/META-INF/wsdl/DSA.wsdl U src/META-INF/wsdl/1.0.wsdl U src/META-INF/wsdl/xml.xsd U src/META-INF/wsdl/tension.xsd
Now see the case where A doesn’t communicate with B. after completing any feature what B does is, he commits the code to trunk. Then whenever A wants he will merge the code with trunk in this way he will get the updated code in his branch and then he can commit the code to his branch and trunk.
6. Merge Your Code with Trunk
To understand this, let us see what kind of problem we’ll encounter during the following merge process.
# svn merge http://192.168.101.1/Repository/trunk/KSS/BUILD/SERVER/conf/kss -r103:HEAD svn: E195020: Cannot merge into mixed-revision working copy [357:378]; try updating first
This error occurs when your working copy is of different revisions. To fix this, first update your working copy with trunk, which will get the latest version.
# svn update U src/Soap.h U src/Soap.cpp Updated to revision 2282.
After the update, when you merge, your merge with trunk will work without any issues as shown below.
# svn merge http://192.168.101.1/Repository/branch/user/KSS/BUILD/SERVER/conf/kss -r103:HEAD U src/Client.cpp U src/Stub.h U src/dependencies U src/Soap.cpp U src/Soap.h U src/ims.h U src/Soap.hpp U src/Makefile.
7. Reintegrate a Branch
After you have merged your code with the trunk, your working copy is in sync with the trunk. But, your working copy changes hasn’t been made to trunk yet.
So, the process of reflecting your changes back to trunk will be done by using reintegrating option as explained in the below steps.
First, you have to commit your code to your branch.
# svn commit -m "makeallchages" Sending build.xml Transmitting file data . Committed revision 2285.
Next, checkout a fresh project code from trunk, or you can use any local copy of trunk but ensure that it is in sync with the trunk.
# svn co http://192.168.101.1/RancoreHssRepository/trunk PROV_ONLY/ A PROV_ONLY/applet.policy A PROV_ONLY/lib A PROV_ONLY/lib/beans-binding A PROV_ONLY/lib/beans-binding/beansbinding-1.2.1.jar A PROV_ONLY/lib/JAXB-ENDORSED/jaxb-api.jar A PROV_ONLY/lib/nblibraries.properties A PROV_ONLY/lib/conf.xml A PROV_ONLY/config.ini
Now, you can execute svn merge command with reintegrate option to reflect all the changes of your working copy, but you need to execute this command from within trunk working copy folder.
# cd PROV_ONLY # pwd /home/santosh/l/PROV_ONLY # svn merge --reintegrate http://192.168.101.1/Repository/branch/user/KSS/BUILD/SERVER/ --- Merging differences between repository URLs into '.': U PROV_ONLY/lib/conf.xml U PROV_ONLY/config.ini
After we have successfully reflected back the branch changes to trunk, you can tag this branch. Tagging is nothing but copying this project folder to tags folder.
# svn commit 'reintegrating changes bck to trunk' Sending Sending conf.xml Sending config.ini Transmitting file data .. Committed revision 2286