Trac is being migrated to new services! Issues can be found in our new YouTrack instance and WIKI pages can be found on our website.

Changes between Version 4 and Version 5 of UsingPidginMonotone


Ignore:
Timestamp:
Nov 6, 2006, 4:47:01 PM (17 years ago)
Author:
elb
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • UsingPidginMonotone

    v4 v5  
    3030At some point you will probably try to execute a command which requires a keypair.  To generate a keypair, use {{{mtn genkey $KEYID}}}.  Key IDs are normally email addresses, and at this point there is no way to use two keys with the same key ID on the same project (keys are addressed by their ID, not fingerprint etc.)  For playing, you might want to generate a throwaway key ID just in case; I recommend that if we adopt monotone, all developers use a key of the form {{{username@pidgin.im}}} for normal development.  There is nothing which says this must be the case, however, and there is certainly something to be said for using a different key for each physical workstation or administrative domain that one uses.
    3131
     32== Branching {{{im.pidgin.gaim}}} ==
     33
     34There are two kinds of branches in monotone, which I will call ''macro-'' and ''micro-''branches.  We will deal with each in turn.
     35
     36=== macro-branches ===
     37
     38A ''macro-branch'' is a set of monotone revisions which have a particular certificate associated with them, identifying them as belonging to the same branch.  In our case, the "main" branch of development is {{{im.pidgin.gaim}}}.  All revisions in the monotone database which carry a cert of type {{{branch}}} with the value {{{im.pidgin.gaim}}} are on this branch.  Note that, technically, revisions on such a branch don't have to have any relation to one another -- however, it probably makes sense that they are all descended from some ultimate ancestor revision, and that they are logically related in some fashion.  In the case of {{{im.pidgin.gaim}}}, they form a (presently) linear history taken from the Gaim svn repository.
     39
     40Branch certificates are a little bit "magic", in that monotone knows about them and changes its behavior based on them.  For example, a {{{commit}}}ted revision will inherit the branch certificate of its parent.  An {{{update}}} on a workspace will update to the "newest" (DAG-wise; more on this later) revision bearing the same branch tag.  The set of revisions to synchronize via netsync is chosen by a branch specification pattern.
     41
     42Creating a new branch is as easy as committing a revision with a new branch name, or adding a new branch certificate to an existing revision.  The former is accomplished at commit time by supplying the {{{-b}}} or {{{--branch}}} argument to {{{monotone commit}}}.  The latter is accomplished with the command {{{mtn approve -b <branch-name> <revision>}}} or {{{mtn cert <revision> branch <branch-name>}}}.  Branch names are not structured (that is to say, their structure is not ''enforced''), but good practices for branch naming suggest that related branches have similar names.  BCP seems to be Java-style inverted-domain naming.
     43
     44Merging two branches is accomplished with the command {{{mtn propagate <from-branch> <to-branch>}}}.  There are other ways to merge (''e.g.'', approve or cert a revision onto the destination branch, and then handle as a micro-branch below), but this is the most straightforward and will normally serve your purposes.
     45
     46=== micro-branches ===
     47
     48Every history in monotone is represented as a directed acyclic graph (DAG).  This means that every revision checked into the database has an ''explicit'' list of parent revisions, which are fixed at the moment that the revision is committed and are thereforth immutable.  The DAG structure is general; this means that a revision can have more than one parent (currently, I believe it is only possible to have zero, one, or two, due to the implementation of monotone), and more than one revision can have the same parent (that is to say, a revision can have more than one child).  Because ancestors are immutable, and an ancestor must exist at creation time, a revision can never be its own ancestor -- thus the acyclic part.
     49
     50Due to the distributed nature of monotone, a little bit of thought will lead to the conclusion that it is possible to have a DAG which has more than one "head" revision.  Consider the case where two developers pull from the {{{pidgin.im}}} repository at the same time, and thus receive the same head; let us call it {{{0123abcd}}}.  Each developer goes on to make a change, and commits that change to their local database.  Say, {{{a1b2c3d4}}} for {{{devA}}} and {{{9876fedc}}} for {{{devB}}}.  The two developers then push their local changes to {{{pidgin.im}}}, and lo and behold, we have the graph:
     51
     52{{{
     53               ,--a1b2c3d4
     54              /
     55  ... 0123abcd
     56              \
     57               '--9876fedc
     58}}}
     59
     60We call {{{a1b2c3d4}}} and {{{9876fedc}}} the ''heads'' of the branch {{{im.pidgin.gaim}}}, and the heads of a branch can be viewed with the command {{{mtn heads}}}.  I call this divergence (within the same logical branch {{{im.pidgin.gaim}}}) a ''micro-branch''.
     61
     62Such a micro-branch obviously cannot be resolved with {{{mtn propagate}}}, as both revisions are on the same logical branch.  To resolve such a branch, the command {{{mtn merge}}} is used.  Either {{{devA}}} or {{{devB}}} can merge these two revisions, say yielding a fourth revision {{{deadbeef}}}.  The resulting graph then looks like:
     63
     64{{{
     65               ,--a1b2c3d4,
     66              /            \
     67  ... 0123abcd              deadbeef
     68              \            /
     69               '--9876fedc'
     70}}}
     71
     72Given that such structure exists and is possible, it can be eploited intentionally as well as created inadvertently.  Monotone:DaggyFixes discusses just this, and its usage in identifying and fixing bugs.  Additionally, this means that it is not necessary (as it often is with svn and CVS) to update your working directory before committing pending changes; simply commit them at the point where you created them, and then merge this commit with the branch as it currently stands.
     73
     74Note that {{{mtn update}}} will not update a branch which has multiple heads; you will either have to explicitly {{{mtn update -r <revision>}}} to select a particular head (or other revision), or merge the divergent heads before updating.
     75
     76=== Branch Complexity ===
     77
     78While all of this seems somewhat complex and difficult compared to the linear-history model of CVS or svn, it is really quite unavoidable in the context of a distributed VCS (as the above example shows).  Different systems handle it differently (darcs in particular using quite a different model), but the problem will exist in any such system.  Once you get your head wrapped around it, it's actually quite intuitive and powerful.
     79
    3280== Important Practices ==
    3381
All information, including names and email addresses, entered onto this website or sent to mailing lists affiliated with this website will be public. Do not post confidential information, especially passwords!