The unified diff between revisions [8846a6b8..] and [ebdccab0..] is displayed below. It can also be downloaded as a raw diff.

#
#
# add_file "tests/t_cvsimport_branch.at"
#  content [d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8]
#
# add_file "tests/t_db_kill_rev_locally_2.at"
#  content [296391166304e8c739fcc7968ae5f58a36b91265]
#
# add_file "tests/t_log_nofiles_nomerges.at"
#  content [dedc7b333ac5e779f29464a1f62285ec787b6dd4]
#
# add_file "tests/t_log_selectors.at"
#  content [3d000a79a2acdff3df5c7a8a804d2e38aa035dc5]
#
# add_file "tests/t_log_to_file.at"
#  content [4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c]
#
# add_file "tests/t_pivot_root.at"
#  content [2bf3634c3c1a16c375a85bc5f403992422cdfc8b]
#
# add_file "tests/t_pivot_root_revert.at"
#  content [bf2c402b7cb49ebdd178928ea01372deb68858a5]
#
# add_file "tests/t_pivot_root_update.at"
#  content [e4f51059ec68ec4f187cd3593eeb49459aea3b5a]
#
# add_file "tests/t_revert_new_project.at"
#  content [ac8b9497aa5d1a89d01be066365bddb8b3889baf]
#
# add_file "tests/t_rosterify_root_suture.at"
#  content [ff625956c64676b2b33f9ccc9f9a45b7b7587318]
#
# patch "ChangeLog"
#  from [cf7af27d617c006696a08efcd68a9bd9fd401a7a]
#    to [cef9fe8e359d630eb8f61133684772293748eade]
#
# patch "Makefile.am"
#  from [d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1]
#    to [380383c22ef6bb6b1d7203b215dbed739c249c63]
#
# patch "app_state.cc"
#  from [18045740e735562c70e3a482927003729014844f]
#    to [4990c26751504dded9cef9b1c6ffa66bef0d2b32]
#
# patch "app_state.hh"
#  from [7fa51b357c748547e5d71dbc84fb35077c148177]
#    to [03afbc7ba543f0b26f8ddf70d97c05e872cdb36b]
#
# patch "commands.cc"
#  from [dbf77e72442ab85b8b4390b8fb1316ca8145d507]
#    to [0fc12a37debd7db7812e2670afcb99d787f869e0]
#
# patch "contrib/color-logs.conf"
#  from [ffe3e7270a2952c508db2f2d9c3df82e05c859f4]
#    to [87e8ceac1e0a8d173e2a0da01e659d048824e9ed]
#
# patch "contrib/color-logs.sh"
#  from [90a0de6aa87b7f4b39f7947fd1d359a3cc936385]
#    to [4e04daeee4ee8ce8bf6ce45f074ba16faf50ccf9]
#
# patch "contrib/monotone-notify.pl"
#  from [aa93d7f9f601b51d607bd4d779e472067c41d5a2]
#    to [d7f551f0f332f56785aaa59e99ade7400c8da84a]
#
# patch "contrib/monotone.bash_completion"
#  from [d942f24e3f430c7e12fceeb7a58e088e45211971]
#    to [c5fff50c3c591f9dd72f80c3812c506571e3ab74]
#
# patch "contrib/monotone.el"
#  from [3dc1c23d499d1aa015ed7f145416a241a55f054f]
#    to [9e1a1ec218b98cd38c6126c48f00a1d585e65a13]
#
# patch "contrib/usher.cc"
#  from [cb295e80eb1af0bd7d55cde7da973c340a05deb2]
#    to [599b754c575694458973cf7ecd5be5fd5a03c06d]
#
# patch "cset.cc"
#  from [ac5f2a4848a4c5661496ec4f5af706de1fb6a454]
#    to [5fdac8f01ad19e4a427e40aa4245026b534422f7]
#
# patch "cset.hh"
#  from [f2d58803ea89b51b5029a349c30acc3c6c3cf580]
#    to [7bd817258ac15fa2b6e4c3473e9b97858721969d]
#
# patch "database.cc"
#  from [4c830b7b46f89cdc384cae08e54bfeac62335eb7]
#    to [fd5eff861239cd1408cca007c0df653f8a0f7d3f]
#
# patch "file_io.cc"
#  from [3214c2cad3ec630d8466926bd4bae693de9184a0]
#    to [3ca8050b61b62ef9010b0ebfda755a0af9269104]
#
# patch "file_io.hh"
#  from [2082dc3c8480400f32fcbe1c4d881d7512de2204]
#    to [362691f10f63d93e7cf83f299fe5aa0b4dcbee17]
#
# patch "lua.cc"
#  from [8284c5010bee38f15141c3e60eeeeb7c288ee20c]
#    to [a9045fcf6d8283a12a96f422b79fb54ae2da727c]
#
# patch "lua.hh"
#  from [a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea]
#    to [5691c7c116dc402741a8a9ba7f5ab7d2ebe7b2e0]
#
# patch "monotone.cc"
#  from [92399bda2cd0fba92739636d7b0955c1c43bea23]
#    to [29890d9e90e828fa96d845cb881bb024a8267d99]
#
# patch "monotone.texi"
#  from [355d07f84caee318dd69f37ff6274842ca2d2c70]
#    to [d62e740d5bf36c317e4ec3fea155132bd7ba702d]
#
# patch "netcmd.cc"
#  from [5a63ccd88ddb02cf5853e13ce3fff6ea20851a53]
#    to [da3773c93069c0834ce0b3caf34020305dd7d8b2]
#
# patch "netcmd.hh"
#  from [22664387cea0916b87288113ec5b559c2c49eda5]
#    to [e290b45f5acb01bfe181832d4750275e05b2f98f]
#
# patch "netsync.cc"
#  from [8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa]
#    to [0edebb049f6f44132b6c97be4663efc113efeee8]
#
# patch "options.hh"
#  from [6dc48543e2cb20ea82ded241dc5bb6088c3cb09c]
#    to [216cb82f6f82b63b0f1535b39bb985a237b43359]
#
# patch "paths.cc"
#  from [c13e9b0c44a37a70e6c7e6d5c8b8869e363ccab9]
#    to [05c27908836d28a468070bb8e7a808417b8401f1]
#
# patch "paths.hh"
#  from [054a74b153b42a34140f2776f468bf79c844fa64]
#    to [e81d1f0e7efdbff539b8b92f04ad357770130fd4]
#
# patch "po/sv.po"
#  from [754e90276863a8b1a53cad17c575bb93ffcdd5b4]
#    to [e065ecfd2c28c0ea89877c3c95ceeae23190b320]
#
# patch "roster.cc"
#  from [4547e72b235da17471b9781c3416e7eac2904027]
#    to [ccbdfd50a2a99c49598ae638a013a095f232c876]
#
# patch "roster.hh"
#  from [0f6d33d17d3d1c804be21f2e8025d86e47f087f9]
#    to [9ec5d3bbd5751f987a7591a3d577002a627a36e3]
#
# patch "roster_merge.cc"
#  from [4dec4aecf9c67f0ba369c9430bb492a3d93170bf]
#    to [d1d307d2cc0fac8f4c50963b1563edcc3df26d86]
#
# patch "roster_merge.hh"
#  from [e9c290f799091e5ecb70e291daae0bff72df2d48]
#    to [3a86138ac40adb1f2736fc9f348988b91aea2ff4]
#
# patch "sanity.cc"
#  from [b31758131617cacbc373a95c25cab49e15ffedc3]
#    to [36f79a9ba2cf13f0f96eb85a36ee0ca1619c39df]
#
# patch "sanity.hh"
#  from [3d91a4abd21f2af06ea78724a922b3b52fa0838f]
#    to [88009f27365f17c86b8dd104021fbcc1cc08a497]
#
# patch "sqlite/alter.c"
#  from [faf98b04050d674d06df21bcf23ded5bbff7b5b7]
#    to [451b34fc4eb2475ca76a2e86b21e1030a9428091]
#
# patch "sqlite/btree.c"
#  from [f45f57e6cbd3b3db947cdd699db64e5215d20b2a]
#    to [23bbfb4745e549ca224f6c933a6e9bc106d77f56]
#
# patch "sqlite/btree.h"
#  from [5663c4f43e8521546ccebc8fc95acb013b8f3184]
#    to [40055cfc09defd1146bc5b922399c035f969e56d]
#
# patch "sqlite/build.c"
#  from [feaa61e769d7887ffeaa060d746638c7b3e994ef]
#    to [b46cd7d0e2daca775d9de0cba8abae1b1625caf4]
#
# patch "sqlite/date.c"
#  from [c70a4f88e495ae2c523f6ef3848c26a021c96de8]
#    to [cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e]
#
# patch "sqlite/delete.c"
#  from [56ab34c3a384caa5d5ea06f5739944957e2e4213]
#    to [ca404d5fd5f678e32f2f46377ad802cd0219aa99]
#
# patch "sqlite/expr.c"
#  from [1149c3380bfce27703f5e9bec7dfb8e51baaf9d9]
#    to [9c957fabf95ef62288151eecd5c490a629470666]
#
# patch "sqlite/func.c"
#  from [96b26601c092b7b43a13e440e3f988b32a385f6a]
#    to [93d004b453a5d9aa754e673eef75d3c9527e0f54]
#
# patch "sqlite/insert.c"
#  from [7e931b7f06afbcefcbbaab175c02eff8268db33f]
#    to [67b3dc11831c58d8703eb502355ad3704ee18f66]
#
# patch "sqlite/main.c"
#  from [2693776249865dc69b97904205638e84a34a059c]
#    to [9a42464c44a6532003391486e802e65e88789cfc]
#
# patch "sqlite/os_common.h"
#  from [061fba8511a656b118551424f64e366ad0d4cb3b]
#    to [108cd719c96a2b714b64e02aeabbd40684274e6a]
#
# patch "sqlite/os_unix.c"
#  from [73c5e722a661ed98d8919f204911e4e34e51fa41]
#    to [378a89aaf15d83b901c1b73350e91ddecf743986]
#
# patch "sqlite/os_win.c"
#  from [566bf7b41b72556fd7dca390bceaa2769dc395e9]
#    to [c67a2c46d929cf54c8f80ec5e6079cf684a141a9]
#
# patch "sqlite/pager.c"
#  from [b5b380ea7a36f84e50c3adc1a414820a0eb3baa6]
#    to [c438aa5fc248e0523e80591eeae33a3993c47278]
#
# patch "sqlite/pager.h"
#  from [e0acb095b3ad0bca48f2ab00c87346665643f64f]
#    to [425a9e52d5404158de016799715cbc2c3d685178]
#
# patch "sqlite/parse.c"
#  from [a31a0cb5fd9be3781389e4b2784b197d03226dc4]
#    to [56d45a7fd03e7c499e1a0bacb81916956b9ec8d7]
#
# patch "sqlite/pragma.c"
#  from [4496cc77dc35824e1c978c3d1413b8a5a4c777d3]
#    to [31d3e1b74cab2172807894e70c674d6a577501fd]
#
# patch "sqlite/prepare.c"
#  from [40ae23c8aeb641dc7b9bb271eb5e295b815154a7]
#    to [cf0fc8ebaf94409955ecb09ffeb0099c9ef44693]
#
# patch "sqlite/select.c"
#  from [daee9b20702ba51cf3807fc1b130edd8846e3e48]
#    to [7d069e875d0eec05129c7e8b9c99422d7c9c6321]
#
# patch "sqlite/sqlite3.h"
#  from [6b9ed927e0a9a3c6051a372929c97c2ac87ab314]
#    to [d0605a62334179d9c38bf587ac38b777d6daee2b]
#
# patch "sqlite/sqliteInt.h"
#  from [0121298397ac14eb468ab1ba9d488ac7ed7d88a1]
#    to [f61b60f243f1709c943c62cfb6d7a50209080e38]
#
# patch "sqlite/table.c"
#  from [486dcfce532685b53b5a2b5da8bba0ded6fb2316]
#    to [f64ec4fbfe333f8df925bc6ba494f55e05b0e75e]
#
# patch "sqlite/tokenize.c"
#  from [9ae9a59238eb97fbc61baea280563b91100518fb]
#    to [382b3bb0ca26eb9153b5d20b246ef512a114a24f]
#
# patch "sqlite/update.c"
#  from [14be4ba2f438919b4217085c02feff569e6cf1f2]
#    to [050a7e0ddaac03dec5271712eee62f1a9e699049]
#
# patch "sqlite/util.c"
#  from [82ee598519b8193184bdeab06b51a4ffa05ad60b]
#    to [405f46fef062b476826d2c171ec21def29563b75]
#
# patch "sqlite/vdbe.c"
#  from [fee677e05236e483d6c75d1d4229955fc1b89193]
#    to [0a7fd81609429bae2b3c326687b02a60a9c01c49]
#
# patch "sqlite/vdbe.h"
#  from [8729a4ee16ff9aeab2af9667df3cf300ff978e13]
#    to [80ba1c391ec28180dd07a630577f50b22c2062da]
#
# patch "sqlite/vdbeapi.c"
#  from [dcb2636f49b4807e34960d52a2fc257b3a751140]
#    to [7dc662e7c905ce666bb506dced932e0307115cbf]
#
# patch "sqlite/vdbeaux.c"
#  from [9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797]
#    to [95f4ed0bc8ed45f16823d84504310495b5dc587d]
#
# patch "sqlite/where.c"
#  from [8409e00fa2cb5fce873b4c911165cfed097e9c49]
#    to [c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6]
#
# patch "std_hooks.lua"
#  from [8f01e338e8056c62de500694210fd22dacac6122]
#    to [4ca1188ac09063710baa429986649f2c3ad13083]
#
# patch "test_hooks.lua"
#  from [391ca756f0e4bd4325ffba83caf9a698b1713e23]
#    to [c8ca29aac8840285176dc56724352917a3b52bf2]
#
# patch "tests/t_netsync_permissions.at"
#  from [9a8356b76404d50e044f74e5f59d6e055ad64d1e]
#    to [14dc033954a1e36979893b0f9b4d5daf4be18b82]
#
# patch "testsuite.at"
#  from [781e96c61a849b6f628e1aa691189b64f4d1bf08]
#    to [d67ef3223629641b02551a0a31cbf4644cd60d82]
#
# patch "ui.cc"
#  from [f412b8a06dfed701085469c14e62e359369469cf]
#    to [7bef43275fba7bdf4c2dc03ee191776dc2a57834]
#
# patch "ui.hh"
#  from [496479433aee1e5ff51e96a22ae7cb662d71c4b8]
#    to [5a1e338407beeda0b373e5296d9106d4a6d9f35f]
#
# patch "unit_tests.cc"
#  from [cd6c9924afd3ab76ba8bfb91ff23990f3a1cc565]
#    to [5f4e6b96f89134edb6d35c799b26932587dc3679]
#
# patch "unit_tests.hh"
#  from [b2611fdb586f062e99b396dd5985db3b1f884360]
#    to [1f0dbf6a811b8bcb25b0a0071239cf7809867037]
#
# patch "work.cc"
#  from [265e6d058be85a58414c208164fbe9592b1d3e74]
#    to [be9eb83e519a1395626b2b29868af63e46a958c2]
#
# patch "work.hh"
#  from [723c827976adf80b589df8c0e2629ed7fafb907e]
#    to [dc6f1035c0b3a27f9b94bff02d5f650b9da8f26b]
#
============================================================
--- tests/t_cvsimport_branch.at	d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8
+++ tests/t_cvsimport_branch.at	d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8
@@ -0,0 +1,127 @@
+#  -*- Autoconf -*-
+
+AT_SETUP([importing CVS branches with correct ancestory])
+
+MONOTONE_SETUP
+
+AT_XFAIL_IF(true)
+
+AT_DATA(file1.0, [version 0 of test file1
+])
+
+AT_DATA(file1.1, [version 1 of test file1
+])
+
+AT_DATA(file1.2, [version 2 of test file1
+])
+
+AT_DATA(file2.0, [version 0 of test file2
+])
+
+AT_DATA(file2.1, [version 1 of test file2
+])
+
+AT_DATA(changelog.0, [first changelog entry
+])
+
+AT_DATA(changelog.1, [second changelog
+
+first changelog entry
+])
+
+AT_DATA(changelog.2, [third changelog -not on branch-
+
+second changelog
+
+first changelog entry
+])
+
+AT_DATA(changelog.3, [third changelog -on branch-
+
+second changelog
+
+first changelog entry
+])
+
+AT_DATA(branchlist, [test
+test.branched
+])
+
+F1SHA0=`SHA1(file1.0)`
+F1SHA1=`SHA1(file1.1)`
+F1SHA2=`SHA1(file1.2)`
+F2SHA0=`SHA1(file2.0)`
+T2SHA1=`SHA1(file2.1)`
+CSHA0=`SHA1(changelog.0)`
+CSHA1=`SHA1(changelog.1)`
+CSHA2=`SHA1(changelog.2)`
+CSHA3=`SHA1(changelog.3)`
+
+# build the cvs repository
+
+CVSROOT=`pwd`/cvs-repository
+AT_CHECK(cvs -q -d $CVSROOT init, [0], [ignore], [ignore])
+AT_CHECK(test -e $CVSROOT)
+AT_CHECK(test -e $CVSROOT/CVSROOT)
+AT_CHECK(test -e $CVSROOT/CVSROOT/modules)
+
+# checkout the empty repository and commit some files
+
+AT_CHECK(cvs -d $CVSROOT co ., [], [ignore], [ignore])
+AT_CHECK(mkdir testdir)
+AT_CHECK(cp file1.0 testdir/file1)
+AT_CHECK(cp file2.0 testdir/file2)
+AT_CHECK(cp changelog.0 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT add testdir, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/file1, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/file2, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/changelog, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT commit -m 'initial import' testdir/file1 testdir/file2 testdir/changelog, [], [ignore], [ignore])
+
+# commit first changes
+AT_CHECK(cp file1.1 testdir/file1)
+AT_CHECK(cp changelog.1 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'first commit' testdir/file1 testdir/changelog, [], [ignore], [ignore])
+
+# now we create a branch
+AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b branched, [], [ignore], [ignore])
+AT_CHECK(cd testdir; cvs -d $CVSROOT up -r branched, [], [ignore], [ignore])
+
+# alter the files on the branch
+AT_CHECK(cp file2.1 testdir/file2)
+AT_CHECK(cp changelog.3 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'commit on branch' testdir/file2 testdir/changelog, [], [ignore], [ignore])
+
+# and create some mainline changes after the branch
+AT_CHECK(cvs -d $CVSROOT up -A, [], [ignore], [ignore])
+AT_CHECK(cp file1.2 testdir/file1)
+AT_CHECK(cp changelog.2 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'commit on mainline after branch' testdir/file1 testdir/changelog, [], [ignore], [ignore])
+
+# import into monotone and check presence of files
+AT_CHECK(MONOTONE --branch=test cvs_import $CVSROOT/testdir, [], [ignore], [ignore])
+
+# check if all branches were imported
+AT_CHECK(MONOTONE list branches, [], [stdout], [ignore])
+AT_CHECK(cmp stdout branchlist)
+
+# checkout the imported repository into maindir and branchdir
+AT_CHECK(MONOTONE checkout --branch=test maindir, [], [ignore], [ignore])
+AT_CHECK(MONOTONE checkout --branch=test.branched branchdir, [], [ignore], [ignore])
+
+# check for correctness of the files in the main tree
+AT_CHECK(cmp file1.2 maindir/file1)
+AT_CHECK(cmp file2.0 maindir/file2)
+AT_CHECK(cmp changelog.2 maindir/changelog)
+
+# check for correctness of the files in the branch
+AT_CHECK(cmp file1.1 branchdir/file1)
+AT_CHECK(cmp file2.1 branchdir/file2)
+AT_CHECK(cmp changelog.3 branchdir/changelog)
+
+# get the log of the branch to check for correct branchpoint
+AT_CHECK(cd branchdir; MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep "commit on branch" stdout, [], [ignore], [ignore])
+AT_CHECK(grep "initial import" stdout, [], [ignore], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_db_kill_rev_locally_2.at	296391166304e8c739fcc7968ae5f58a36b91265
+++ tests/t_db_kill_rev_locally_2.at	296391166304e8c739fcc7968ae5f58a36b91265
@@ -0,0 +1,32 @@
+AT_SETUP([db kill_rev_locally command 2])
+MONOTONE_SETUP
+
+# start off with three revisions
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+ANCESTOR=`BASE_REVISION`
+
+SET_FILE(testfile, [stuff stuff
+])
+COMMIT(testbranch)
+CHILD1=`BASE_REVISION`
+
+SET_FILE(testfile, [blahdy blah blay
+])
+COMMIT(testbranch)
+CHILD2=`BASE_REVISION`
+
+# kill head revision
+AT_CHECK(MONOTONE automate get_revision $CHILD2, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db kill_rev_locally $CHILD2, [], [ignore], [ignore])
+AT_CHECK(MONOTONE automate get_revision $CHILD2, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE db check, [], ignore, ignore)
+
+# head is an older revision now, let's kill that too
+AT_CHECK(MONOTONE automate get_revision $CHILD1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db kill_rev_locally $CHILD1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE automate get_revision $CHILD1, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE db check, [], ignore, ignore)
+
+AT_CLEANUP
============================================================
--- tests/t_log_nofiles_nomerges.at	dedc7b333ac5e779f29464a1f62285ec787b6dd4
+++ tests/t_log_nofiles_nomerges.at	dedc7b333ac5e779f29464a1f62285ec787b6dd4
@@ -0,0 +1,41 @@
+AT_SETUP([log --no-files and --merges])
+MONOTONE_SETUP
+
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+R1=`BASE_REVISION`
+
+# check that changed (added) file is listed in the log output
+AT_CHECK(MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep testfile stdout, [], [ignore])
+
+# and that it has been excluded by --no-files
+AT_CHECK(MONOTONE log --no-files, [], [stdout], [ignore])
+AT_CHECK(grep testfile stdout, [1], [ignore])
+
+# add create some divergence...
+SET_FILE(testfile, [stuff stuff
+])
+COMMIT(testbranch)
+
+REVERT_TO($R1)
+
+ADD_FILE(nufile, [moo moo
+])
+COMMIT(testbranch)
+
+# ...and now merge it cleanly
+AT_CHECK(MONOTONE merge, [], [ignore], [ignore])
+AT_CHECK(MONOTONE update, [], [ignore], [ignore])
+R2=`BASE_REVISION`
+
+# check that merge is included by default
+AT_CHECK(MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep '^Revision' stdout | grep $R2, [], [ignore])
+
+# and that it is excluded by --no-merges
+AT_CHECK(MONOTONE log --no-merges, [], [stdout], [ignore])
+AT_CHECK(grep '^Revision' stdout | grep $R2, [1], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_log_selectors.at	3d000a79a2acdff3df5c7a8a804d2e38aa035dc5
+++ tests/t_log_selectors.at	3d000a79a2acdff3df5c7a8a804d2e38aa035dc5
@@ -0,0 +1,26 @@
+AT_SETUP([log and selectors returning multiple rids])
+MONOTONE_SETUP
+
+# testcase for bug #15877
+
+ADD_FILE(testfile, [blah blah
+])
+AT_CHECK(MONOTONE commit -b testbranch --date "2005-08-16T03:16:00" -m foo, [], [ignore], [ignore])
+R0=`BASE_REVISION`
+
+SET_FILE(testfile, [stuff stuff
+])
+AT_CHECK(MONOTONE commit -b testbranch --date "2005-08-16T03:16:00" -m foo, [], [ignore], [ignore])
+R1=`BASE_REVISION`
+
+SET_FILE(testfile, [other other
+])
+AT_CHECK(MONOTONE commit -b otherbranch --date "2005-08-16T03:16:05" -m foo, [], [ignore], [ignore])
+R2=`BASE_REVISION`
+
+AT_CHECK(RAW_MONOTONE --db=$_ROOT_DIR/test.db --root=$_ROOT_DIR log --brief --revision d:2005-08-16, [], [stdout], [ignore])
+AT_CHECK(grep $R0 stdout, [0], [ignore])
+AT_CHECK(grep $R1 stdout, [0], [ignore])
+AT_CHECK(grep $R2 stdout, [0], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_log_to_file.at	4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c
+++ tests/t_log_to_file.at	4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c
@@ -0,0 +1,17 @@
+# -*- Autoconf -*-
+
+AT_SETUP([check --log])
+
+MONOTONE_SETUP
+
+AT_DATA(input.txt, [random content
+])
+
+AT_CHECK(MONOTONE add input.txt, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE --branch=testbranch --log=log.log commit -m "test", [], [stdout], [ignore])
+
+AT_CHECK(QGREP('^monotone:' stdout), [1])
+AT_CHECK(QGREP('^monotone:' log.log), [0])
+
+AT_CLEANUP
============================================================
--- tests/t_pivot_root.at	2bf3634c3c1a16c375a85bc5f403992422cdfc8b
+++ tests/t_pivot_root.at	2bf3634c3c1a16c375a85bc5f403992422cdfc8b
@@ -0,0 +1,52 @@
+AT_SETUP([pivot_root])
+MONOTONE_SETUP
+
+# possible problems:
+#   -- the new root doesn't exist
+#   -- the new root is not a dir
+#   -- the new root has an MT in it
+#   -- the directory the old root is supposed to end up in doesn't exist
+#   -- the directory the old root is supposed to end up in is not a directory
+#   -- the directory the old root is supposed to end up in already
+#      contains something with the given name
+# then make sure --execute puts things in the right place...
+
+AT_CHECK(mkdir workspace)
+AT_CHECK(cd workspace/ && MONOTONE setup . -b testbranch, [], [ignore], [ignore])
+
+AT_CHECK(mkdir workspace/dir1)
+AT_CHECK(mkdir workspace/dir1/dir2)
+AT_DATA(workspace/dir1/file1, [blah blah
+])
+AT_CHECK(mkdir workspace/dir3)
+AT_CHECK(mkdir workspace/dir3/MT)
+AT_CHECK(cd workspace/ && MONOTONE add ., [], [ignore], [ignore])
+
+AT_CHECK(cd workspace/ && MONOTONE commit -m foo, [], [ignore], [ignore])
+
+AT_CHECK(cd workspace/ && MONOTONE pivot_root nosuchdir foo, [1], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE pivot_root dir1/file1 foo, [1], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE pivot_root dir3 old_root, [1], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE pivot_root dir1 nosuchdir/old_root, [1], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE pivot_root dir1 file1/old_root, [1], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE pivot_root dir1 dir2, [1], [ignore], [ignore])
+
+AT_CHECK(cd workspace/ && MONOTONE ls changed, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls missing, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls unknown, [], [], [])
+
+AT_CHECK(cd workspace/ && MONOTONE pivot_root --execute dir1 old_root, [], [ignore], [ignore])
+
+AT_CHECK(test -d workspace/MT)
+AT_CHECK(test -d workspace/dir2)
+AT_CHECK(test -f workspace/file1)
+AT_CHECK(test -d workspace/old_root)
+AT_CHECK(test -d workspace/old_root/dir3)
+AT_CHECK(test -d workspace/old_root/dir3/MT)
+
+AT_CHECK(cd workspace/ && MONOTONE ls missing, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls unknown, [], [], [])
+
+AT_CHECK(cd workspace/ && MONOTONE commit -m foo, [], [ignore], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_pivot_root_revert.at	bf2c402b7cb49ebdd178928ea01372deb68858a5
+++ tests/t_pivot_root_revert.at	bf2c402b7cb49ebdd178928ea01372deb68858a5
@@ -0,0 +1,47 @@
+AT_SETUP([reverting a pivot_root])
+MONOTONE_SETUP
+
+# This test is a bug report
+# I think the problem is just generally that revert does not do a good
+# job cleaning up after renames?
+AT_XFAIL_IF(true)
+
+AT_CHECK(mkdir workspace)
+AT_CHECK(cd workspace/ && MONOTONE setup . -b testbranch, [], [ignore], [ignore])
+
+AT_CHECK(mkdir workspace/dir1)
+AT_CHECK(mkdir workspace/dir1/dir2)
+AT_DATA(workspace/dir1/file1, [blah blah
+])
+AT_CHECK(mkdir workspace/dir3)
+AT_CHECK(mkdir workspace/dir3/MT)
+AT_CHECK(cd workspace/ && MONOTONE add ., [], [ignore], [ignore])
+
+AT_CHECK(cd workspace/ && MONOTONE commit -m foo, [], [ignore], [ignore])
+
+AT_CHECK(cd workspace/ && MONOTONE pivot_root --execute dir1 old_root, [], [ignore], [ignore])
+
+AT_CHECK(test -d workspace/MT)
+AT_CHECK(test -d workspace/dir2)
+AT_CHECK(test -f workspace/file1)
+AT_CHECK(test -d workspace/old_root)
+AT_CHECK(test -d workspace/old_root/dir3)
+AT_CHECK(test -d workspace/old_root/dir3/MT)
+
+AT_CHECK(cd workspace/ && MONOTONE ls missing, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls unknown, [], [], [])
+
+AT_CHECK(cd workspace/ && MONOTONE revert ., [], [ignore], [ignore])
+
+AT_CHECK(test -d workspace/MT)
+AT_CHECK(test -d workspace/dir1)
+AT_CHECK(test -d workspace/dir1/dir2)
+AT_CHECK(test -f workspace/dir1/file1)
+AT_CHECK(test -d workspace/dir3)
+AT_CHECK(test -d workspace/dir3/MT)
+
+AT_CHECK(cd workspace/ && MONOTONE ls changed, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls missing, [], [], [])
+AT_CHECK(cd workspace/ && MONOTONE ls unknown, [], [], [])
+
+AT_CLEANUP
============================================================
--- tests/t_pivot_root_update.at	e4f51059ec68ec4f187cd3593eeb49459aea3b5a
+++ tests/t_pivot_root_update.at	e4f51059ec68ec4f187cd3593eeb49459aea3b5a
@@ -0,0 +1,49 @@
+AT_SETUP([updating through a pivot_root])
+MONOTONE_SETUP
+
+AT_CHECK(mkdir workspace)
+AT_CHECK(cd workspace/ && MONOTONE setup -b testbranch, [], [ignore], [ignore])
+
+AT_CHECK(mkdir workspace/dir1)
+AT_DATA(workspace/old_root_file, [I'm in the root to start off with!
+])
+AT_DATA(workspace/dir1/new_root_file, [I'm in the subdir to start off with.
+])
+AT_CHECK(cd workspace/ && MONOTONE add ., [], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE commit -m foo, [], [ignore], [ignore])
+BASE_REV=`cat workspace/MT/revision`
+
+AT_CHECK(cd workspace/ && MONOTONE pivot_root --execute dir1 old_root, [], [ignore], [ignore])
+AT_CHECK(cd workspace/ && MONOTONE commit -m foo, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE co -r $BASE_REV testspace, [], [ignore], [ignore])
+AT_DATA(new_old_root_file, [old root file modified
+])
+AT_DATA(new_new_root_file, [new root file modified
+])
+AT_DATA(new_unversioned_root_file, [newly placed in root dir, unversioned
+])
+AT_DATA(new_unversioned_subdir_file, [newly placed in sub dir, unversioned
+])
+AT_DATA(new_versioned_root_file, [newly placed in root dir, versioned
+])
+AT_DATA(new_versioned_subdir_file, [newly placed in sub dir, versioned
+])
+AT_CHECK(cp new_old_root_file testspace/old_root_file)
+AT_CHECK(cp new_new_root_file testspace/dir1/new_root_file)
+AT_CHECK(cp new_unversioned_root_file testspace)
+AT_CHECK(cp new_unversioned_subdir_file testspace/dir1)
+AT_CHECK(cp new_versioned_root_file testspace)
+AT_CHECK(cp new_versioned_subdir_file testspace/dir1)
+
+AT_CHECK(cd testspace/ && MONOTONE add new_versioned_root_file dir1/new_versioned_subdir_file, [], [ignore], [ignore])
+AT_CHECK(cd testspace/ && MONOTONE update, [], [ignore], [ignore])
+
+AT_CHECK(cmp new_old_root_file testspace/old_root/old_root_file)
+AT_CHECK(cmp new_new_root_file testspace/new_root_file)
+AT_CHECK(cmp new_unversioned_root_file testspace/old_root/new_unversioned_root_file)
+AT_CHECK(cmp new_unversioned_subdir_file testspace/new_unversioned_subdir_file)
+AT_CHECK(cmp new_versioned_root_file testspace/old_root/new_versioned_root_file)
+AT_CHECK(cmp new_versioned_subdir_file testspace/new_versioned_subdir_file)
+
+AT_CLEANUP
============================================================
--- tests/t_revert_new_project.at	ac8b9497aa5d1a89d01be066365bddb8b3889baf
+++ tests/t_revert_new_project.at	ac8b9497aa5d1a89d01be066365bddb8b3889baf
@@ -0,0 +1,32 @@
+#  -*- Autoconf -*-
+
+AT_SETUP([revert file in new project])
+
+AT_XFAIL_IF(true)
+
+MONOTONE_SETUP
+
+
+# reverting one of one files
+AT_DATA(testfile0, [version 0 of first test file
+])
+
+AT_CHECK(MONOTONE add testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE revert testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE status, [], [stdout], [ignore])
+AT_CHECK(grep testfile0 stdout, [1], [ignore])
+
+
+# reverting one of two files
+AT_DATA(testfile0, [version 0 of first test file
+])
+AT_DATA(testfile1, [version 0 of second test file
+])
+
+AT_CHECK(MONOTONE add testfile0 testfile1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE revert testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE status, [], [stdout], [ignore])
+AT_CHECK(grep testfile0 stdout, [1], [ignore])
+
+
+AT_CLEANUP
============================================================
--- tests/t_rosterify_root_suture.at	ff625956c64676b2b33f9ccc9f9a45b7b7587318
+++ tests/t_rosterify_root_suture.at	ff625956c64676b2b33f9ccc9f9a45b7b7587318
@@ -0,0 +1,124 @@
+AT_SETUP([db rosterify on a db with a root suture])
+MONOTONE_SETUP
+NEED_UNGZB64
+
+AT_DATA([test.db.dump.gz.b64], [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
+])
+
+AT_CHECK(rm -f test.db)
+
+UNGZB64(test.db.dump.gz.b64, test.db.dump)
+AT_CHECK(MONOTONE db load < test.db.dump, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db migrate, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db rosterify, [], [ignore], [ignore])
+
+AT_CHECK(for REV in `MONOTONE automate select i:`; do MONOTONE automate get_revision $REV; done, [], [stdout], [ignore])
+AT_CHECK(QGREP('delete ""' stdout))
+AT_CHECK(QGREP('add_dir ""' stdout))
+
+AT_CLEANUP
============================================================
--- ChangeLog	cf7af27d617c006696a08efcd68a9bd9fd401a7a
+++ ChangeLog	cef9fe8e359d630eb8f61133684772293748eade
@@ -1,3 +1,304 @@
+2006-02-27  Matt Johnston  <matt@ucc.asn.au>
+
+	* std_hooks.lua (ignore_file, dir_matches): add dir_matches helper
+	to avoid including ignored dirs such as '.svn', since dirs now
+	actually exist.
+
+2006-02-26  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc: Update notes on tests.
+
+2006-02-25  Nathaniel Smith  <njs@pobox.com>
+
+	* work.cc (attach_node): Apparently the tests depend on update
+	clobbering existing non-versioned files... and we don't have a
+	good solution _anyway_, so just go back to clobbering them.
+
+2006-02-25  Nathaniel Smith  <njs@pobox.com>
+
+	* cset.cc (root_dir_test, invalid_csets_test): Don't test that
+	root dir stuff fails.  Test that it works.
+
+2006-02-25  Nathaniel Smith  <njs@pobox.com>
+
+	* roster.cc (detach_node): Add missing invariant.
+
+2006-02-25  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc (roster_merge): Fix strange merge-created
+	problem...
+
+2006-02-25  Nathaniel Smith  <njs@pobox.com>
+
+	* work.cc (attach_node): This code should use path_exists, not
+	file_exists.
+
+2006-02-24  Timothy Brownawell  <tbrownaw@gmail.com>
+
+	* netcmd.cc: Ignore protocol version field on usher_cmd packets. It
+	should now be possible to use an usher to redirect connections based
+	on netsync version.
+	* netcmd.hh: Remove unused netcmd::get_version() and
+	unused/unimplemented netcmd::netcmd(u8 version).
+
+2006-02-24  Richard Levitte  <richard@levitte.org>
+
+	* commands.cc (ls_changed): I was a bit overly paranoid about the
+	possibilities with C++ and defined an explicit functor for the set
+	instead of relying on the automatic generation of less<file_path>.
+	Derek Scherger made me realise I was a bit overzealous, and this
+	change removes the explicit functor.
+
+2006-02-23  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* enumerator.hh: Another GCC 4.1 compile fix.
+
+	* tests/t_log_selectors.at: UnXFAIL.
+
+	* commands.cc (complete): Refactor selector completion to enable
+	return of single or sets of completed revisions.
+	(CMD(log)): Do something sensible with selectors that return
+	multiple revisions.
+
+	* tests/t_log_selectors.at: XFAILed test for bug #15877.
+
+	* testsuite.at: Add it.
+
+	* app_state.cc, app_state.hh, commands.cc, monotone.cc,
+	options.hh: Revert failed UI experiment: reenable logging merges
+	by default and rename --merges back to --no-merges.
+
+	* contrib/color-logs.{conf,sh}, contrib/monotone-notify.pl,
+	contrib/monotone.el, tests/t_log_nofiles_nomerges.at,
+	testsuite.at: Handle --no-merges.
+
+	* monotone.texi: Document --no-merges.
+
+2006-02-23  Matt Johnston  <matt@ucc.asn.au>
+
+	* enumerator.{cc,hh}: avoid transferring deltas on both sides of merge
+	revisions, and prefer deltas to data when both are available.
+	See
+	https://savannah.nongnu.org/bugs/?func=detailitem&item_id=15846
+
+2006-02-21  Nathaniel Smith  <njs@pobox.com>
+
+	* work.cc (detach_node): This time for sure!
+
+2006-02-21  Nathaniel Smith  <njs@pobox.com>
+
+	* work.cc (detach_node): Oops, x != y != !(x == y).
+
+2006-02-21  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc: Fixup after merge.
+
+2006-02-21  Nathaniel Smith  <njs@pobox.com>
+
+	* work.cc (detach_node): Check if we are passed the root dir, and
+	error out if so.
+
+2006-02-21  Matt Johnston  <matt@ucc.asn.au>
+
+	* commands.cc (pid_file): newline-terminate the pid
+
+2006-02-21  Richard Levitte  <richard@levitte.org>
+
+	* contrib/usher.cc (server::set_hosts): Erasing the list node that
+	we're iterating on, then trying to go to the next node doesn't
+	work.  Save the iterator, then increment it before erasing the
+	node using the saved value.  No more segfaults.
+
+2006-02-21  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* sanity.hh: Work around roster_merge.cc compilation failure with
+	GCC 3.4.
+
+2006-02-20  Richard Levitte  <richard@levitte.org>
+
+	* monotone.cc (cpp_main), options.hh, ui.cc (redirect_log_to),
+	ui.hh (struct user_interface): Add --log option, to redirect the
+	log lines to a file.
+
+	* monotone.texi (OPTIONS): Document it.
+
+	* po/sv.po: Translate help for this option to Swedish.
+
+	* testsuite.at, tests/t_log_to_file.at: Test it.
+
+2006-02-20  Matt Johnston  <matt@ucc.asn.au>
+
+	* database.cc (remove_version): get rid of dangling deltas,
+	don't try to put data or deltas if they already exist.
+	* tests/t_db_kill_rev_locally_2.at: un-XFAIL
+
+2006-02-20  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* testsuite.at: Add an ADD_FILE variant that allows use of
+	alternate databases.
+
+	* tests/t_netsync_permissions.at: Missed some cases of the
+	database locking race.
+
+2006-02-19  Nathaniel Smith  <njs@pobox.com>
+
+	* ChangeLog: Fixup after xxdiff lossage.
+
+2006-02-19  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc (make_lifecycle_objs): Fix test bug.
+
+2006-02-19  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* testsuite.at: Add a REVERT_TO variant that allows use of
+	alternate databases.
+
+	* tests/t_netsync_permissions.at: Attempt to avoid a database
+	locking race in this test that is causing spurious failures by
+	using the new REVERT_TO variant to cause revert to be performed
+	using the "client" database.
+
+2006-02-19  Nathaniel Smith  <njs@pobox.com>
+
+	* roster.cc (shallow_equal): Publically expose.
+	* roster.cc, roster_merge.cc: Various compile fixes.
+
+2006-02-19  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.{hh,cc}: Make terminology more consistent.
+	"marking_map" type -> "markings" name, "marking_t" type ->
+	"marking" name.
+
+2006-02-19  Nathaniel Smith  <njs@pobox.com>
+
+	* roster.{hh,cc} (testing_node_id_source): Make this node source
+	available to unit tests in other files.
+	* roster_merge.cc (test_roster_merge_node_lifecycle): New test.
+	Still quite ugly.
+
+2006-02-18  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc (roster_merge): Remove obsolete FIXME.
+
+2005-10-19  Matthew A. Nicholson  <matt@matt-land.com>
+
+	* contrib/monotone.bash_completion: Update for 0.25.
+
+2006-02-19  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* cset.hh (struct editable_tree): Add commit() member function to
+	editable_tree.
+
+	* cset.cc (cset::apply_to): Call editable_tree::commit() after
+	applying any other changes.
+
+	* roster.hh, roster.cc: Empty implementation of
+	editable_roster_base::commit().
+
+	* work.hh, work.cc: Implementation of
+	editable_working_tree::commit() that ensures all detached nodes
+	have been reattached.
+
+	* work.hh (struct editable_working_tree): Add map for tracking
+	path name mappings across node detach operations.
+
+	* work.cc (editable_working_tree::detach_node): Insert path name
+	mappings into map.
+	(editable_working_tree::drop_detached_node,
+	editable_working_tree::attach_node): Report add/drop/rename
+	operations during workspace updates.
+
+	* lua.cc: Use the safer luaL_check* rather than lua_to* in
+	monotone_*_for_lua functions.
+
+2006-02-18  Markus Schiltknecht  <markus@bluegap.ch>
+
+	* tests/t_cvsimport_branch.at, testsuite.at: New XFAIL test for
+	cvs_import branch reconstruction.
+
+2006-02-18  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* tests/t_log_nofiles_merges.at: Add test for the log options
+	--no-files and --merges.
+
+	* testsuite.at: Add t_log_nofiles_merges.at.
+
+2006-02-13  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc (log_conflicts): Tweak string.
+	Add list of tests needed.
+
+2006-02-13  Nathaniel Smith  <njs@pobox.com>
+
+	* roster_merge.cc (is_clean): Simplify.
+	(add_roster_merge_tests):
+	* unit_tests.cc (init_unit_test_suite):
+	* unit_tests.hh (add_roster_merge_tests): Add unit test
+	boilerplate.
+
+2006-02-18  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* tests/t_db_kill_rev_locally_2.at: Add an XFAIL test for a
+	kill_rev_locally bug reported by Daniel Carosone.
+
+	* testsuite.at: Add t_db_kill_rev_locally_2.at.
+
+	* sqlite/parse.h: Regenerated parse.h from pristine SQLite 3.3.4
+	source.  The version committed in the 3.3.4 import had a bunch of
+	duplicate entries.
+
+	* commands.cc (CMD(identify)): This isn't really a "workspace"
+	command--stick it under "debug" for lack of a better place.
+
+	* commands.cc (CMD(refresh_inodeprints)): Check for a valid
+	workspace rather than failing with an invariant when run outside
+	of a workspace.
+
+	* tests/t_revert_new_project.at: Add an XFAIL test for a bug where
+	reverting a file added in a new project will leave the workspace
+	in a bad state until MT/work is removed manually.
+
+	* testsuite.at: Add t_revert_new_project.at.
+
+	* app_state.cc, app_state.hh, commands.cc, monotone.cc,
+	options.hh: Add '--no-files' option to log to allow users to
+	exclude the list of files changed in each revision from the log
+	output.
+
+	* monotone.texi: Document '--no-files', and '--next' and '--diffs'
+	while there.
+
+2006-02-17  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* lua.cc, lua.hh, monotone.texi, std_hooks.lua, test_hooks.lua,
+	testsuite.at: Remove unused non_blocking_rng_ok hook.
+
+	* sqlite/*: Import SQLite 3.3.4.
+
+2006-02-16  Patrick Mauritz  <oxygene@studentenbude.ath.cx>
+
+	* netsync.cc (handle_new_connection): Netxx::Address.get_name()
+	returns NULL every now and then. if so, continue with "" instead
+
+	* sqlite/parse.c: move #line under all #include directives so
+	the compiler can't be confused by it.
+
+2006-02-14  Richard Levitte  <richard@levitte.org>
+
+	* Makefile.am (htmldir): Add variables so monotone.html is created
+	and installed automatically.
+	This is prompted by debian/monotone.html, which indicates
+	monotone.html should be available.
+
+	* netsync.cc (serve_connections): Correct spelling.
+
+2006-02-13  Matthew Gregan  <kinetik@orcon.net.nz>
+
+	* sanity.cc (sanity::dump_buffer): Fix a SEGV when we're in an
+	error unwind and about to ask the user to mail us the crash
+	log--we must use FL() rather than F() here, since by the time this
+	is called we can't rely on the i18n infrastructure being alive.
+
 2006-02-12  Nathaniel Smith  <njs@pobox.com>

 	* netsync.cc (serve_connections): Revert garbage that I
============================================================
--- Makefile.am	d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1
+++ Makefile.am	380383c22ef6bb6b1d7203b215dbed739c249c63
@@ -241,6 +241,9 @@ lib3rdparty_a_SOURCES = $(BOOST_SANDBOX_
 			$(LUA_SOURCES) \
 			$(SQLITE_SOURCES)

+htmldir = $(datadir)/doc/monotone
+html_DATA = monotone.html
+
 # flags

 if BUILD_PCH
============================================================
--- app_state.cc	18045740e735562c70e3a482927003729014844f
+++ app_state.cc	4990c26751504dded9cef9b1c6ffa66bef0d2b32
@@ -31,12 +31,12 @@ app_state::app_state()
 app_state::app_state()
   : branch_name(""), db(system_path()), keys(this), stdhooks(true),
     rcfiles(true), diffs(false),
-    merges(false), set_default(false), verbose(false), date_set(false),
+    no_merges(false), set_default(false), verbose(false), date_set(false),
     search_root("/"),
     depth(-1), last(-1), next(-1), diff_format(unified_diff), diff_args_provided(false),
     use_lca(false), execute(false), bind_address(""), bind_port(""),
     missing(false), unknown(false),
-    confdir(get_default_confdir()), have_set_key_dir(false)
+    confdir(get_default_confdir()), have_set_key_dir(false), no_files(false)
 {
   db.set_app(this);
   lua.set_app(this);
============================================================
--- app_state.hh	7fa51b357c748547e5d71dbc84fb35077c148177
+++ app_state.hh	03afbc7ba543f0b26f8ddf70d97c05e872cdb36b
@@ -40,7 +40,7 @@ public:
   bool stdhooks;
   bool rcfiles;
   bool diffs;
-  bool merges;
+  bool no_merges;
   bool set_default;
   bool verbose;
   options_map options;
@@ -73,6 +73,7 @@ public:
   system_path confdir;
   bool have_set_key_dir;
   std::set<std::string> attrs_to_drop;
+  bool no_files;

   std::map<int, bool> explicit_option_map;  // set if the value of the flag was explicitly given on the command line
   void set_is_explicit_option (int option_id);
============================================================
--- commands.cc	dbf77e72442ab85b8b4390b8fb1316ca8145d507
+++ commands.cc	0fc12a37debd7db7812e2670afcb99d787f869e0
@@ -300,7 +300,7 @@ struct pid_file
       return;
     require_path_is_nonexistent(path, F("pid file '%s' already exists") % path);
     file.open(path.as_external().c_str());
-    file << get_process_id();
+    file << get_process_id() << endl;
     file.flush();
   }

@@ -461,10 +461,11 @@ describe_revision(app_state & app, revis
   return description;
 }

+
 static void
 complete(app_state & app,
          string const & str,
-         revision_id & completion,
+         set<revision_id> & completion,
          bool must_exist=true)
 {
   // This copies the start of selectors::parse_selector().to avoid
@@ -475,10 +476,10 @@ complete(app_state & app,
   if (str.find_first_not_of(constants::legal_id_bytes) == string::npos
       && str.size() == constants::idlen)
     {
-      completion = revision_id(str);
+      completion.insert(revision_id(str));
       if (must_exist)
-        N(app.db.revision_exists(completion),
-          F("no such revision '%s'") % completion);
+        N(app.db.revision_exists(*completion.begin()),
+          F("no such revision '%s'") % *completion.begin());
       return;
     }

@@ -494,16 +495,36 @@ complete(app_state & app,

   N(completions.size() != 0,
     F("no match for selection '%s'") % str);
+
+  for (set<string>::const_iterator i = completions.begin();
+       i != completions.end(); ++i)
+    {
+      pair<set<revision_id>::const_iterator, bool> p = completion.insert(revision_id(*i));
+      P(F("expanded to '%s'\n") % *(p.first));
+    }
+}
+
+
+static void
+complete(app_state & app,
+         string const & str,
+         revision_id & completion,
+         bool must_exist=true)
+{
+  set<revision_id> completions;
+
+  complete(app, str, completions, must_exist);
+
   if (completions.size() > 1)
     {
       string err = (F("selection '%s' has multiple ambiguous expansions: \n") % str).str();
-      for (set<string>::const_iterator i = completions.begin();
+      for (set<revision_id>::const_iterator i = completions.begin();
            i != completions.end(); ++i)
-        err += (describe_revision(app, revision_id(*i)) + "\n");
+        err += (describe_revision(app, *i) + "\n");
       N(completions.size() == 1, i18n_format(err));
     }
-  completion = revision_id(*(completions.begin()));
-  P(F("expanded to '%s'\n") %  completion);
+
+  completion = *completions.begin();
 }


@@ -1243,6 +1264,23 @@ ALIAS(mv, rename)
 ALIAS(mv, rename)


+CMD(pivot_root, N_("workspace"), N_("NEW_ROOT PUT_OLD"),
+    N_("rename the root directory\n"
+       "after this command, the directory that currently has the name NEW_ROOT\n"
+       "will be the root directory, and the directory that is currently the root\n"
+       "directory will have name PUT_OLD.\n"
+       "Using --execute is strongly recommended."),
+    OPT_EXECUTE)
+{
+  if (args.size() != 2)
+    throw usage(name);
+
+  app.require_workspace();
+  file_path new_root = file_path_external(idx(args, 0));
+  file_path put_old = file_path_external(idx(args, 1));
+  perform_pivot_root(new_root, put_old, app);
+}
+
 // fload and fmerge are simple commands for debugging the line
 // merger.

@@ -1339,7 +1377,7 @@ CMD(status, N_("informative"), N_("[PATH
 }


-CMD(identify, N_("workspace"), N_("[PATH]"),
+CMD(identify, N_("debug"), N_("[PATH]"),
     N_("calculate identity of PATH or stdin"),
     OPT_NONE)
 {
@@ -1740,13 +1778,6 @@ ls_missing (app_state & app, vector<utf8
 }


-struct lt_file_path
-{
-  bool operator()(const file_path &fp1, const file_path &fp2) const
-  {
-    return fp1 < fp2;
-  }
-};
 static void
 ls_changed (app_state & app, vector<utf8> const & args)
 {
@@ -1754,7 +1785,7 @@ ls_changed (app_state & app, vector<utf8
   revision_id rid;
   roster_t old_roster, new_roster;
   data tmp;
-  std::set<file_path, lt_file_path> files;
+  std::set<file_path> files;

   app.require_workspace();
   get_working_revision_and_rosters(app, args, rs, old_roster, new_roster);
@@ -3219,6 +3250,7 @@ CMD(refresh_inodeprints, N_("tree"), "",
 CMD(refresh_inodeprints, N_("tree"), "", N_("refresh the inodeprint cache"),
     OPT_NONE)
 {
+  app.require_workspace();
   enable_inodeprints();
   maybe_update_inodeprints(app);
 }
@@ -3409,7 +3441,11 @@ CMD(revert, N_("workspace"), N_("[PATH].
         }
       else
         {
-          mkdir_p(fp);
+          if (!directory_exists(fp))
+            {
+              P(F("recreating %s/") % fp);
+              mkdir_p(fp);
+            }
         }
     }

@@ -3541,7 +3577,8 @@ CMD(log, N_("informative"), N_("[FILE] .
 CMD(log, N_("informative"), N_("[FILE] ..."),
     N_("print history in reverse order (filtering by 'FILE'). If one or more\n"
     "revisions are given, use them as a starting point."),
-    OPT_LAST % OPT_NEXT % OPT_REVISION % OPT_BRIEF % OPT_DIFFS % OPT_MERGES)
+    OPT_LAST % OPT_NEXT % OPT_REVISION % OPT_BRIEF % OPT_DIFFS % OPT_NO_MERGES %
+    OPT_NO_FILES)
 {
   if (app.revision_selectors.size() == 0)
     app.require_workspace("try passing a --revision to start at");
@@ -3561,11 +3598,11 @@ CMD(log, N_("informative"), N_("[FILE] .
       for (std::vector<utf8>::const_iterator i = app.revision_selectors.begin();
            i != app.revision_selectors.end(); i++)
         {
-          revision_id rid;
-          complete(app, (*i)(), rid);
-          frontier.insert(rid);
+          set<revision_id> rids;
+          complete(app, (*i)(), rids);
+          frontier.insert(rids.begin(), rids.end());
           if (i == app.revision_selectors.begin())
-            first_rid = rid;
+            first_rid = *rids.begin();
         }
     }

@@ -3688,7 +3725,7 @@ CMD(log, N_("informative"), N_("[FILE] .
                    inserter(next_frontier, next_frontier.end()));
             }

-          if (!app.merges && rev.is_merge_node())
+          if (app.no_merges && rev.is_merge_node())
             print_this = false;

           if (print_this)
@@ -3716,7 +3753,7 @@ CMD(log, N_("informative"), N_("[FILE] .
                 log_certs(app, rid, branch_name, "Branch: ", false);
                 log_certs(app, rid, tag_name,    "Tag: ",    false);

-                if (! csum.cs.empty())
+                if (!app.no_files && !csum.cs.empty())
                   {
                     cout << endl;
                     csum.print(cout, 70);
============================================================
--- contrib/color-logs.conf	ffe3e7270a2952c508db2f2d9c3df82e05c859f4
+++ contrib/color-logs.conf	87e8ceac1e0a8d173e2a0da01e659d048824e9ed
@@ -1,6 +1,6 @@
 #
 # this is a colorization config for reading the output of "monotone log"
-# or "monotone diff", or best of all "monotone log --diffs".
+# or "monotone diff", or best of all "monotone log --no-merges --diffs".
 #
 # use with the "colorize" script in this dir, or color-logs.sh
 #
============================================================
--- contrib/color-logs.sh	90a0de6aa87b7f4b39f7947fd1d359a3cc936385
+++ contrib/color-logs.sh	4e04daeee4ee8ce8bf6ce45f074ba16faf50ccf9
@@ -1,5 +1,5 @@
 #!/bin/sh

-./monotone log --diffs $@    \
+./monotone log --diffs --no-merges $@    \
   | ./contrib/colorize -c contrib/color-logs.conf  \
   | less -r -p -----------------------------------------------------------------
============================================================
--- contrib/monotone-notify.pl	aa93d7f9f601b51d607bd4d779e472067c41d5a2
+++ contrib/monotone-notify.pl	d7f551f0f332f56785aaa59e99ade7400c8da84a
@@ -268,7 +268,7 @@ if ($mail || $debug) {
     foreach my $revision (keys %revisions) {
 	$revision_data{$revision} =
 	    [ map { chomp; $_ }
-	      my_backtick("$monotone$database log --last=1 --merges --revision=$revision") ];
+	      my_backtick("$monotone$database log --last=1 --revision=$revision") ];
 	my $date = (split(' ', (grep(/^Date:/, @{$revision_data{$revision}}))[0]))[1];

 	if (defined $before && $date ge $before) {
@@ -582,7 +582,7 @@ sub revision_is_in_branch
     if (!defined $$revision_data{$revision}) {
 	$$revision_data{$revision} =
 	    [ map { chomp; $_ }
-	      my_backtick("$monotone$database log --last=1 --merges --revision=$revision") ];
+	      my_backtick("$monotone$database log --last=1 --revision=$revision") ];
     }

     map {
============================================================
--- contrib/monotone.bash_completion	d942f24e3f430c7e12fceeb7a58e088e45211971
+++ contrib/monotone.bash_completion	c5fff50c3c591f9dd72f80c3812c506571e3ab74
@@ -1,7 +1,9 @@
 # -*- shell-script -*-
+# vim: set ft=sh:

-# bash completion for monotone 0.18
+# bash completion for monotone 0.25
 # Author: Olivier Andrieu <oandrieu@nerim.net>
+# Contributions by Matthew A. Nicholson <matt@matt-land.com>

 # source this file from your .bashrc
 # If you use the bash completion package <http://www.caliban.org/bash/>,
@@ -42,6 +44,10 @@ _monotone_branches() {
   COMPREPLY=( $(compgen -W "$(monotone $mono_db list branches 2> /dev/null)" -- ${cur#*=} ) )
 }

+_monotone_tags() {
+  COMPREPLY=( $(compgen -W "$(monotone $mono_db list tags 2> /dev/null | awk '{print $1}')" -- ${cur#*=} ) )
+}
+
 _monotone() {
   local cur prev mono_db

@@ -68,6 +74,10 @@ _monotone() {
       cur="${cur#*=}"
       _filedir
       ;;
+    --root=* )
+      cur="${cur#*=}"
+      _filedir -d
+      ;;
     --branch=* )
       _monotone_branches
       ;;
@@ -76,19 +86,22 @@ _monotone() {
       ;;
     --ticker=* )
       cur="${cur#*=}"
-      COMPREPLY=( $(compgen -W 'count dot' -- $cur ) )
+      COMPREPLY=( $(compgen -W 'count dot none' -- $cur ) )
       ;;
     --revision=* )
       _monotone_complete revision
       ;;
     -* )
-      COMPREPLY=( $(compgen -W '--debug --dump --quiet --help --nostd --norc\
-                                --rcfile --key --db --branch --version --full-version\
-                                --ticker --revision --message' -- $cur) )
+      COMPREPLY=( $(compgen -W '--debug --dump --quiet --help --version
+                                --full-version --xargs --ticker --nostd --norc
+                                --rcfile --key --db --root --verbose -k -d -@
+                                -m -b -r --branch --message --date --author
+                                --depth --execute --keydir --confdir
+                                --key-to-push --bind' -- $cur) )
       ;;
     * )
       case $prev in
-        --db | -d | --rcfile | --dump )
+        --db | -d | --rcfile | --dump | --root )
           _filedir
           ;;
         --branch | -b )
@@ -103,105 +116,112 @@ _monotone() {
         --revision | -r )
           _monotone_complete revision
           ;;
-	db )
-	  COMPREPLY=( $(compgen -W 'init info version dump load migrate execute check changesetify rebuild' -- $cur ) )
-	  ;;
-	cdiff | diff | annotate )
+        db )
+          COMPREPLY=( $(compgen -W 'init info version dump load migrate execute kill_rev_locally kill_branch_certs_locally kill_tag_locally check changesetify rebuild set_epoch' -- $cur ) )
+          ;;
+        cdiff | diff | annotate )
           COMPREPLY=( $(compgen -W '--revision' -- $cur ) )
-	  _filedir
-	  ;;
-	log | approve | disapprove | comment | tag | testresult | cert | explicit_merge | trusted | update )
-	  _monotone_complete revision
-	  ;;
-	ls | list )
-	  COMPREPLY=( $(compgen -W 'certs keys branches epochs tags vars known unknown ignored missing' -- $cur ) )
-	  ;;
-	attr )
-	  COMPREPLY=( $(compgen -W 'get set drop' -- $cur ) )
-	  ;;
-	co | checkout )
-	  _filedir -d
-	  _monotone_complete revision
-	  ;;
-	status | cvs_import | add | drop | rename | revert | identify )
-	  _filedir
-	  ;;
-	cat )
-	  COMPREPLY=( $(compgen -W 'file manifest revision' -- $cur) )
-	  ;;
+          _filedir
+          ;;
+        log | approve | disapprove | comment | tag | testresult | cert | explicit_merge | trusted | update )
+          _monotone_complete revision
+          ;;
+        ls | list )
+          COMPREPLY=( $(compgen -W 'certs keys branches epochs tags vars known unknown ignored missing' -- $cur ) )
+          ;;
+        attr )
+          COMPREPLY=( $(compgen -W 'get set drop' -- $cur ) )
+          ;;
+        co | checkout )
+          _filedir -d
+          _monotone_complete revision
+          ;;
+        status | cvs_import | add | drop | rm | rename | mv | revert | identify )
+          _filedir
+          ;;
+        complete )
+          COMPREPLY=( $(compgen -W 'revision manifest file key' -- $cur) )
+          ;;
+        cat )
+          COMPREPLY=( $(compgen -W 'file manifest revision' -- $cur) )
+          ;;
         push | pull | serve | sync )
-	  COMPREPLY=( $(compgen -A hostname -- $cur) )
-	  ;;
-	pubkey | privkey )
-	  _monotone_keys $prev
-	  ;;
-	chkeypass | dropkey )
-	  _monotone_keys privkey
-	  ;;
-	propagate | reindex )
-	  _monotone_branches
-	  ;;
-	* )
-	  if (( $COMP_CWORD >= 2 )) ; then
-	    local prev2=${COMP_WORDS[COMP_CWORD-2]}
-	    case $prev2 in
-	      cdiff | diff | explicit_merge )
-		_monotone_complete revision
-		;;
-	      co | checkout | rename | annotate )
-		_filedir -d
-		;;
-	      cat )
-		_monotone_complete $prev
-		;;
-	      log | attr )
-		_filedir
-		;;
-	      list )
-		if [ $prev == certs ] ; then
-		    _monotone_complete revision
-		    _monotone_complete manifest
-		    _monotone_complete file
-		fi
-		;;
-	      push | pull | serve | sync | propagate )
+          COMPREPLY=( $(compgen -A hostname -- $cur) )
+          ;;
+        pubkey | privkey )
+          _monotone_keys $prev
+          ;;
+        chkeypass | dropkey )
+          _monotone_keys privkey
+          ;;
+        propagate | reindex )
+          _monotone_branches
+          ;;
+        * )
+          if (( $COMP_CWORD >= 2 )) ; then
+            local prev2=${COMP_WORDS[COMP_CWORD-2]}
+            case $prev2 in
+              cdiff | diff | explicit_merge )
+                _monotone_complete revision
+                ;;
+              co | checkout | rename | mv | annotate )
+                _filedir
+                ;;
+              cat )
+                _monotone_complete $prev
+                ;;
+              log | attr )
+                _filedir
+                ;;
+              list )
+                if [ $prev == certs ] ; then
+                    _monotone_complete revision
+                    _monotone_complete manifest
+                    _monotone_complete file
+                fi
+                ;;
+              push | pull | serve | sync | propagate )
                 _monotone_branches
-		;;
-	      * )
-		if (( $COMP_CWORD >= 3 )) ; then
-		    local prev3=${COMP_WORDS[COMP_CWORD-3]}
-		    case $prev3 in
-			explicit_merge )
-			    _monotone_complete revision
-			    _monotone_branches
-			    ;;
-			*)
-			    unset prev2
-			    unset prev3
-		    esac
-		else
-		    unset prev2
-		fi
-		;;
-	    esac
-	  fi
-	  if [ -z "$prev2" ] ; then
-	    COMPREPLY=( $(compgen -W 'db agraph \
-                                      annotate cat cdiff complete diff list log ls status \
-                                      cert chkeypass dropkey genkey trusted \
-                                      pull push reindex serve sync \
-                                      privkey pubkey read \
-                                      cvs_import \
-                                      approve comment disapprove tag testresult \
-                                      checkout co explicit_merge heads merge propagate refresh_inodeprints setup \
-                                      set unset \
-                                      add attr commit drop identify rename revert update' -- $cur) )
-	  fi
-	  ;;
+                ;;
+              * )
+                if (( $COMP_CWORD >= 3 )) ; then
+                    local prev3=${COMP_WORDS[COMP_CWORD-3]}
+                    case $prev3 in
+                        explicit_merge )
+                            _monotone_complete revision
+                            _monotone_branches
+                            ;;
+                        *)
+                            unset prev2
+                            unset prev3
+                    esac
+                else
+                    unset prev2
+                    _filedir
+                fi
+                ;;
+            esac
+          fi
+          if (( $COMP_CWORD < 2 )) ; then
+            COMPREPLY=( $(compgen -W 'automate db agraph fload fmerge lca lcad
+                                      rcs_import annotate cat complete diff
+                                      list log ls status cert chkeypass dropkey
+                                      genkey trusted pull push reindex serve
+                                      sync certs fdata fdelta mdata mdelta
+                                      privkey pubkey rdata read cvs_import
+                                      approve comment disapprove tag testresult
+                                      checkout co explicit_merge fcommit heads
+                                      merge propagate refresh_inodeprints setup
+                                      set unset add attr ci commit drop
+                                      identify mv rename revert rm update' -- $cur) )
+          else
+              _filedir
+          fi
+          ;;
       esac
       ;;
   esac
   return 0
 }

+complete -F _monotone -o filenames monotone
-complete -F _monotone -o default monotone
============================================================
--- contrib/monotone.el	3dc1c23d499d1aa015ed7f145416a241a55f054f
+++ contrib/monotone.el	9e1a1ec218b98cd38c6126c48f00a1d585e65a13
@@ -686,7 +686,7 @@ the buffer if not global."
   (when (eq 'tree (monotone-arg-decode arg))
     (error "monotone subtree log is busted"))
   ;;
-  (let ((cmds (list "log"))
+  (let ((cmds (list "log" "--no-merges"))
         (depth monotone-log-depth))
     (when (and (numberp depth) (< 0 depth))
       (setq cmds (append cmds (list (format "--last=%d" depth)))))
============================================================
--- contrib/usher.cc	cb295e80eb1af0bd7d55cde7da973c340a05deb2
+++ contrib/usher.cc	599b754c575694458973cf7ecd5be5fd5a03c06d
@@ -1,3 +1,4 @@
+// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
 // Timothy Brownawell  <tbrownaw@gmail.com>
 // GPL v2
 //
@@ -691,10 +692,16 @@ struct server
       c = servers_by_host.find(*i);
       if (c != servers_by_host.end()) {
         list<map<string, shared_ptr<server> >::iterator>::iterator j;
-        for (j = c->second->by_host.begin(); j != c->second->by_host.end(); ++j)
-          if ((*j)->first == *i) {
-            servers_by_host.erase(*j);
-            c->second->by_host.erase(j);
+        for (j = c->second->by_host.begin(); j != c->second->by_host.end();)
+          {
+            list<map<string, shared_ptr<server> >::iterator>::iterator j_saved
+              = j;
+            ++j;
+            if ((*j_saved)->first == *i)
+              {
+                servers_by_host.erase(*j_saved);
+                c->second->by_host.erase(j_saved);
+              }
           }
       }
       c = servers_by_host.insert(make_pair(*i, me)).first;
============================================================
--- cset.cc	ac5f2a4848a4c5661496ec4f5af706de1fb6a454
+++ cset.cc	5fdac8f01ad19e4a427e40aa4245026b534422f7
@@ -225,6 +225,8 @@ cset::apply_to(editable_tree & t) const
   for (map<pair<split_path, attr_key>, attr_value>::const_iterator i = attrs_set.begin();
        i != attrs_set.end(); ++i)
     t.set_attr(i->first.first, i->first.second, i->second);
+
+  t.commit();
 }

 ////////////////////////////////////////////////////////////////////
@@ -1070,56 +1072,76 @@ invalid_csets_test()
     BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
   }
   {
-    L(FL("TEST: can't rename root (for now)"));
+    L(FL("TEST: can't delete non-empty directory"));
     setup_roster(r, f1, nis);
     cset cs; MM(cs);
-    split_path sp1, sp2;
-    cs.dirs_added.insert(root);
-    cs.nodes_renamed.insert(std::make_pair(root, baz));
+    cs.nodes_deleted.insert(foo);
     BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
   }
   {
-    L(FL("TEST: can't delete non-empty directory"));
-    setup_roster(r, f1, nis);
+    L(FL("TEST: attach node with no root directory present"));
+    // for this test, make sure original roster has no contents
+    r = roster_t();
     cset cs; MM(cs);
-    cs.nodes_deleted.insert(foo);
+    split_path sp;
+    file_path_internal("blah/blah/blah").split(sp);
+    cs.dirs_added.insert(sp);
     BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
   }
   {
-    L(FL("TEST: can't delete root"));
-    // for this test, make sure root has no contents
-    r = roster_t();
+    L(FL("TEST: can't move a directory underneath itself"));
+    setup_roster(r, f1, nis);
     cset cs; MM(cs);
-    cs.nodes_deleted.insert(root);
+    split_path foo_blah;
+    file_path_internal("foo/blah").split(foo_blah);
+    cs.nodes_renamed.insert(std::make_pair(foo, foo_blah));
     BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
   }
+}
+
+void
+root_dir_test()
+{
+  temp_node_id_source nis;
+  roster_t r;
+  MM(r);
+  editable_roster_base tree(r, nis);
+
+  file_id f1(std::string("0000000000000000000000000000000000000001"));
+
+  split_path root, baz;
+  file_path().split(root);
+  file_path_internal("baz").split(baz);
+
   {
-    L(FL("TEST: can't delete and replace root"));
-    // for this test, make sure root has no contents
-    r = roster_t();
+    L(FL("TEST: can rename root"));
+    setup_roster(r, f1, nis);
     cset cs; MM(cs);
-    cs.nodes_deleted.insert(root);
+    split_path sp1, sp2;
     cs.dirs_added.insert(root);
-    BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
+    cs.nodes_renamed.insert(std::make_pair(root, baz));
+    cs.apply_to(tree);
+    r.check_sane(true);
   }
   {
-    L(FL("TEST: attach node with no root directory present"));
+    L(FL("TEST: can delete root (but it makes us insane)"));
     // for this test, make sure root has no contents
     r = roster_t();
+    r.attach_node(r.create_dir_node(nis), root);
     cset cs; MM(cs);
-    split_path sp;
-    file_path_internal("blah/blah/blah").split(sp);
-    cs.dirs_added.insert(sp);
-    BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
+    cs.nodes_deleted.insert(root);
+    cs.apply_to(tree);
+    BOOST_CHECK_THROW(r.check_sane(true), std::logic_error);
   }
   {
-    L(FL("TEST: can't move a directory underneath itself"));
-    setup_roster(r, f1, nis);
+    L(FL("TEST: can delete and replace root"));
+    r = roster_t();
+    r.attach_node(r.create_dir_node(nis), root);
     cset cs; MM(cs);
-    split_path foo_blah;
-    file_path_internal("foo/blah").split(foo_blah);
-    cs.nodes_renamed.insert(std::make_pair(foo, foo_blah));
-    BOOST_CHECK_THROW(cs.apply_to(tree), std::logic_error);
+    cs.nodes_deleted.insert(root);
+    cs.dirs_added.insert(root);
+    cs.apply_to(tree);
+    r.check_sane(true);
   }
 }

@@ -1130,6 +1152,7 @@ add_cset_tests(test_suite * suite)
   suite->add(BOOST_TEST_CASE(&basic_csets_test));
   suite->add(BOOST_TEST_CASE(&invalid_csets_test));
   suite->add(BOOST_TEST_CASE(&cset_written_test));
+  suite->add(BOOST_TEST_CASE(&root_dir_test));
 }

 #endif // BUILD_UNIT_TESTS
============================================================
--- cset.hh	f2d58803ea89b51b5029a349c30acc3c6c3cf580
+++ cset.hh	7bd817258ac15fa2b6e4c3473e9b97858721969d
@@ -46,6 +46,8 @@ struct editable_tree
                         attr_key const & name,
                         attr_value const & val) = 0;

+  virtual void commit() = 0;
+
   virtual ~editable_tree() {}
 };

============================================================
--- database.cc	4c830b7b46f89cdc384cae08e54bfeac62335eb7
+++ database.cc	fd5eff861239cd1408cca007c0df653f8a0f7d3f
@@ -1224,6 +1224,10 @@ database::remove_version(hexenc<id> cons
       }
   }

+  // no deltas are allowed to point to the target.
+  execute(query("DELETE from " + delta_table + " WHERE base = ?")
+          % text(target_id()));
+
   if (delta_exists(target_id, delta_table))
     {
       if (!older.empty())
@@ -1243,6 +1247,8 @@ database::remove_version(hexenc<id> cons
           for (map<hexenc<id>, data>::const_iterator i = older.begin();
                i != older.end(); ++i)
             {
+              if (delta_exists(i->first, delta_table))
+                continue;
               delta bypass_delta;
               diff(newer_data, i->second, bypass_delta);
               put_delta(i->first, newer_id, bypass_delta, delta_table);
@@ -1257,7 +1263,10 @@ database::remove_version(hexenc<id> cons
       I(exists(target_id, data_table));
       for (map<hexenc<id>, data>::const_iterator i = older.begin();
            i != older.end(); ++i)
-        put(i->first, i->second, data_table);
+        {
+          if (!exists(i->first, data_table))
+            put(i->first, i->second, data_table);
+        }
       execute(query("DELETE from " + data_table + " WHERE id = ?")
               % text(target_id()));
     }
============================================================
--- file_io.cc	3214c2cad3ec630d8466926bd4bae693de9184a0
+++ file_io.cc	3ca8050b61b62ef9010b0ebfda755a0af9269104
@@ -347,15 +347,15 @@ read_localized_data(file_path const & pa
   dat = tmp2;
 }

-void read_directory(system_path const & path,
+void read_directory(any_path const & path,
                     std::vector<utf8> & files,
                     std::vector<utf8> & dirs)
 {
   files.clear();
   dirs.clear();
   fs::directory_iterator ei;
-  for(fs::directory_iterator di(path.as_external());
-      di != ei; ++di)
+  for (fs::directory_iterator di(system_path(path).as_external());
+       di != ei; ++di)
     {
       fs::path entry = *di;
       if (!fs::exists(entry)
@@ -363,6 +363,8 @@ void read_directory(system_path const &
           || di->string() == "..")
         continue;

+      // FIXME: BUG: this screws up charsets (assumes blindly that the fs is
+      // utf8)
       if (fs::is_directory(entry))
         dirs.push_back(utf8(entry.leaf()));
       else
@@ -484,8 +486,6 @@ write_data(system_path const & path,
 {
   write_data_impl(path, data, tmpdir / (boost::format("data.tmp.%d") %
                                              get_process_id()).str());
-
-
 }

 tree_walker::~tree_walker() {}
============================================================
--- file_io.hh	2082dc3c8480400f32fcbe1c4d881d7512de2204
+++ file_io.hh	362691f10f63d93e7cf83f299fe5aa0b4dcbee17
@@ -72,7 +72,7 @@ void read_localized_data(file_path const
                          data & dat,
                          lua_hooks & lua);

-void read_directory(system_path const & path,
+void read_directory(any_path const & path,
                     std::vector<utf8> & files,
                     std::vector<utf8> & dirs);

@@ -101,6 +101,7 @@ public:
 class tree_walker
 {
 public:
+  // returns true if the directory should be descended into
   virtual void visit_dir(file_path const & path);
   virtual void visit_file(file_path const & path) = 0;
   virtual ~tree_walker();
============================================================
--- lua.cc	8284c5010bee38f15141c3e60eeeeb7c288ee20c
+++ lua.cc	a9045fcf6d8283a12a96f422b79fb54ae2da727c
@@ -426,7 +426,7 @@ extern "C"
   {
     int fd = -1;
     FILE **pf = NULL;
-    char const *filename = lua_tostring (L, -1);
+    char const *filename = luaL_checkstring (L, -1);
     std::string dup(filename);

     fd = monotone_mkstemp(dup);
@@ -458,7 +458,7 @@ extern "C"
   static int
   monotone_existsonpath_for_lua(lua_State *L)
   {
-    const char *exe = lua_tostring(L, -1);
+    const char *exe = luaL_checkstring(L, -1);
     lua_pushnumber(L, existsonpath(exe));
     return 1;
   }
@@ -466,7 +466,7 @@ extern "C"
   static int
   monotone_is_executable_for_lua(lua_State *L)
   {
-    const char *path = lua_tostring(L, -1);
+    const char *path = luaL_checkstring(L, -1);
     lua_pushboolean(L, is_executable(path));
     return 1;
   }
@@ -474,7 +474,7 @@ extern "C"
   static int
   monotone_make_executable_for_lua(lua_State *L)
   {
-    const char *path = lua_tostring(L, -1);
+    const char *path = luaL_checkstring(L, -1);
     lua_pushnumber(L, make_executable(path));
     return 1;
   }
@@ -483,14 +483,14 @@ extern "C"
   monotone_spawn_for_lua(lua_State *L)
   {
     int n = lua_gettop(L);
-    const char *path = lua_tostring(L, -n);
+    const char *path = luaL_checkstring(L, -n);
     char **argv = (char**)malloc((n+1)*sizeof(char*));
     int i;
     pid_t ret;
     if (argv==NULL)
       return 0;
     argv[0] = (char*)path;
-    for (i=1; i<n; i++) argv[i] = (char*)lua_tostring(L, -(n - i));
+    for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, -(n - i));
     argv[i] = NULL;
     ret = process_spawn(argv);
     free(argv);
@@ -501,7 +501,7 @@ extern "C"
   static int
   monotone_wait_for_lua(lua_State *L)
   {
-    pid_t pid = (pid_t)lua_tonumber(L, -1);
+    pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -1));
     int res;
     int ret;
     ret = process_wait(pid, &res);
@@ -514,10 +514,10 @@ extern "C"
   monotone_kill_for_lua(lua_State *L)
   {
     int n = lua_gettop(L);
-    pid_t pid = (pid_t)lua_tonumber(L, -2);
+    pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -2));
     int sig;
     if (n>1)
-      sig = (int)lua_tonumber(L, -1);
+      sig = static_cast<int>(luaL_checknumber(L, -1));
     else
       sig = SIGTERM;
     lua_pushnumber(L, process_kill(pid, sig));
@@ -527,7 +527,7 @@ extern "C"
   static int
   monotone_sleep_for_lua(lua_State *L)
   {
-    int seconds = (int)lua_tonumber(L, -1);
+    int seconds = static_cast<int>(luaL_checknumber(L, -1));
     lua_pushnumber(L, process_sleep(seconds));
     return 1;
   }
@@ -535,7 +535,7 @@ extern "C"
   static int
   monotone_guess_binary_file_contents_for_lua(lua_State *L)
   {
-    const char *path = lua_tostring(L, -1);
+    const char *path = luaL_checkstring(L, -1);
     N(path, F("%s called with an invalid parameter") % "guess_binary");

     std::ifstream file(path, ios_base::binary);
@@ -564,7 +564,7 @@ extern "C"
   static int
   monotone_include_for_lua(lua_State *L)
   {
-    const char *path = lua_tostring(L, -1);
+    const char *path = luaL_checkstring(L, -1);
     N(path, F("%s called with an invalid parameter") % "Include");

     bool res =Lua(L)
@@ -579,7 +579,7 @@ extern "C"
   static int
   monotone_includedir_for_lua(lua_State *L)
   {
-    const char *pathstr = lua_tostring(L, -1);
+    const char *pathstr = luaL_checkstring(L, -1);
     N(pathstr, F("%s called with an invalid parameter") % "IncludeDir");

     fs::path locpath(pathstr, fs::native);
@@ -613,8 +613,8 @@ extern "C"
   static int
   monotone_regex_search_for_lua(lua_State *L)
   {
-    const char *re = lua_tostring(L, -2);
-    const char *str = lua_tostring(L, -1);
+    const char *re = luaL_checkstring(L, -2);
+    const char *str = luaL_checkstring(L, -1);
     boost::cmatch what;

     bool result = false;
@@ -632,8 +632,8 @@ extern "C"
   static int
   monotone_globish_match_for_lua(lua_State *L)
   {
-    const char *re = lua_tostring(L, -2);
-    const char *str = lua_tostring(L, -1);
+    const char *re = luaL_checkstring(L, -2);
+    const char *str = luaL_checkstring(L, -1);

     bool result = false;
     try {
@@ -661,7 +661,7 @@ extern "C"
   static int
   monotone_gettext_for_lua(lua_State *L)
   {
-    const char *msgid = lua_tostring(L, -1);
+    const char *msgid = luaL_checkstring(L, -1);
     lua_pushstring(L, gettext(msgid));
     return 1;
   }
@@ -685,7 +685,7 @@ extern "C"
   monotone_parse_basic_io_for_lua(lua_State *L)
   {
     vector<pair<string, vector<string> > > res;
-    const string str(lua_tostring(L, -1), lua_strlen(L, -1));
+    const string str(luaL_checkstring(L, -1), lua_strlen(L, -1));
     basic_io::input_source in(str, "monotone_parse_basic_io_for_lua");
     basic_io::tokenizer tok(in);
     try
@@ -1049,18 +1049,6 @@ lua_hooks::hook_ignore_branch(std::strin
   return exec_ok && ignore_it;
 }

-bool
-lua_hooks::hook_non_blocking_rng_ok()
-{
-  bool ok = false;
-  bool exec_ok = Lua(st)
-    .func("non_blocking_rng_ok")
-    .call(0,1)
-    .extract_bool(ok)
-    .ok();
-  return exec_ok && ok;
-}
-
 static inline bool
 shared_trust_function_body(Lua & ll,
                            std::set<rsa_keypair_id> const & signers,
============================================================
--- lua.hh	a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea
+++ lua.hh	5691c7c116dc402741a8a9ba7f5ab7d2ebe7b2e0
@@ -49,7 +49,6 @@ public:
                          std::string const & user_log_message,
                          std::string & result);
   bool hook_persist_phrase_ok();
-  bool hook_non_blocking_rng_ok();
   bool hook_get_revision_cert_trust(std::set<rsa_keypair_id> const & signers,
                                    hexenc<id> const & id,
                                    cert_name const & name,
============================================================
--- monotone.cc	92399bda2cd0fba92739636d7b0955c1c43bea23
+++ monotone.cc	29890d9e90e828fa96d845cb881bb024a8267d99
@@ -60,7 +60,7 @@ struct poptOption coptions[] =
     {"pid-file", 0, POPT_ARG_STRING, &argstr, OPT_PIDFILE, gettext_noop("record process id of server"), NULL},
     {"brief", 0, POPT_ARG_NONE, NULL, OPT_BRIEF, gettext_noop("print a brief version of the normal output"), NULL},
     {"diffs", 0, POPT_ARG_NONE, NULL, OPT_DIFFS, gettext_noop("print diffs along with logs"), NULL},
-    {"merges", 0, POPT_ARG_NONE, NULL, OPT_MERGES, gettext_noop("include merges when printing logs"), NULL},
+    {"no-merges", 0, POPT_ARG_NONE, NULL, OPT_NO_MERGES, gettext_noop("exclude merges when printing logs"), NULL},
     {"set-default", 0, POPT_ARG_NONE, NULL, OPT_SET_DEFAULT, gettext_noop("use the current arguments as the future default"), NULL},
     {"exclude", 0, POPT_ARG_STRING, &argstr, OPT_EXCLUDE, gettext_noop("leave out anything described by its argument"), NULL},
     {"unified", 0, POPT_ARG_NONE, NULL, OPT_UNIFIED_DIFF, gettext_noop("use unified diff format"), NULL},
@@ -74,6 +74,7 @@ struct poptOption coptions[] =
     {"unknown", 0, POPT_ARG_NONE, NULL, OPT_UNKNOWN, gettext_noop("perform the operations for unknown files from workspace"), NULL},
     {"key-to-push", 0, POPT_ARG_STRING, &argstr, OPT_KEY_TO_PUSH, gettext_noop("push the specified key even if it hasn't signed anything"), NULL},
     {"drop-attr", 0, POPT_ARG_STRING, &argstr, OPT_DROP_ATTR, gettext_noop("when rosterifying, drop attrs entries with the given key"), NULL},
+    {"no-files", 0, POPT_ARG_NONE, NULL, OPT_NO_FILES, gettext_noop("exclude files when printing logs"), NULL},
     { NULL, 0, 0, NULL, 0, NULL, NULL }
   };

@@ -84,6 +85,7 @@ struct poptOption options[] =

     {"debug", 0, POPT_ARG_NONE, NULL, OPT_DEBUG, gettext_noop("print debug log to stderr while running"), NULL},
     {"dump", 0, POPT_ARG_STRING, &argstr, OPT_DUMP, gettext_noop("file to dump debugging log to, on failure"), NULL},
+    {"log", 0, POPT_ARG_STRING, &argstr, OPT_LOG, gettext_noop("file to write the log to"), NULL},
     {"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, gettext_noop("suppress log and progress messages"), NULL},
     {"help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, gettext_noop("display help message"), NULL},
     {"version", 0, POPT_ARG_NONE, NULL, OPT_VERSION, gettext_noop("print version number, then exit"), NULL},
@@ -332,6 +334,10 @@ cpp_main(int argc, char ** argv)
               global_sanity.filename = system_path(argstr);
               break;

+            case OPT_LOG:
+              ui.redirect_log_to(system_path(argstr));
+              break;
+
             case OPT_DB_NAME:
               app.set_database(system_path(argstr));
               break;
@@ -420,8 +426,8 @@ cpp_main(int argc, char ** argv)
               app.diffs = true;
               break;

-            case OPT_MERGES:
-              app.merges = true;
+            case OPT_NO_MERGES:
+              app.no_merges = true;
               break;

             case OPT_SET_DEFAULT:
@@ -519,6 +525,10 @@ cpp_main(int argc, char ** argv)
               app.attrs_to_drop.insert(string(argstr));
               break;

+            case OPT_NO_FILES:
+              app.no_files = true;
+              break;
+
             case OPT_HELP:
             default:
               requested_help = true;
============================================================
--- monotone.texi	355d07f84caee318dd69f37ff6274842ca2d2c70
+++ monotone.texi	d62e740d5bf36c317e4ec3fea155132bd7ba702d
@@ -34,7 +34,7 @@
 @page
 @vskip 0pt plus 1filll
 Copyright @copyright{} 2003, 2004 Graydon Hoare
-Copyright @copyright{} 2004, 2005 Nathaniel Smith
+Copyright @copyright{} 2004, 2005, 2006 Nathaniel Smith
 Copyright @copyright{} 2005 Derek Scherger
 Copyright @copyright{} 2005 Daniel Carosone
 All rights reserved
@@ -3186,7 +3186,7 @@ @section File Attributes
 quoted value for that attribute.  Stanzas are separated by blank lines.

 As a convenience, you can use the @code{monotone attr} command to set
-and view the values of these attributes; see @ref{Working Copy}.
+and view the values of these attributes; see @ref{Workspace}.

 You can tell monotone to automatically take actions based on these
 attributes by defining hooks; see the @code{attr_functions} entry in
@@ -3421,7 +3421,7 @@ @heading Incorporating New Changes
 examine descendents of your base revision, and ignore other heads on
 your branch.

-@heading Moving Working Copy to Another Revision
+@heading Moving Workspace to Another Revision

 @multitable @columnfractions .4 .4
 @item
@@ -3487,7 +3487,7 @@ @heading Viewing Differences
 @emph{revision IDs}, rather than file IDs.  If one leaves off the file
 argument, then diff can print the difference between two entire trees.

-@heading Showing Working Copy Status
+@heading Showing Workspace Status

 @multitable @columnfractions .4 .4
 @item
@@ -3508,7 +3508,7 @@ @heading Showing Working Copy Status
 difference is that monotone's @command{status} command always gives a
 status of the whole tree, and outputs a more compact summary than CVS.

-@heading Adding Directories and Files to Working Copy
+@heading Adding Directories and Files to Workspace

 @multitable @columnfractions .4 .4
 @item
@@ -3532,7 +3532,7 @@ @heading Adding Directories and Files to
 Directories are created as needed, and empty directories are ignored.


-@heading Removing Directories and Files from Working Copy
+@heading Removing Directories and Files from Workspace

 @multitable @columnfractions .4 .4
 @item
@@ -3631,7 +3631,7 @@ @chapter Command Reference

 @menu
 * Tree::             Operations on tree states in your database
-* Working Copy::     Operations on your workspace
+* Workspace::        Operations on your workspace
 * Network::          Communication with the network
 * Informative::      Production of descriptive reports
 * Key and Cert::     General operations on keys or certificates
@@ -3790,8 +3790,8 @@ @section Tree


 @page
-@node    Working Copy
-@section Working Copy
+@node    Workspace
+@section Workspace

 @ftable @command
 @item monotone setup [@var{directory}]
@@ -3826,7 +3826,7 @@ @section Working Copy
 any added entries inserted in its manifest.


-@item monotone drop @var{pathname...}
+@item monotone [--execute] drop @var{pathname...}
 @itemx monotone drop --missing
 This command places ``drop'' entries for the paths specified in
 @var{pathname...} in the workspace's ``work list''. The work list of
@@ -3850,6 +3850,10 @@ @section Working Copy
 you should run @command{drop}, and then perform the actual delete using
 whatever mechanism you normally use to delete files.

+The option @option{--execute} will make ``drop'' perform the actual
+deletion operations in the filesystem.  It will ignore files or
+directories which have already been deleted.
+
 @item monotone [--execute] rename @var{src} @var{dst}
 @itemx monotone [--execute] rename @var{src1} @var{...} @var{dst/}
 This command places ``rename'' entries for the paths specified in
@@ -4012,6 +4016,35 @@ @section Working Copy
 in inodeprints mode, and that the inodeprints cache is accurate and up
 to date.

+@item monotone pivot_root [--execute] pivot_root @var{new_root} @var{put_old}
+Most users will never need this command.  It is primarily useful in
+certain tricky cases where one wishes to combine several projects
+into one, or split one project into several.
+
+Its effect is to rename the directory whose name is currently
+@var{new_root} to become the root directory of the versioned tree, and
+to at the same time rename the directory that is currently the root of
+the versioned tree to have the name @var{put_old}.  Conceptually, it
+is equivalent to executing the following commands in the root of the
+workspace:
+
+@smallexample
+@group
+$ monotone rename . @var{new_root}/@var{put_old}
+$ monotone rename @var{new_root} .
+@end group
+@end smallexample
+
+Except, of course, that these @command{rename} commands are illegal,
+because after the first command the tree has no root at all, and there
+is a directory loop.  This illegality is the only reason for
+@command{pivot_root}'s existence; internally, the result is treated
+exactly like two renames, including with respect to merges and
+updates.
+
+The use of @option{--execute} with this command is strongly
+recommended, though not required.
+
 @end ftable

 @page
@@ -4139,26 +4172,37 @@ @section Informative
 to files changed within the current subdirectory of the workspace.

 @item monotone log
-@itemx monotone log [--last=@var{n}] [--revision=@var{id} [...]] [--brief] [--merges] [@var{file} [...]]
+@itemx monotone log [--last=@var{n}] [--next=@var{n}] [--revision=@var{id} [...]] [--brief] [--no-merges] [--no-files] [--diffs] [@var{file} [...]]

 This command prints out a log, in reverse-ancestry order, of small
 history summaries.  Each summary contains author, date, changelog and
-comment information associated with a revision.
+comment information associated with a revision.

 If @code{--brief} is given, the output consists of one line per revision
 with the revision ID, the author, the date and the branches (separated
 with commas).

-If @code{--last=}@var{n} is given, at most that many log entries will be
+If @code{--last=}@var{n} is given, at most @var{n} log entries will be
 given.

-By default, the log entries for merge nodes are not shown; usually they
-don't contain much interesting information. If @code{--merges} is given,
-the log entries for these nodes will be included.
+If @code{--next=}@var{n} is given, at most @var{n} log entries towards
+the current head revision will be given from the workspace's base
+revision in forward-ancestry order.  This is useful to review changes
+that will be applied to the workspace when @command{update} is run.

+By default, the log entries for merge nodes are shown.  If
+@code{--no-merges} is given, the log entries for these nodes will be
+excluded.
+
+If @code{--no-files} is given, the log output excludes the list of
+files changed in each revision.
+
+Specifying @code{--diffs} causes the log output to include a unified
+diff of the changes in each revision.
+
 If one or more revision IDs are given, the command starts tracing back
-through history from these revisions, otherwise it starts from the base
-revision of your workspace.
+through history from these revisions, otherwise it starts from the
+base revision of your workspace.

 If one or more files are given, the command will only log the revisions
 where those files are changed.
@@ -4435,12 +4479,7 @@ @section Key and Cert

 This command generates an @sc{rsa} public/private key pair, using a
 system random number generator, and stores it in your keystore under
-the key name @var{keyid}. If the the hook
-@code{non_blocking_rng_ok()} returns @code{true}, the key
-generation will use an unlimited random number generator (such as
-@file{/dev/urandom}), otherwise it will use a higher quality random
-number generator (such as @file{/dev/random}) but might run slightly
-slower.
+the key name @var{keyid}.

 The private half of the key is stored in an encrypted form, so that anyone
 who can read your keystore cannot extract your private key and use it.
@@ -6157,25 +6196,6 @@ @subsection User Defaults

 For the default definition of this hook, see @ref{Default hooks}.

-@item non_blocking_rng_ok ()
-
-Returns @code{true} if you are willing to let monotone use the
-system's non-blocking random number generator, such as
-@file{/dev/urandom}, for generating random values during cryptographic
-operations. This diminishes the cryptographic strength of such
-operations, but speeds them up. Returns @code{false} if you want to
-force monotone to always use higher quality random numbers, such as
-those from @file{/dev/random}.
-
-The default definition of this hook is:
-@smallexample
-@group
-function non_blocking_rng_ok()
-        return true
-end
-@end group
-@end smallexample
-
 @item persist_phrase_ok ()

 Returns @code{true} if you want monotone to remember the passphrase of
@@ -7770,6 +7790,10 @@ @section OPTIONS
 Dump debugging log to @i{<file>} on failure.
 @comment TROFF INPUT: .TP

+@item @b{--log=}@i{<file>}
+Redirect the log lines to to @i{<file>}.
+@comment TROFF INPUT: .TP
+
 @item @b{--nostd}
 Do not evaluate "standard" Lua hooks compiled into @b{monotone}.
 @comment TROFF INPUT: .TP
============================================================
--- netcmd.cc	5a63ccd88ddb02cf5853e13ce3fff6ea20851a53
+++ netcmd.cc	da3773c93069c0834ce0b3caf34020305dd7d8b2
@@ -88,15 +88,6 @@ netcmd::read(string_queue & inbuf, chain
     return false;

   u8 extracted_ver = extract_datum_lsb<u8>(inbuf, pos, "netcmd protocol number");
-  if (extracted_ver != version)
-    throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'\n"
-                       "%s")
-                     % widen<u32,u8>(version)
-                     % widen<u32,u8>(extracted_ver)
-                     % ((version < extracted_ver)
-                        ? _("the remote side has a newer, incompatible version of monotone")
-                        : _("the remote side has an older, incompatible version of monotone")));
-  version = extracted_ver;

   u8 cmd_byte = extract_datum_lsb<u8>(inbuf, pos, "netcmd code");
   switch (cmd_byte)
@@ -115,8 +106,21 @@ netcmd::read(string_queue & inbuf, chain
       cmd_code = static_cast<netcmd_code>(cmd_byte);
       break;
     default:
-      throw bad_decode(F("unknown netcmd code 0x%x") % widen<u32,u8>(cmd_byte));
+      // if the versions don't match, we will throw the more descriptive
+      // error immediately after this switch.
+      if (extracted_ver == version)
+        throw bad_decode(F("unknown netcmd code 0x%x")
+                          % widen<u32,u8>(cmd_byte));
     }
+  // Ignore the version on usher_cmd packets.
+  if (extracted_ver != version && cmd_code != usher_cmd)
+    throw bad_decode(F("protocol version mismatch: wanted '%d' got '%d'\n"
+                       "%s")
+                     % widen<u32,u8>(version)
+                     % widen<u32,u8>(extracted_ver)
+                     % ((version < extracted_ver)
+                        ? _("the remote side has a newer, incompatible version of monotone")
+                        : _("the remote side has an older, incompatible version of monotone")));

   // check to see if we have even enough bytes for a complete uleb128
   size_t payload_len = 0;
============================================================
--- netcmd.hh	22664387cea0916b87288113ec5b559c2c49eda5
+++ netcmd.hh	e290b45f5acb01bfe181832d4750275e05b2f98f
@@ -69,9 +69,7 @@ public:
   std::string payload;
 public:
   netcmd();
-  netcmd(u8 _version);
   netcmd_code get_cmd_code() const {return cmd_code;}
-  u8 get_version() const {return version;}
   size_t encoded_size();
   bool operator==(netcmd const & other) const;

============================================================
--- netsync.cc	8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa
+++ netsync.cc	0edebb049f6f44132b6c97be4663efc113efeee8
@@ -2390,7 +2390,7 @@ handle_new_connection(Netxx::Address & a
                       app_state & app)
 {
   L(FL("accepting new connection on %s : %s\n")
-    % addr.get_name() % lexical_cast<string>(addr.get_port()));
+    % (addr.get_name()?addr.get_name():"") % lexical_cast<string>(addr.get_port()));
   Netxx::Peer client = server.accept_connection();

   if (!client)
@@ -2589,7 +2589,7 @@ serve_connections(protocol_role role,
           else
             addr.add_all_addresses (default_port);

-          // If se use IPv6 and the initiasation of server fails, we want
+          // If se use IPv6 and the initialisation of server fails, we want
           // to try again with IPv4.  The reason is that someone may have
           // downloaded a IPv6-enabled monotone on a system that doesn't
           // have IPv6, and which might fail therefore.
============================================================
--- options.hh	6dc48543e2cb20ea82ded241dc5bb6088c3cb09c
+++ options.hh	216cb82f6f82b63b0f1535b39bb985a237b43359
@@ -32,7 +32,7 @@
 #define OPT_MSGFILE 23
 #define OPT_BRIEF 24
 #define OPT_DIFFS 25
-#define OPT_MERGES 26
+#define OPT_NO_MERGES 26
 #define OPT_LAST 27
 #define OPT_NEXT 28
 #define OPT_VERBOSE 29
@@ -51,3 +51,5 @@
 #define OPT_KEY_TO_PUSH 42
 #define OPT_CONF_DIR 43
 #define OPT_DROP_ATTR 44
+#define OPT_NO_FILES 45
+#define OPT_LOG 46
============================================================
--- paths.cc	c13e9b0c44a37a70e6c7e6d5c8b8869e363ccab9
+++ paths.cc	05c27908836d28a468070bb8e7a808417b8401f1
@@ -76,6 +76,7 @@ bookkeeping_path const bookkeeping_root(
 static access_tracker<system_path> working_root;

 bookkeeping_path const bookkeeping_root("MT");
+path_component const bookkeeping_root_component("MT");

 void
 save_initial_path()
@@ -438,13 +439,19 @@ system_path::system_path(any_path const

 system_path::system_path(any_path const & other, bool in_true_workspace)
 {
-  I(!is_absolute_here(other.as_internal()));
-  system_path wr;
-  if (in_true_workspace)
-    wr = working_root.get();
+  if (is_absolute_here(other.as_internal()))
+    // another system_path.  the normalizing isn't really necessary, but it
+    // makes me feel warm and fuzzy.
+    data = normalize_out_dots(other.as_internal());
   else
-    wr = working_root.get_but_unused();
-  data = normalize_out_dots((wr / other.as_internal()).as_internal());
+    {
+      system_path wr;
+      if (in_true_workspace)
+        wr = working_root.get();
+      else
+        wr = working_root.get_but_unused();
+      data = normalize_out_dots((wr / other.as_internal()).as_internal());
+    }
 }

 static inline std::string const_system_path(utf8 const & path)
@@ -468,6 +475,26 @@ system_path::system_path(utf8 const & pa
 }

 ///////////////////////////////////////////////////////////////////////////
+// utility
+///////////////////////////////////////////////////////////////////////////
+
+void
+dirname_basename(split_path const & sp,
+                 split_path & dirname, path_component & basename)
+{
+  I(!sp.empty());
+  // L(FL("dirname_basename('%s' [%d components],...)\n") % file_path(sp) % sp.size());
+  dirname = sp;
+  dirname.pop_back();
+  basename = sp.back();
+  if (dirname.empty())
+    {
+      // L(FL("basename %d vs. null component %d\n") % basename % the_null_component);
+      I(null_name(basename));
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
 // workspace (and path root) handling
 ///////////////////////////////////////////////////////////////////////////

@@ -825,6 +852,7 @@ static void test_split_join()
   split_path split_mt1, split_mt2;
   file_path_internal("foo/MT").split(split_mt1);
   BOOST_CHECK(split_mt1.size() == 3);
+  I(split_mt1[2] == bookkeeping_root_component);
   split_mt2.push_back(the_null_component);
   split_mt2.push_back(split_mt1[2]);
   // split_mt2 now contains the component "MT"
============================================================
--- paths.hh	054a74b153b42a34140f2776f468bf79c844fa64
+++ paths.hh	e81d1f0e7efdbff539b8b92f04ad357770130fd4
@@ -207,6 +207,7 @@ extern bookkeeping_path const bookkeepin
 };

 extern bookkeeping_path const bookkeeping_root;
+extern path_component const bookkeeping_root_component;

 // this will always be an absolute path
 class system_path : public any_path
@@ -234,6 +235,9 @@ public:
   system_path operator /(std::string const & to_append) const;
 };

+void
+dirname_basename(split_path const & sp,
+                 split_path & dirname, path_component & basename);

 void
 save_initial_path();
============================================================
--- po/sv.po	754e90276863a8b1a53cad17c575bb93ffcdd5b4
+++ po/sv.po	e065ecfd2c28c0ea89877c3c95ceeae23190b320
@@ -144,8 +144,8 @@ msgstr ""
 msgstr ""
 "Project-Id-Version: monotone 0.26pre1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-11 08:32+0100\n"
-"PO-Revision-Date: 2006-02-11 08:43+0100\n"
+"POT-Creation-Date: 2006-02-20 17:26+0100\n"
+"PO-Revision-Date: 2006-02-20 17:28+0100\n"
 "Last-Translator: Joel Rosdahl <joel@rosdahl.net>\n"
 "Language-Team: Richard Levitte <richard@levitte.org>\n"
 "MIME-Version: 1.0\n"
@@ -303,7 +303,7 @@ msgstr "pid-filen '%s' finns redan"
 msgstr "pid-filen '%s' finns redan"

 #: commands.cc:325 commands.cc:1295 commands.cc:1365 commands.cc:1801
-#: commands.cc:2722 commands.cc:3266 commands.cc:3497 commands.cc:3536
+#: commands.cc:2722 commands.cc:3267 commands.cc:3498 commands.cc:3537
 msgid "informative"
 msgstr "informativ"

@@ -343,7 +343,7 @@ msgstr ""

 #: commands.cc:481 commands.cc:737 commands.cc:1383 commands.cc:1460
 #: commands.cc:1888 commands.cc:2772 commands.cc:2800 commands.cc:2803
-#: commands.cc:2939 commands.cc:3519
+#: commands.cc:2939 commands.cc:3520
 #, c-format
 msgid "no such revision '%s'"
 msgstr "det finns ingen revision med identiteten '%s'"
@@ -618,13 +618,13 @@ msgstr "tom kommentar"
 msgid "empty comment"
 msgstr "tom kommentar"

-#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:1342
-#: commands.cc:2224 commands.cc:2342 commands.cc:2875 commands.cc:3314
+#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:2224
+#: commands.cc:2342 commands.cc:2875 commands.cc:3315
 msgid "workspace"
 msgstr "arbetskopia"

 #: commands.cc:1168 commands.cc:1196 commands.cc:1295 commands.cc:2342
-#: commands.cc:2722 commands.cc:3314
+#: commands.cc:2722 commands.cc:3315
 msgid "[PATH]..."
 msgstr "[SÖKVÄG]..."

@@ -651,7 +651,8 @@ msgstr "byt namn på filer i arbetskopia
 msgid "rename entries in the workspace"
 msgstr "byt namn på filer i arbetskopian"

-#: commands.cc:1249 commands.cc:1262 commands.cc:3417 commands.cc:3857
+#: commands.cc:1249 commands.cc:1262 commands.cc:1342 commands.cc:3418
+#: commands.cc:3859
 msgid "debug"
 msgstr "felsökning"

@@ -708,13 +709,13 @@ msgstr "skriv ut angiven fil från datab
 msgid "write file from database to stdout"
 msgstr "skriv ut angiven fil från databasen"

-#: commands.cc:1395 commands.cc:1397 commands.cc:3528
+#: commands.cc:1395 commands.cc:1397 commands.cc:3529
 #, c-format
 msgid "no file '%s' found in revision '%s'\n"
 msgstr "filen '%s' finns inte i revisionen '%s'\n"

 #: commands.cc:1409 commands.cc:1531 commands.cc:3076 commands.cc:3125
-#: commands.cc:3214 commands.cc:3221 commands.cc:3770
+#: commands.cc:3214 commands.cc:3222 commands.cc:3772
 msgid "tree"
 msgstr "träd"

@@ -1224,13 +1225,13 @@ msgstr "slår ihop med revision %d av %d
 msgid "merging with revision %d / %d\n"
 msgstr "slår ihop med revision %d av %d\n"

-#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3244
-#: commands.cc:3245
+#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3245
+#: commands.cc:3246
 #, c-format
 msgid "[source] %s\n"
 msgstr "[källa]      %s\n"

-#: commands.cc:3119 commands.cc:3210 commands.cc:3263
+#: commands.cc:3119 commands.cc:3210 commands.cc:3264
 #, c-format
 msgid "[merged] %s\n"
 msgstr "[ihopslagen] %s\n"
@@ -1282,58 +1283,58 @@ msgstr "uppdatera inodeprint-cachen"
 msgid "refresh the inodeprint cache"
 msgstr "uppdatera inodeprint-cachen"

-#: commands.cc:3222
+#: commands.cc:3223
 msgid "LEFT-REVISION RIGHT-REVISION DEST-BRANCH"
 msgstr "VÄNSTERREVISION HÖGERREVISION MÅLGREN"

-#: commands.cc:3223
+#: commands.cc:3224
 msgid "merge two explicitly given revisions, placing result in given branch"
 msgstr ""
 "slå ihop två explicit angivna revisioner, placera resultatet i angiven gren"

-#: commands.cc:3237
+#: commands.cc:3238
 #, c-format
 msgid "%s and %s are the same revision, aborting"
 msgstr "%s och %s är samma revision, avbryter"

-#: commands.cc:3239 commands.cc:3241
+#: commands.cc:3240 commands.cc:3242
 #, c-format
 msgid "%s is already an ancestor of %s"
 msgstr "%s är redan förfader till %s"

-#: commands.cc:3266
+#: commands.cc:3267
 msgid "(revision|file|key) PARTIAL-ID"
 msgstr "(revision|file|key) PARTIAL-ID"

-#: commands.cc:3267
+#: commands.cc:3268
 msgid "complete partial id"
 msgstr "utöka den partiella identiteten"

-#: commands.cc:3276
+#: commands.cc:3277
 #, c-format
 msgid "non-hex digits in partial id"
 msgstr "något tecken i den partiella identiteten är inte hexadecimalt"

-#: commands.cc:3315
+#: commands.cc:3316
 #, fuzzy
 msgid "revert file(s), dir(s) or entire workspace (\".\")"
 msgstr "återställ fil(er), katalog(er) eller hela arbetskopian (\".\")"

-#: commands.cc:3392
+#: commands.cc:3393
 #, c-format
 msgid "reverting %s"
 msgstr "återställer %s"

-#: commands.cc:3396
+#: commands.cc:3397
 #, c-format
 msgid "no file version %s found in database for %s"
 msgstr "filversionen %s finns inte i databasen för %s"

-#: commands.cc:3417
+#: commands.cc:3418
 msgid "RCSFILE..."
 msgstr "RCSFIL..."

-#: commands.cc:3418
+#: commands.cc:3419
 msgid ""
 "parse versions in RCS files\n"
 "this command doesn't reconstruct or import revisions.you probably want "
@@ -1343,36 +1344,36 @@ msgstr ""
 "detta kommando importerar inte revisioner; du vill antagligen använda\n"
 "cvs_import"

-#: commands.cc:3434
+#: commands.cc:3435
 msgid "rcs"
 msgstr "rcs"

-#: commands.cc:3434
+#: commands.cc:3435
 msgid "CVSROOT"
 msgstr "CVSROOT"

-#: commands.cc:3434
+#: commands.cc:3435
 msgid "import all versions in CVS repository"
 msgstr "importera alla revisioner i ett CVS-arkiv"

-#: commands.cc:3497
+#: commands.cc:3498
 msgid "PATH"
 msgstr "SÖKVÄG"

-#: commands.cc:3498
+#: commands.cc:3499
 msgid "print annotated copy of the file from REVISION"
 msgstr "skriv ut filen ur REVISION med extra detaljer"

-#: commands.cc:3518
+#: commands.cc:3519
 #, c-format
 msgid "no revision for file '%s' in database"
 msgstr "filen '%s' har ingen revision i databasen"

-#: commands.cc:3536
+#: commands.cc:3537
 msgid "[FILE] ..."
 msgstr "[FIL] ..."

-#: commands.cc:3537
+#: commands.cc:3538
 msgid ""
 "print history in reverse order (filtering by 'FILE'). If one or more\n"
 "revisions are given, use them as a starting point."
@@ -1381,35 +1382,35 @@ msgstr ""
 "arbetskatalogen om inga filer angivits. Om en eller flera revisioner\n"
 "har angivits används de som utgångspunkter."

-#: commands.cc:3584
+#: commands.cc:3586
 #, c-format
 msgid "Unknown file '%s' for log command"
 msgstr "Okänd fil '%s'"

-#: commands.cc:3602
+#: commands.cc:3604
 #, c-format
 msgid "only one of --last/--next allowed"
 msgstr "enbart en av --last eller --next tillåten"

-#: commands.cc:3770
+#: commands.cc:3772
 msgid "[DIRECTORY]"
 msgstr "[KATALOG]"

-#: commands.cc:3770
+#: commands.cc:3772
 #, fuzzy
 msgid "setup a new workspace directory, default to current"
 msgstr "initiera en ny arbetskatalog (nuvarande om katalog ej anges)"

-#: commands.cc:3776
+#: commands.cc:3778
 #, c-format
 msgid "need --branch argument for setup"
 msgstr "du måste ange en gren med --branch till kommandot \"setup\""

-#: commands.cc:3790
+#: commands.cc:3792
 msgid "automation"
 msgstr "automatisering"

-#: commands.cc:3791
+#: commands.cc:3793
 msgid ""
 "interface_version\n"
 "heads [BRANCH]\n"
@@ -1453,40 +1454,40 @@ msgstr ""
 "get_revision [REVID]\n"
 "keys\n"

-#: commands.cc:3811
+#: commands.cc:3813
 msgid "automation interface"
 msgstr "automatiseringsgränssnitt"

-#: commands.cc:3825 commands.cc:3841
+#: commands.cc:3827 commands.cc:3843
 msgid "vars"
 msgstr "variabler"

-#: commands.cc:3825
+#: commands.cc:3827
 msgid "DOMAIN NAME VALUE"
 msgstr "DOMÄN NAMN VÄRDE"

-#: commands.cc:3826
+#: commands.cc:3828
 msgid "set the database variable NAME to VALUE, in domain DOMAIN"
 msgstr "sätt databasvariabeln NAMN till VÄRDE i domänen DOMÄN"

-#: commands.cc:3841
+#: commands.cc:3843
 msgid "DOMAIN NAME"
 msgstr "DOMÄN NAMN"

-#: commands.cc:3842
+#: commands.cc:3844
 msgid "remove the database variable NAME in domain DOMAIN"
 msgstr "ta bort databasvariabeln NAMN från domänen DOMÄN"

-#: commands.cc:3853
+#: commands.cc:3855
 #, c-format
 msgid "no var with name %s in domain %s"
 msgstr "det finns inga variabler med namnet %s i domänen %s"

-#: commands.cc:3857
+#: commands.cc:3859
 msgid "REVID"
 msgstr "REVID"

-#: commands.cc:3858
+#: commands.cc:3860
 msgid "dump the roster associated with the given REVID"
 msgstr "skriv ut den roster som hör ihop med angivet REVID"

@@ -1502,7 +1503,7 @@ msgstr "markeringar"
 msgid "markings"
 msgstr "markeringar"

-#: database_check.cc:319 database_check.cc:507 netsync.cc:2719
+#: database_check.cc:319 database_check.cc:507 netsync.cc:2755
 #: rcs_import.cc:1226
 msgid "revisions"
 msgstr "revisioner"
@@ -1511,7 +1512,7 @@ msgstr "föräldraskap"
 msgid "ancestry"
 msgstr "föräldraskap"

-#: database_check.cc:451 netsync.cc:2723
+#: database_check.cc:451 netsync.cc:2759
 msgid "keys"
 msgstr "nycklar"

@@ -1780,7 +1781,7 @@ msgstr "databasen är i gott skick\n"
 msgid "database is good\n"
 msgstr "databasen är i gott skick\n"

-#: database.cc:134
+#: database.cc:144
 #, c-format
 msgid ""
 "layout of database %s doesn't match this version of monotone\n"
@@ -1794,7 +1795,7 @@ msgstr ""
 "(detta går inte att ångra; du vill nog ta en säkerhetskopia av databasen\n"
 "först)"

-#: database.cc:158
+#: database.cc:168
 #, c-format
 msgid ""
 "database %s contains revisions but no rosters\n"
@@ -1813,7 +1814,7 @@ msgstr ""
 "  sedan databasen på nytt.\n"
 "ursäkta besväret."

-#: database.cc:177
+#: database.cc:187
 #, c-format
 msgid ""
 "database %s contains manifests but no revisions\n"
@@ -1824,19 +1825,19 @@ msgstr ""
 "detta är en väldigt gammal databas; den behöver uppgraderas\n"
 "var god läs README.changesets för detaljer"

-#: database.cc:238
+#: database.cc:248
 #, c-format
 msgid "unable to probe database version in file %s"
 msgstr "kunde inte hitta någon databasversion i filen %s"

-#: database.cc:245
+#: database.cc:255
 #, c-format
 msgid "database %s is not an sqlite version 3 file, try dump and reload"
 msgstr ""
 "databasen %s är inte skapad med SQLite version 3; testa att dumpa och ladda "
 "på nytt"

-#: database.cc:272
+#: database.cc:282
 msgid ""
 "make sure database and containing directory are writeable\n"
 "and you have not run out of disk space"
@@ -1845,7 +1846,7 @@ msgstr ""
 "i\n"
 "samt att det finns tillräckligt med ledigt utrymme på disken"

-#: database.cc:278
+#: database.cc:288
 #, c-format
 msgid ""
 "sqlite error: %d: %s\n"
@@ -1854,12 +1855,12 @@ msgstr ""
 "sqlite-fel: %d: %s\n"
 "%s"

-#: database.cc:324
+#: database.cc:334
 #, c-format
 msgid "could not initialize database: %s: already exists"
 msgstr "kunde inte initiera databasen: %s: den finns redan"

-#: database.cc:329
+#: database.cc:339
 #, c-format
 msgid ""
 "existing (possibly stale) journal file '%s' has same stem as new database '%"
@@ -1870,12 +1871,12 @@ msgstr ""
 "databasen '%s'\n"
 "avbryter skapandet av databasen"

-#: database.cc:451
+#: database.cc:461
 #, c-format
 msgid "cannot create %s; it already exists"
 msgstr "kan inte skapa %s; den finns redan"

-#: database.cc:511
+#: database.cc:521
 #, c-format
 msgid ""
 "schema version    : %s\n"
@@ -1916,52 +1917,52 @@ msgstr ""
 "  cert                : %u\n"
 "  total               : %u\n"

-#: database.cc:565
+#: database.cc:575
 #, c-format
 msgid "database schema version: %s"
 msgstr "databasens schemaversion: %s"

-#: database.cc:642
+#: database.cc:652
 #, c-format
 msgid "multiple statements in query: %s\n"
 msgstr "multipla kommandon i databasfråga: %s\n"

-#: database.cc:648
+#: database.cc:658
 #, c-format
 msgid "wanted %d columns got %d in query: %s\n"
 msgstr "ville ha %d kolumner, fick %d i databasfråga: %s\n"

-#: database.cc:706
+#: database.cc:716
 #, c-format
 msgid "null result in query: %s\n"
 msgstr "inget resultat med databasfråga: %s\n"

-#: database.cc:724
+#: database.cc:734
 #, c-format
 msgid "wanted %d rows got %s in query: %s\n"
 msgstr "ville ha %d rader, fick %s i databasfråga: %s\n"

-#: database.cc:1771
+#: database.cc:1781
 #, c-format
 msgid "another key with name '%s' already exists"
 msgstr "det finns redan en annan nyckel med namnet '%s'"

-#: database.cc:2815
+#: database.cc:2825
 #, c-format
 msgid "no database specified"
 msgstr "ingen databas angiven"

-#: database.cc:2823
+#: database.cc:2833
 #, c-format
 msgid "database %s does not exist"
 msgstr "databasen %s finns inte"

-#: database.cc:2824
+#: database.cc:2834
 #, c-format
 msgid "%s is a directory, not a database"
 msgstr "%s är en katalog, inte en databas"

-#: database.cc:2849
+#: database.cc:2859
 #, c-format
 msgid "could not open database '%s': %s"
 msgstr "kunde inte öppna databasen '%s': %s"
@@ -2344,100 +2345,109 @@ msgstr "släng attribut med den givna ny
 msgid "when rosterifying, drop attrs entries with the given key"
 msgstr "släng attribut med den givna nyckeln vid konvertering till 'rosters'"

-#: monotone.cc:85
+#: monotone.cc:77
+#, fuzzy
+msgid "exclude files when printing logs"
+msgstr "ta med ihopslagningar i loggen"
+
+#: monotone.cc:86
 msgid "print debug log to stderr while running"
 msgstr "skriv ut felsökningslogg till stderr under körning"

-#: monotone.cc:86
+#: monotone.cc:87
 msgid "file to dump debugging log to, on failure"
 msgstr "fil att skriva ut felsökningsloggen till om något gick fel"

-#: monotone.cc:87
+#: monotone.cc:88
+msgid "file to write the log to"
+msgstr "fil att skriva ut loggen till"
+
+#: monotone.cc:89
 msgid "suppress log and progress messages"
 msgstr "skriv inte ut loggar eller förloppsmeddelanden"

-#: monotone.cc:88
+#: monotone.cc:90
 msgid "display help message"
 msgstr "skriv ut extra hjälptext"

-#: monotone.cc:89
+#: monotone.cc:91
 msgid "print version number, then exit"
 msgstr "skriv ut versionsnumret och avsluta sedan omedelbart"

-#: monotone.cc:90
+#: monotone.cc:92
 msgid "print detailed version number, then exit"
 msgstr "skriv ut detaljerad versionsinformation och avsluta sedan omedelbart"

-#: monotone.cc:91
+#: monotone.cc:93
 msgid "insert command line arguments taken from the given file"
 msgstr "använd kommandoradsargument ur denna fil"

-#: monotone.cc:92
+#: monotone.cc:94
 msgid "set ticker style (count|dot|none)"
 msgstr "sätt stilen för förloppsinformationen (count|dot|none)"

-#: monotone.cc:93
+#: monotone.cc:95
 msgid "do not load standard lua hooks"
 msgstr "använd inte standard-lua-rutinerna"

-#: monotone.cc:94
+#: monotone.cc:96
 msgid "do not load ~/.monotone/monotonerc or MT/monotonerc lua files"
 msgstr "använd inte ~/.monotone/monotonerc eller MT/monotonerc"

-#: monotone.cc:95
+#: monotone.cc:97
 msgid "load extra rc file"
 msgstr "använd denna lua-fil"

-#: monotone.cc:96
+#: monotone.cc:98
 msgid "set key for signatures"
 msgstr "ange nyckel att signera med"

-#: monotone.cc:97
+#: monotone.cc:99
 msgid "set name of database"
 msgstr "ange databasens filnamn"

-#: monotone.cc:98
+#: monotone.cc:100
 #, fuzzy
 msgid "limit search for workspace to specified root"
 msgstr "begränsa sökningen efter arbetskatalogen till denna katalog"

-#: monotone.cc:99
+#: monotone.cc:101
 msgid "verbose completion output"
 msgstr "ge utförlig information"

-#: monotone.cc:100
+#: monotone.cc:102
 msgid "set location of key store"
 msgstr "ange i vilken katalog nycklarna finns"

-#: monotone.cc:101
+#: monotone.cc:103
 msgid "set location of configuration directory"
 msgstr "ange i vilken katalog konfigurationsfilerna finns"

-#: monotone.cc:205
+#: monotone.cc:207
 #, c-format
 msgid "problem parsing arguments from file %s: %s"
 msgstr "problem att tyda argumenten i filen %s: %s"

-#: monotone.cc:214
+#: monotone.cc:216
 #, c-format
 msgid "weird error when stuffing arguments read from %s: %s\n"
 msgstr "underligt fel när argument lästa från %s stoppades in: %s\n"

-#: monotone.cc:294
+#: monotone.cc:296
 msgid "[OPTION...] command [ARGS...]\n"
 msgstr "[FLAGGOR...] kommando [ARGUMENT...]\n"

-#: monotone.cc:532
+#: monotone.cc:542
 #, c-format
 msgid "syntax error near the \"%s\" option: %s"
 msgstr "syntaxfel nära flaggan \"%s\": %s"

-#: monotone.cc:571
+#: monotone.cc:581
 #, c-format
 msgid "monotone %s doesn't use the option %s"
 msgstr "monotone %s använder inte flaggan %s"

-#: monotone.cc:606
+#: monotone.cc:616
 #, c-format
 msgid "Options specific to 'monotone %s':"
 msgstr "Specifika flaggor för 'monotone %s':"
@@ -2885,53 +2895,53 @@ msgstr "fd %d (%s) har varit inaktiv fö
 msgid "fd %d (peer %s) has been idle too long, disconnecting\n"
 msgstr "fd %d (%s) har varit inaktiv för länge, kopplar ifrån\n"

-#: netsync.cc:2588
+#: netsync.cc:2610
 #, c-format
 msgid "beginning service on %s : %s\n"
 msgstr "startar tjänst på %s : %s\n"

-#: netsync.cc:2603
+#: netsync.cc:2625
 #, c-format
 msgid "session limit %d reached, some connections will be refused\n"
 msgstr ""
 "gränsen för antalet sessioner, %d, är nådd, en del uppkopplingar kommer att "
 "nekas\n"

-#: netsync.cc:2658
+#: netsync.cc:2680
 #, c-format
 msgid "got OOB from peer %s, disconnecting\n"
 msgstr "fick OOB-data från %s, kopplar ifrån\n"

-#: netsync.cc:2713
+#: netsync.cc:2749
 #, c-format
 msgid "finding items to synchronize:\n"
 msgstr "letar efter saker att synkronisera:\n"

-#: netsync.cc:2721
+#: netsync.cc:2757
 msgid "certificates"
 msgstr "certifikat"

-#: netsync.cc:2830
+#: netsync.cc:2866
 #, c-format
 msgid "Cannot find key '%s'"
 msgstr "Kan inte hitta nyckeln '%s'"

-#: netsync.cc:2870
+#: netsync.cc:2906
 #, c-format
 msgid "include branch pattern contains a quote character:\n"
 msgstr "grenmönstret givet med --include innehåller ett citattecken\n"

-#: netsync.cc:2871 netsync.cc:2877
+#: netsync.cc:2907 netsync.cc:2913
 #, c-format
 msgid "%s\n"
 msgstr "%s\n"

-#: netsync.cc:2876
+#: netsync.cc:2912
 #, c-format
 msgid "exclude branch pattern contains a quote character:\n"
 msgstr "grenmönstret givet med --exclude innehåller ett citattecken\n"

-#: netsync.cc:2899 netsync.cc:2903
+#: netsync.cc:2935 netsync.cc:2939
 #, c-format
 msgid "network error: %s"
 msgstr "nätverksfel: %s"
@@ -3114,20 +3124,6 @@ msgstr "bygger om revisionsgrafen från
 msgid "rebuilding revision graph from manifest certs\n"
 msgstr "bygger om revisionsgrafen från manifestcert\n"

-#: sanity.cc:54
-#, c-format
-msgid ""
-"wrote debugging log to %s\n"
-"if reporting a bug, please include this file"
-m