Archive for July, 2007
Bazaar doesn’t do much for you, by default, when it comes to resolving conflicts. If a conflict occurs, the file in question will be merged with sections of text indicating the conflict. In addition, three files will be created using the original file name and appending THIS (the file before the merge), OTHER (the file being merged) and BASE (the revision THIS and OTHER have in common). With this information, it would be possible to manually correct the conflict, but this can be tedious and error prone. It’s easier to use a graphical merge tool to do this. There’s a great merge tool available for free called P4Merge. You could manually use P4Merge to open the respective versions of the file in order to perform the merge, but that can be a pain when there’s a lot of conflicting files.
A better solution exists. There’s a Bazaar plugin that adds an extmerge command. Once this plugin is installed (follow the directions in the plugin link), you need to configure it to use P4Merge.
PS> notepad $env:APPDATA\bazaar\2.0\bazaar.conf
Add a line like this.
external_merge = p4merge %b %t %o %r
Here’s an explanation of the replaceable parameters, in case you want to use a different graphical merge utility.
|%r||results file, or the original file|
With this all set up, when a conflict occurs, you simply do this:
PS> bzr extmerge --all PS> bzr resolve --all
This will first run your external merge program and then tell Bazaar that the conflicts have been resolved. The "–all" option does this for all conflicting files. You could instead specify which conflicting file to operate on. Once resolved, you’ll still need to commit the changes.
I thought I’d blog about how I’m actually using Bazaar. As I mentioned earlier, the reason for learning to use Bazaar was a need to be able to manage a set of scripts between several computers that may not have access to each other or a central server. A DRCS solution would allow me to track and manage changes to these scripts across these computers through the use of a "central" branch I’ll keep on a USB memory stick. Here’s how I set this up, and how I use it on a daily basis.
First, we create a new branch on the memory stick.
PS> cd g:\ PS> bzr init scripts
Now, on a central computer in each location I can create a "shared" branch.
PS> cd c:\ PS> bzr branch g:\scripts scripts
Now I can make individual branches on each machine and use them normally.
PS> net use \\machine\scripts PS> bzr co \\machine\scripts scripts
If I make a change on one of these machines, I simply have to commit the changes, which will also commit the changes to the "shared" branch. To push these changes out to machines at this location, all I have to do is run "bzr update". To push the changes to other locations requires a little more work, though it’s simple and straight forward.
PS> cd g:\scripts PS> bzr merge c:\scripts PS> bzr ci -m "Merged changes"
This pushes the changes onto the memory stick. Now at the other locations I can pull the changes off the stick.
PS> cd c:\scripts PS> bzr pull
Now on individual machines at the new location I can simply "bzr update".
This isn’t much different than just copying the scripts around everywhere. However, Bazaar gives me several benefits over the simple copy. First, changes are revision controlled, which is always beneficial for code! Second, because I’m committing and updating to a DRCS instead of just copying files, it’s very difficult to accidentally copy over changes made in one location that I forgot to copy out everywhere else.
I’m finding the terminology used by Bazaar to be both familiar, and confusing. In particular, there are three terms that, for the most part, have identical meanings to how the terms are used in the centralized RCS solutions I’m used to, but for which there’s a slight difference that requires different thinking about them. These three terms are repository, branch and working tree.
A repository is the the storage area that contains all the history information. The difference here is one that shouldn’t be shocking: there is no central repository in a DRCS solution. However, this fact does require some different thinking. A given repository may not, for instance, contain a complete history of the "project" under revision control. Why not? Because, just as an example, a repository on one machine may not have history that’s in a repository on another machine that was created with a branch. This may be obvious, but the nuances of this can be subtle and surprising at first. Entirely new ways of managing a project are possible, each with their own sets of pros and cons.
A branch is a copy of a project at a point in time, where changes and commits can happen in parelel. The difference here is that in a centralized RCS solution, there’s a "main branch" or "trunk" and all branches exist within the central repository. In a DRCS solution, there is no "main branch", except possibly by convention. In an RCS it’s normal to do most development in the main branch. In fact, there’s often a desire to not branch, since branches have a reputation of being difficult to manage and to merge. In a DRCS, however, it’s not possible for multiple developers to work within a project with out branching. Every developer will have at least one branch to themselves. Because branches don’t exist within a central repository, the relationship between branches is purely logical, and you may not know what branches even exist. Branching and merging are just part of daily life, and in general are not complex operations. Another point to keep in mind, at least with Bazaar, is that branches by default will have their own repository, but it’s possible (and recommended) for local branches to share a repository (see the init-repo command).
A working tree is the copy of files from a specific point in time that modifications can be made to and committed. The difference here is that the files exist within the same directory as the branch, if they exist at all. It’s possible to have a "treeless" branch, and in fact that’s a good strategy for a shared central branch.
Keeping in mind the subtle differences in these terms is definitely helpful when learning to use a DRCS solution.
I’ve been evaluating a new (for me) RCS solution, named Bazaar. I’ve used plenty of RCS systems in the past: PVCS, CVS, Subversion, ClearCase. All of these were centralized RCS solutions. In other words, they all relied upon a central server that acted as the main repository. This means, in order to use them, you must have access to the server. For personal use, this means setting up and maintaining a server, which isn’t always a trivial task. Worse, it means the server must be accessible from everywhere that you’ll need it. I’m currently sharing some script files between about 10 machines, not all of which will have easy access to a central server. This makes maintaining the scripts difficult at best. So, I went looking for a solution.
There’s a new breed of RCS solutions known as DRCS, or decentralized revision control systems. These solutions don’t use a central server concept at all. All of the functionality exists in locally. Changes are made, applied and tracked locally. These changes can be pushed or pulled to other locations, in order to facility typical code sharing scenarios that exist in centralized RCS solutions. A single repository can be located in a centralized location to act much as the centralized server did in those scenarios. Or you can opt to use entirely new ways of working.
In my particular case, I can version control my scripts in a repository that I can move back and forth between work and home using a memory stick. Then in those two locations I can use a local copy as a central repository for the various machines in those networks. Changes are moved back and forth between all of the various branches in a fashion that’s pretty familiar to CVS or Subversion users. So far, I’m really liking this solution.
There are plenty of DRCS solutions available. The big names seem to be Git, Mercurial, Bazaar and DARCS, though there are plenty of others. I settled on Bazaar. Git is basically a Linux only solution, so it’s out. DARCS is reportedly very slow, and doesn’t use a familiar scripting interface. Mercurial and Bazaar are very comparable. Mercurial is reportedly faster (and speed is one complaint I have with Bazaar), but I’m impressed with the development community behind Bazaar.