I’ve just merged a new feature to monotone‘s mainline which introduces database management features in the next major version. “Huh, database management? What are you talking about?” you might ask. Well, let me explain:
If you work with monotone you know that it has a strong concept of keeping workspace and repository distinct from each other, unlike for example git, where you can accidentially destroy unpushed changes if you remove your workspace. On the other hand separate databases make monotone workspaces also very lightweight, because checking out a new feature branch is a matter of seconds with an existing database.
Regular monotone users also keep separate projects in separate databases, because that eases the synchronization with other nodes (you don’t have to define complex include / exclude patterns for this then). But they may now face the problem that they have many databases with even more checked out workspaces in different places. Questions like “Uh, have I pulled this already? Where is my workspace again…? What branch is checked out there again…?” may arise – and working with long relative or absolute paths to use the correct database is not easier as well.
Monotone for the rescue! In the upcoming release monotone offers a way to manage regular databases in pre-defined places and allows access to these databases only by giving the file or base name as an argument for the `–database` option. Additionally, a new command `mtn list databases` (or `mtn ls dbs` for short) lists all available databases and shows the known workspaces of these databases.
Give me an example, already!
Lets do an example and create a new project:
$ mtn setup -b my.test.branch test-branch
mtn: initializing new database '/home/thomas/.monotone/databases/default.mtn'
Several things happened here: Just like the `clone` command, `setup` will also create a database if no database is explicitely given, but it will not put this database in the bookkeeping directory as `clone` did in the past versions. Instead, it looks if a default database with the name “default.mtn” (this is configurable via a hook, named `get_default_database_alias`) exists in the first found default location and if not, creates it. Subsequent calls to `setup` and `clone` will use the same database unless otherwise specified.
The default locations where monotone looks for managed databases is configurable through another hook, named `get_default_database_locations`. This hook defaults to `%APPDIR%\monotone\databases` on Windows and `$HOME/.monotone/databases` on Linux.
If you now look at `_MTN/options` of your new workspace, you’ll see that the database option does not contain an absolute path, but a so-called alias which is used by monotone internally to look up the actual location of the database:
$ cat test-branch/_MTN/options
database ":default.mtn"
branch "my.test.branch"
keydir "/home/thomas/.monotone/keys"
Aliases always start with a colon and are followed by the name or basename of the database. The following commands are therefor all use the same database:
$ mtn ls branches -d :default.mtn
$ mtn ls branches -d :default
$ mtn ls branches -d ~/.monotone/databases/default.mtn
Where are my workspaces?
Now as promised monotone is also smart about knowing what workspaces you have created for a particular database. Whenever the database option of a workspace is changed, it removes the workspace path from the old database and adds it to the new one.
Lets look at the current output of the new list databases command:
$ mtn ls dbs
:default.mtn (in /home/thomas/.monotone/databases)
my.test.branch (in /home/thomas/test-branch)
If you want to change the database of the workspace, all you have to do is calling a command which uses a workspace (f.e. `status`) with the new database option:
$ mtn db init -d :test
$ cd test-branch && mtn status -d :test
[... output of mtn status ...]
Now if we check the output of the `list databases` command again, we see the following:
$ mtn ls dbs
:default.mtn (in /home/thomas/.monotone/databases):
no known valid workspaces
:test.mtn (in /home/thomas/.monotone/databases):
my.test.branch (in /home/thomas/test-branch)
One thing monotone can’t automatically catch and handle is if you move a workspace within the file system. For this use case, two utility commands have been added, `register_workspace` and `unregister_workspace`:
$ ( cd test-branch && mtn unregister_workspace )
$ mv test-branch my-test-branch
$ ( cd my-test-branch && mtn register_workspace )
Thanks to the manual (de)registration, the output of `list databases` is still correct:
$ mtn ls dbs
:default.mtn (in /home/thomas/.monotone/databases):
no known valid workspaces
:test.mtn (in /home/thomas/.monotone/databases):
my.test.branch (in /home/thomas/my-test-branch)
Thats it. I’d love to hear your comments on this new feature. Thanks for reading!