We know how to create a repository. We know how to set up our SVN client and import our initial set of files. And in the 3rd module in this series, we saw how to check out and commit changes from/to the SVN repository. All pretty straightforward and easy to follow while just one user is working on one file.
It won’t be long though before you start getting warning messages from SVN that you have a conflict. It’s how you should go about handling these conflicts we’re looking at in this module.
What you’ll find is that two people will be working on the same file and try to commit changes to the same file to the repository on the server. When this happens we get a conflict. Two users are trying to commit conflicting changes to the repository. This works as follows:
In short, we have this…
- two users have checked out the contents of the repository to their local machines
- both users start editing one of the files on the local machines
(just so happens that they are both editing the same file)
- the first user commits his/her changes to the repository
- the second user tries to commit his/her changes to the repository too
- trouble is the second user changes would overwrite the first user changes
(so the first user changes would be lost)
- SVN warns user 2 that there is a conflict
- It’s down to user 2 to resolve that conflict
What we’ll see from SVN when the second user tries to commit their change is this warning from SVN:
It’s one of SVN’s key jobs to warn users that changes to files might be lost or overwrite if multiple users are making and committing changes to the same file(s). SVN does this by warning the user that there is a conflict. You can see this happening when you follow these steps:
Create a new directory (a 2nd directory) where User 2 will check their files out to
Check out the contents of the repository to this directory…
Using the Tortoise SVN Check Out command…
… And specifying the directory URL of the repository…
Note we’re simulating being user 2 here…. just by the act of checking out the same repository contents but to a different directory. In reality, this second directory will be on a different computer and will be a different user.
Both directories now contain the contents of the repository and both are in sync with the latest updates that have been committed to the repository. You can check this with…
In this first instance, you’ll see a list of modification you’ve made (if any) to your local files. You’ll need to click on the ‘Check repository’ button to see if anyone has committed changes to the repository so there is a modification in the repository version that you’re missing locally.
Assuming you’re all up to date and in sync with the repository then we can go through the process of simulating a conflict and working through resolving that conflict. To do this we’ll go through these steps…
- modify a file in the first (user 1) directory
- commit the modified file in the first directory to the repository
- modify a file in the second (user 2) directory
- attempt to commit the modified file in the second directory to the repository
- deal with the conflict
So first, update one of the text files in the first directory and save your changes (you can use notepad or any text editor of your choice).
Then commit these changes to the repository
Adding a comment and clicking okay to complete the commit.
Check you get a successful commit message and note the new revision number… then click OK.
Now we’ll repeat the process in User 2’s directory.
Update one of the text files in the second directory and save the changes.
To commit the changes…
Note that you are committing changes from Users 2’s directory to the same central repository.
When you click OK you’ll be presented with a warning message like this…
SVN is warning users that the version of file1.txt that we updated was not done to the latest version of the file that was in the repository. If we commit this change then the latest version of the file in the repository will be overwritten and changes lost.
We need to resolve this conflict first. Without a resolution, SVN won’t let us commit this change to the repository. So click OK to clear the ‘Commit Failed’ warning dialogue box. And at this point SVN will ask you if you want to update your local working copy.
There are many ways to resolve conflicts. We’ll walk you through the update process that SVN prompts you to follow here. So click the ‘Update’ option on this dialogue box:
When you get presented with the update finished message you can clear this by clicking the okay button…
And then on the next dialogue box (that gives you the option to commit your changes again) click ‘Cancel’.
We’re canceling this because I want to show you what SVN did when it attempted to resolve the conflict and update your local copy of the file. When you click the update button what SVN does to your local file is this…
What you’re getting here is not 1, but 4 copies of the file you were working on. Those 4 files are…
This is the version of your file where SVN has tried to combine both the latest version from the repository and your local version with your latest changes.
This is your copy of the file with the changes you made. It’s exactly what you had before you attempted the commit.
This is the version of the file that you originally checked out of the repository (before you made your local changes)
This is the latest version of the file from the repository with all the latest updates that have been committed by other users.
If you take file1.txt first thing you’ll notice in explorer is that it has a triangle with an exclamation mark against it. This is showing us that it’s in a conflict state and that SVN has combined your changes with those from the latest revision found in the repository. Basically, you need to do something with this file before you can resolve the conflict and commit the merged changes to the file back into the repository.
In short what we really want to do is take the latest version of the file from the repository (file1.txt.r3) merge it with the file you had been updating (file1.txt.mine), rename the resulting file to the original file name (file1.txt) and commit the merged file back to the repository.
The simplest way (and most logical to me) I find to do this :
- use a diff/merge tool to compare file1.txt.mine and file1.txt.r3
- merge the changes between file1.txt.mine and file1.txt.r3 (with a tool like winMerge)
- copy the resulting file (or rename it) to file1.txt (overwriting the svn merge file)
- resolve the conflict
- commit the change back to the repository
In step 1 then we use a tool like WinMerge (or any merge tool of your choice; like winDiff, TortoiseDiff, etc) and compare your work with what is currently the latest version in the repository.
In the case of WinMerge select both files (file1.txt.r3 and file1.txt.mine) and then right-click to select WinMerge
From here, for step 2, we can see our local version and changes on the left. And on the right the latest version of the file from the repository. We’ll merge the repository changes into our local version. So we’ll merge right to left.
We’re being careful here to pull changes from the repository version into our version (file.txt.mine) without overwriting our changes. So the left-hand version ends up with the repository changes and our changes.
Once they’ve been merged into file1.txt.mine we want to save this file.txt.mine. This is the file with ALL the changes in. The version of the file we want to push back into the repository.
So save the file and close your merge tool.
Now for step 3, we want to make our file with all the changes the one called file1.txt. So, rename file1.txt to file1.txt.Svnmerged. Then rename file1.txt.mine to file1.txt.
Now we’ll have all our changes (the merged changes) in the file file1.txt. The newly merged file1.txt should still show the SVN conflict warning triangle.
Now, step 4, we want to tell SVN that we’ve resolved the conflict. Right click on the file and select ‘Resolve’.
And in the conflict resolution dialogue box now displayed just click okay to confirm the resolution and then click OK to the last confirmation dialogue box.
At which point we should be back to one of our usual states where SVN is just telling us that we have updated our local file and that it’s ready to be committed to the repository.
So for step 5 just commit the file back to the repository.
Complete the commit and we should now have the latest revision of the file (revision 4 in this case) stored in the repository with the merged changes from both user 1 and user 2.
At this point, we’ve completed the merge and everything is straight. Well, almost everything. User 2 has the latest copy of the merged changes (revision 3). User 1 is still in revision 3. So a good last step for User 1 (and a step you should do on a regular basis) is to update the local copy of the files.
So user 1 (in the directory ../co-repo1-user1) should update their local copy by right-clicking and selecting ‘SVN Update’.
At this point, everybody is in sync with the latest merged version of the files from the repository. And we’ve seen 2 users successfully collaborate and version control the same file on multiple client machines without losing anybody updates to the files.
There are many ways to go about this conflict, merge and update process. The one described above is a little long winded but I believe it’s the one that’s easiest to explain and understand. It’s a process that helps highlight exactly what’s going on behind the scenes with SVN. Once you’ve grasped this experiment with other approaches and see where that gest you too.