As I have seen many people not being able to sort out conflict state of their local copy of the project I decided to write a little about it.
First of all why do these conflicts happen.
Subversion unlike for example SourceSafe from Microsoft by default does not require locking of files in repository when you want to modify your local copy. Rather then to be restrictive and let only single user to modify file at any one time subversion lets anyone to do his changes on file and then when change is being committed/updated locally modified file is merged with incoming changes.
When does this happen? Lets say you start your work and modify some files in your local copy on freshly updated non-conflicted state of your repository. Then meantime your coworker doing his job opens and modify his local copy of the same file. Then when he commits his changes in the file get written to the repository and its revision is incremented. Now your repository contains file you have modified but it is older revision than the one in repository. On your next update all modified files by your co-worker are got from repository and replaced by new version. But this cannot be simply done with files you have also modified, so there are 2 possibilities.
Either, if you are lucky enough and you both did not change same line in the file, both changes yours and the ones in repository are kept and you end up locally with file containing all changes. Your repository is in non-conflict latest revision + your changes. You are fine to commit.
If you are not lucky and you both have changed the same lines of the file, or file is binary e.g. picture which you’ve both updated, changes cannot be merged automatically. Subversion cannot let you to remove latest modification of someone else of the file committed to repository without you knowing about it as you can’t if you hadn’t seen the change yet. At the same time it cannot just overwrite your changes you did in the file locally. So it cannot update your local copy to latest revision as you asked with update. In this case Subversion marks your local copy as conflicted and does not let you to commit until you resolve the conflict.
There are also other types of conflicts, for example you delete or create folder, create file in folder someone deleted, or create new file in your copy with same name as someone else created meantime. The someone has done the same and committed changes sooner than you did. Similarly as with merging files modified on same line, these are conflict which cannot be resolved by Subversion.
So how to resolve the conflict?
Your SVN software you run on your computer should show you which files or folders got into conflict. If the conflict is file modified in repository and by you, then you client SVN software should present you each of interesting versions of the file. It does it by creating these files in the place where original file is located:
1. File with same name as original. This file is file containing all changes yours and ones from repository enclosed by <<<<<< ======= >>>>>> where one block contains your change and other change from repository.
2. You original file, suffixed by .mine
3. File with suffix of number of revision you started your changes on. You can compare your file against this to see your changes in file.
4. File with suffix of number of latest revision in repository. You can compare your file against this to see conflicts, or compare this file with previous version file to see other person changes committed to repository.
Now the mistake most people do is to mark the original file as resolved without really resolving it. This will cause original file to be kept in merged state with all changes enclosed in <<<<<< ======= >>>>>>, which most probably breaks things somewhere when file will be used.
To resolve conflict properly you must first review changes which conflicted. So either open file with original name and locate blocks with marks and manually delete these marks and keep only content of block you want to keep. You can also merge manually the changes to keep logically both functionality. Note that there may be more than one conflicting change in the same file so review entire file carefully. Alternatively you can compare by visual comparison tool the changes between .mine file and latest revision file. You’ll see conflicted lines and you can modify it there. If you copy final changes to file .mine don’t forget to make this file the one with original name. What is your goal is simply to get the file with original name to state you want it. Only then mark the file as resolved.
If the conflict is for example deleted file or folder which has been deleted before, you resolve the conflict by reverting change of delete action and updating. If the change is new file or folder created at the same time, you need to rename you file or folder, update and then have a look what it is inside the one you get on update. Then you merge folders or keep the file you want and get rid of you renamed folder.
How to avoid conflicts in the future.
There is simple general rule. As long you don’t update your local copy as high gets the probability to get into conflicts. How long is “long” ? Well this depends on activity on the repository, if there are several people working and committing all together hundreds of commits every day, then “long” is quite short day or even hours. On the other hand if you are alone using repository you’ll probably never get into any conflict. So commit or get updates as often as you feel it is appropriate, you cannot break anything by updating your repository often, you will possibly get into trouble if you are not updating and committing regularly.
Other good point is to avoid two or more people to work on the same thing at the same time.
Also if there are files which are frequently updated you can add property to the file called need-lock and commit this property addition. This will cause that on next update everyone should get this file marked as read only in his local file system. Therefore before he can modify/save file he must acquire lock from the repository. Successful lock acquisition will let him modify the file and prevent others to lock the same file which basically forbids them to edit the file until he doesn’t release the lock which normally happens on commit. Well if you go for this option you need to understand that situation is not being resolved by this. Conflict resolution is just moved to different stage of development process.
Regardless whether the file is or is not marked that it needs lock, there are two people wanting to do their changes to the file. The difference is that in one case they can both edit and one of them is forced to resolve the conflict of his changes while in the other case the one wanting to do his changes and file is already locked must negotiate release of the file by other developer. Which in both cases there is an issue where communication between these too people must happen, sooner or later.