monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] My impressions of monotone


From: Tommi Virtanen
Subject: [Monotone-devel] My impressions of monotone
Date: Fri, 06 Aug 2004 15:30:02 +0300
User-agent: Mozilla Thunderbird 0.7.1 (X11/20040716)

[I'm not yet on the list, please Cc.]

Hi. I've been looking for a replacement for bitkeeper for a while now.
I've looked at subversion, arch and svk. Subversion wasn't distributed,
arch was sort of baroque with {lotsof} =silly behaviours-that--annoy-me--0.1, and svk just seemed like a hack that allows you to move commits from one repository to another without really being able to treat repositories as equivalents. So far, monotone looks to be the most promising one; the core looks really sane, though the user interface could use some work.

One of my tests for any replacement version control system has been to replay the commits I've done to http://ldaptor.bkbits.net/ldaptor and comparing each revision and merge between bk and monotone (I've attached the scripts I used, be careful with them, they contain a lot of assumptions). Here are some things I found myself thinking while writing the shell scripts to import things changeset by changeset. Often they mean the mentioned item is missing, or I couldn't find out how to do it:

- monotone is missing an equivalent of "bk superset", a single command that tells you whether it is safe to rm -rf things, without losing any work. For monotone, this'd probably be separate for db's and workdirs.

- annotate/svn blame/bk annotate equivalent?

- I want a way to list all tags (in a brach)

- list manifest/file hashes matching a selector

- for moving things between db's, I'd like to see something like "bk changes -L" and "bk changes -R"; that is, "if I pull/push now, what will be transferred".

- I want a way to list certs with name X (and maybe value Y). Right now the ways to access them from the commandline seem quite limited, without doing SQL.

- I want an equivalent of "bk changes -k -r+", that is, give the id that describes the head of this branch. Currently it seems doing some text manipulation on monotone status output works, but it's a kludge.

- I want a way to merge two _specific_ heads together, even if there are currently >2 heads open. This is mostly so I can import the bitkeeper history exactly.

- I tried to do the above with a temporary db where I'd transfer every change from the initial branch creation to the latest id's on the two heads I wanted to merge; then merge there and push changes back to main db. I couldn't figure out a nice way to do that, and while playing with mdelta managed to break some invariants in monotone. If this is a new bug, I can give you more information.

- I want a way to merge things so I can review the merge before it is "final". Should I do this with a temporary db, or is there another way?


All in all, thank you for a nice-looking version control system, if I can manage to import my bk things, I'll say byebye to the bitkeeper license and help you improve it.


PS. The mailing list web interface gives 404s when you try to download as mailbox.
#!/bin/bash
set -e
set -x
TOP="$PWD"
DB="$TOP/test/db"

die() {
    echo "$@" 1>&2
    exit 1
}

bkrenames() {
    REV="$1"; shift
    bk cset -r"$REV" >../test/deltas
    while read KEY; do
        PARENT="$(echo "$KEY" | bk prs -hnd':PARENT:' -)"
        GFILE="$(echo "$KEY"|bk prs -hnd':GFILE:' -)"
        if [ -n "$PARENT" ]; then
            OLDNAME="$(echo "$GFILE|$PARENT" | bk prs -hnd':DPN:' -)"
            NEWNAME="$(echo "$KEY"|bk prs -hnd':DPN:' -)"
            if [ "$OLDNAME" != "$NEWNAME" ]; then
                echo "$OLDNAME -> $NEWNAME"
            fi
        fi
    done <../test/deltas
}

mono() {
    yes s3kr3t | monotone "$@"
}

manifest() {
    D="$1"; shift
    cd "$D"
    monotone --db="$DB" status|perl -ne 's/^Old manifest: // and print'
}

bk_rev2key() {
    pushd ~/import/bitkeeper >/dev/null
    for rev in "$@"; do
        bk changes -k -r"$rev"
    done
    popd >/dev/null
}

empty() {
    O="$("$@")"
    [ -z "$O" ] || die "Command $@ output is not empty."
}

