SVN Merge
SVN Merge
The SVN book and in particular the Chapter on branching and merging are highly recommended
The brief documentation below assumes you have read and understood this Chapter, and the summary provided by :
svn help merge
For clarity two environment variables are used in the below description :
DYW | path to the working copy of your development branch |
DYBSVN | URL of IHEP SVN repository http://dayabay.ihep.ac.cn/svn/dybsvn |
For definiteness real paths and URLs are used, clearly they must be changed to match your branch.
Understanding SVN Merge
The key to understanding what svn merge is going to do is to realise that the arguments boil down to a specification of two directory trees (usually at different revisions) which are compared, and the differences are applied to the working copy in the directory from which you issued the command.
Caution on Merge usage
It is very easy to specify two trees that do not make any sense to compare, or otherwise mess up the merge command. This can very easily result in the loss of all your local modifications. Due to this you should always follow the below precautions :
- ensure your working copy is clean before doing a merge ; this allows you to svn revert if things go wrong
- do --dry-run merges before doing real ones
Clean working copy
Clean working copy means that there are no(or very few) local changes compared to a revision in the repository. Meaning that all your modifications are safely in the repository on your branch and hence cannot be lost. A reasonably clean example :
svn status -u ? Test/UnitTest/cmt/tmp ? External/ROOT/cmt/fragments/rootcint.orig M 1732 External/ROOT/cmt/fragments/rootcint ? External/SITE/cmt/requirements ? External/SITE/cmt/requirements.G1 ? External/GEANT/cmt/requirements.orig M 1732 External/GEANT/cmt/requirements ? include
When fully clean the state of the working copy can be expressed by a single integer.
cd $DYW svnversion 1732M ## mixed revision, as local changes are not checked in
It is preferable for the working copy to be clean, in order to avoid confusion on merging and leave open the possibility to revert if things go wrong. To clean your working copy :
- check in svn ci any local changes
- AND ALSO update your working copy svn update
Following this svnversion should return a single integer corrresponding to the revision number.
Propagate developments from the trunk onto your branch
Sometime after branching, you find you need to update to keep in step with other peoples work on the trunk. Do this using svn merge . First assess the changes that have happened on the trunk since you branched, and also the changes on your branch (you may have done some merges previously and forgot about them) :
Check your branch
- Go to your working copy and verify its location in the repository,
cd $DYW svn info > Path: . > URL: http://dayabay.ihep.ac.cn/svn/dybsvn/legacy/branches/legacy-blyth > Repository Root: http://dayabay.ihep.ac.cn/svn/dybsvn > ...
- Also check the cleanliness of the working copy
svn status -u svnversion
if unclean then make it clean as described above.
- Look at the history of the branch back to its creation, the last entry provides the revision number NTU|dybsvn|r1621 at which this branch was created via a copy from the trunk.
svn -v --stop-on-copy log
Check the trunk
- Check whats happened on the trunk since your branched
svn log -v -r1621:HEAD $DYBSVN/legacy/trunk
you can also use the web interfaces to view this information, eg by looking at NTU|dybsvn|log:/legacy/trunk
Plan your branch updates
Decide which changes you want to propagate onto your branch, and identify the revision ranges and/or paths that can select these changes. Do some --dry-run merges to ensure that the changes to your working copy are the intended ones,
- For example to just propagate two changes: NTU|dybsvn|r1628 NTU|dybsvn|r1629 from the trunk URL onto the branch working copy, use the revision range 1628 - 1 : 1629 .
cd $DYW svn merge --dry-run -r 1627:1629 $DYBSVN/trunk A G4dyb/include/dywGSD.h A G4dyb/include/dywHitGSD.h A G4dyb/src/dywGSD.cc A G4dyb/src/dywHitGSD.cc A G4dyb/src/dywConstructFarSitePool0.cc
- look at the status reported by the dry run, look especially for conflicts indicated by C which indicate that overlapping changes have occurred both to the trunk version and your working copy version , and you will need to do some manual conflict resolution in order to complete the merge.
- if there are a large number of conflicts you might wish to refactor your changes to avoid the maintenance overhead now and over the life of your code
Perform the updates
Preform the merge without the --dry-run and do any necessary conflict resolution db:ConflictResolution
Propagate developments from your branch back to the trunk
Eventually it becomes time to share your developments with your colleagues by merging back to the trunk for everyone to use. The svn mechanics of this are exactly the same as propagating from the trunk into your branch, however the consequences of getting things wrong are more embarrassing !
Check the trunk
Steps to do this
- check out the trunk into a directory beside your branch, called trunk
cd $DYW/.. svn co $DYBSVN/legacy/trunk
- if reusing a prior checkout ensure that its uptodate
cd $DYW/../trunk svn status -u svn update ## if needed
- verify that the trunk working copy is at a clean revision, svnversion should return with a single integer (without M)
cd $DYW/../trunk svn info ## verify location in repository svnversion ## verify cleanliness > 1732
Check your branch
- check that your branch is in its intended state , look for non-committed modifications in your working copy area(s)
cd $DYW svn status -u
- consider if any modifications may be useful to others , if so svn add and svn ci them to your branch
- look at the history of your branch since birth, note the birth revision (corresponding to the copy from the trunk) NTU|dybsvn|r1621 and also look for any merges from the trunk NTU|dybsvn|r1636
cd $DYW svn -v --stop-on-copy log
the web interfaces can be used also, NTU|dybsvn|log:/legacy/branches/legacy-blyth
Dry-run merges
Do --dry-run merges from your branch in the repository to the trunk working copy in order to plan the merge command or commands you will use.
- Assess all changes made to your branch since its creation
cd $DYW/../trunk svn merge --dry-run -r 1621:HEAD $DYBSVN/legacy/branches/legacy-blyth U DataStructure/MCEvent/include/dywGLEvent.hh U DataStructure/MCEvent/include/dywGLPhotonHitData.hh U DataStructure/MCEvent/src/dywGLPhotonHitData.cc U DataStructure/MCEvent/src/dywGLEvent.cc U G4dyb/app/dyw.cc A G4dyb/include/dywFakeSD.hh U G4dyb/include/dywSeedReader.hh A G4dyb/include/dywGSD.h ### ???? A G4dyb/include/dywMacroLine.hh U G4dyb/include/dywUtilities.hh A G4dyb/include/dywDetectorEditor.hh U G4dyb/include/dywXMLReader.hh U G4dyb/include/dywPrimaryGeneratorAction.hh U G4dyb/include/dywHit_PMT.hh A G4dyb/include/dywSensitiveSkinEdit.hh A G4dyb/include/dywHitGSD.h ### ??? A G4dyb/include/dywG4Helper.hh U G4dyb/include/dywAnalysisManager.hh U G4dyb/include/dywDetectorConstruction.hh A G4dyb/include/dywEdit.hh A G4dyb/include/dywUImessenger.hh A G4dyb/src/dywG4Helper.cc A G4dyb/src/dywGSD.cc ##### ???? A G4dyb/src/dywHitGSD.cc ###### ???? U G4dyb/src/dywDetectorConstruction.cc A G4dyb/src/dywEdit.cc A G4dyb/src/dywFakeSD.cc U G4dyb/src/dywGenerator2.cc U G4dyb/src/dywUtilities.cc U G4dyb/src/dywXMLReader.cc A G4dyb/src/dywSensitiveSkinEdit.cc U G4dyb/src/dywAnalysisManager.cc A G4dyb/src/dywUImessenger.cc U G4dyb/src/dywGeneratorMessenger.cc A G4dyb/src/dywMacroLine.cc A G4dyb/src/dywConstructFarSitePool0.cc ####### ???? A G4dyb/src/dywDetectorEditor.cc U G4dyb/src/dywPrimaryGeneratorAction.cc A G4dyb/src/dywConstructEditor.cc U G4dyb/src/dywHit_PMT.cc A G4dyb/data/xml/edit A G4dyb/data/xml/edit/sensitive_skin_defaults.xml A G4dyb/data/xml/edit/sensitive_skin.xml
- investigate any files listed that you dont think you made changes to ... usually a forgotten prior merge from the trunk
A G4dyb/include/dywGSD.h ### surprised that this is here with '''A''' ??? A G4dyb/include/dywHitGSD.h ### ??? A G4dyb/src/dywGSD.cc ##### ??? A G4dyb/src/dywHitGSD.cc ###### ???? A G4dyb/src/dywConstructFarSitePool0.cc ####### ????
it is not recommended to re-merge again, so split the planned merge into multiple commands or adjust the revision range to avoid the prior merge.
- check what the changes actually are using svn diff or use one of the web interfaces.
svn diff -r 1636:HEAD $DYBSVN/legacy/branches/legacy-blyth/G4dyb/include/dywSeedReader.hh Index: dywSeedReader.hh =================================================================== --- dywSeedReader.hh (revision 1636) +++ dywSeedReader.hh (revision 1732) @@ -40,4 +40,4 @@ }; -#endif \ No newline at end of file +#endif
- as the former merge from trunk was the first revision made to the branch, it can be avoided by adjusting the revision range.
cd $DYW/../trunk svn merge --dry-run -r 1636:HEAD $DYBSVN/legacy/branches/legacy-blyth U DataStructure/MCEvent/include/dywGLEvent.hh U DataStructure/MCEvent/include/dywGLPhotonHitData.hh U DataStructure/MCEvent/src/dywGLPhotonHitData.cc U DataStructure/MCEvent/src/dywGLEvent.cc U G4dyb/app/dyw.cc A G4dyb/include/dywFakeSD.hh U G4dyb/include/dywSeedReader.hh A G4dyb/include/dywMacroLine.hh U G4dyb/include/dywUtilities.hh A G4dyb/include/dywDetectorEditor.hh U G4dyb/include/dywXMLReader.hh U G4dyb/include/dywPrimaryGeneratorAction.hh U G4dyb/include/dywHit_PMT.hh A G4dyb/include/dywSensitiveSkinEdit.hh A G4dyb/include/dywG4Helper.hh U G4dyb/include/dywAnalysisManager.hh U G4dyb/include/dywDetectorConstruction.hh A G4dyb/include/dywEdit.hh A G4dyb/include/dywUImessenger.hh A G4dyb/src/dywG4Helper.cc U G4dyb/src/dywDetectorConstruction.cc A G4dyb/src/dywEdit.cc A G4dyb/src/dywFakeSD.cc U G4dyb/src/dywGenerator2.cc U G4dyb/src/dywUtilities.cc U G4dyb/src/dywXMLReader.cc A G4dyb/src/dywSensitiveSkinEdit.cc U G4dyb/src/dywAnalysisManager.cc A G4dyb/src/dywUImessenger.cc U G4dyb/src/dywGeneratorMessenger.cc A G4dyb/src/dywMacroLine.cc A G4dyb/src/dywDetectorEditor.cc U G4dyb/src/dywPrimaryGeneratorAction.cc A G4dyb/src/dywConstructEditor.cc U G4dyb/src/dywHit_PMT.cc A G4dyb/data/xml/edit A G4dyb/data/xml/edit/sensitive_skin_defaults.xml A G4dyb/data/xml/edit/sensitive_skin.xml
- look at the status symbols reported by the merge, A/U/G/... look especially for conflicts indicated by C which indicate that overlapping changes have occurred both to the trunk version and your working copy version , and you will need to do some manual conflict resolution in order to complete the merge.
- if there are a large number of conflicts you might wish to refactor your changes to avoid the maintenance overhead now and over the life of the code
Performing the actual merge
When confident that the merge commands you intend to use will do what you want, go ahead without the --dry-run ,
cd $DYW/../trunk svn merge -r 1636:HEAD $DYBSVN/legacy/branches/legacy-blyth
- see db:ConflictResolution for guidance on doing conflict resolution
Post-Merge Checks
Before commiting onto the trunk , do a full clean and rebuild and perhaps an autovalidation run.
cd $DYW/../trunk svn status -u
Communicate your changes
Prior to commiting you may want to communicate your changes to others, for example if you wish to invoke the 2-day rule. You can do this easily using the Trac web interface to the NTU mirror of the IHEP repository, with URLs like :
Media Wiki wikitext for the link :
[[NTU|dybsvn|diff:/legacy/branches/legacy-blyth@1636:1736]]
Commit your changes onto the trunk
Consider if your changes should be divided into multiple commits. If they comprise logically distinct fixes or additions then separate commits would allow :
- distinct commit messages for documenting the separate changes
- separate control, allowing changes to be easily swapped in or out
Time your commits to allow you to complete and test them prior to the autovalidation run.
From Scratch Checkout
The best way to check that your commits are complete is to checkout build and test starting from scratch. Check out the trunk, creating a new folder :
cd $DYW/.. svn co $DYBSVN/legacy/trunk newtrunk ## do a clean and build
Note you could just update your trunk area, however this would not be a full test as it opens the possibility that a local modification could shield an issue from you that will be felt by the next person to check out the trunk, or the autovalidation script.
Undoing Changes
Another common use for svn merge is to roll back a change that has already been commited. Taking Karen's problem as an example (see r3372 and the corresponding Karen's mail on 19 Apr. 2008), She committed codes to the dybgaudi/Simulation/GenTools directory by mistake. These code were intended to put in to my area in under people directory. The following rolls back the 'components' directory to the pre-3372 version, where 3372 is the revision that we want to remove.
svn co http://dayabay.ihep.ac.cn/svn/dybsvn/dybgaudi/trunk/Simulation/GenTools/src/components cd components svn merge -c -3372 http://dayabay.ihep.ac.cn/svn/dybsvn/dybgaudi/trunk/Simulation/GenToolsrc/components svn ci -m "Unroll changes r3372"