equal() {
    BKREV="$1"; shift

    rm -rf equal-bk
    bk export -k -T -r"$BKREV" ../bitkeeper equal-bk

    for MONOHASH in "$@"; do
        rm -rf equal-mono
        monotone --db="$DB" --branch=ldaptor co "$MONOHASH" equal-mono
        rm -rf equal-mono/MT

        diff -rq equal-bk equal-mono
    done
    rm -rf equal-bk equal-mono
}

import() {
    OLD="$1"; shift
    NEW="$1"; shift

    cd ~/import/test
    rm -rf new
    bk export -k -T -r"$NEW" ../bitkeeper new
    if rmdir new; then
        # it was empty -> that cset didn't contain any real source
        # (e.g. when creating the directory)
        # ignore it and flag it so we can ignore it later, also
        touch "empty-csets/$NEW"
        return
    fi

    if [ "$OLD" != "1.0" -a \! -e "empty-csets/$OLD" ]; then
        rm -rf old
        mono --db="$DB" --branch=ldaptor co "t:bitkeeper-$(bk_rev2key "$OLD")" 
old
        cp -ar old/MT new/
    fi

    # renames
    pushd ../bitkeeper >/dev/null
    # bk renames sucks, it seems to show origname -> finalname,
    # not origname -> nextname
    #bk renames -r"$NEW" >../test/renames
    bkrenames "$NEW" >../test/renames
    popd >/dev/null

    pushd new >/dev/null
    while read from arrow to; do
        [ "$arrow" = "->" ] || die "bad input: $from $arrow $to"

        case "$to" in
            BitKeeper/deleted/.del-*)
                # really a delete
                monotone drop "$from"
                ;;
            *)
                monotone rename "$from" "$to"
                ;;
        esac
    done <../renames

    # additions
    monotone list unknown >../unknown
    xargs --no-run-if-empty monotone add <../unknown

    empty monotone list unknown
    empty monotone list missing
    mono --db="$DB" --branch=ldaptor commit "import bk $(bk_rev2key "$NEW")"
    mono --db="$DB" tag "$(manifest .)" "bitkeeper-$(bk_rev2key "$NEW")"

    popd >/dev/null

    # compare
    echo "COMPARE IMPORT $NEW"
    equal "$NEW" "t:bitkeeper-$(bk_rev2key "$NEW")" "$(manifest new)"

    rm -rf new old
}

merge() {
    A="$1"; shift
    B="$1"; shift
    NEW="$1"; shift

    #mono --db="$DB" --branch=ldaptor co "t:bitkeeper-$(bk_rev2key "$A")" a

    mono --db="$DB" --branch=ldaptor heads >heads
    {
        read overview
        [ "$overview" = "branch 'ldaptor' is currently unmerged:" ] || die "bad 
overview"
        COUNT="$(wc -l)"
        [ "$COUNT" = "2" ] || die "wrong number of branch heads"
    } <heads
    mono --db="$DB" --branch=ldaptor merge
    mono --db="$DB" --branch=ldaptor co merged
    mono --db="$DB" tag "$(manifest merged)" "bitkeeper-$(bk_rev2key "$NEW")"

    echo "COMPARE MERGE $NEW"
    equal "$NEW" "t:bitkeeper-$(bk_rev2key "$NEW")" "$(manifest merged)"

    rm -rf merge
}

./output-graph \
    | {
    cd ~/import
    rm -rf test
    mkdir test
    cd test

    mkdir empty-csets
    mono --db="$DB" db init
    mono --db="$DB" genkey ldaptor-test

    while read new old merged; do
        if [ -z "$merged" ]; then
            import "$old" "$new"
        else
            merge "$old" "$merged" "$new"
        fi
    done
}
#!/bin/sh
set -e

# output format:
# newrev parent [merged]

cd bitkeeper
exec \
        bk changes -end':I: $if(:PARENT:){:PARENT:$if(:MPARENT:){ 
:MPARENT:}}$unless(:PARENT:){-}' \
        |tac

reply via email to

[Prev in Thread] Current Thread [Next in Thread]