The unified diff between revisions [0010ca1a..] and [8846a6b8..] is displayed below. It can also be downloaded as a raw diff.
#
#
# delete "sqlite/config.h"
#
# delete "sqlite/os_unix.h"
#
# delete "sqlite/os_win.h"
#
# add_file "sqlite/os.c"
# content [59f05de8c5777c34876607114a2fbe55ae578235]
#
# add_file "tests/t_commit_validate.at"
# content [2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3]
#
# add_file "tests/t_ls_changed.at"
# content [1fc5edbd5d67ff60df161f44864efced6c08670a]
#
# patch "AUTHORS"
# from [be2883d201fdd61b63582334f52312a640e012a1]
# to [66d90072b355ef6e2b66f56c0dfa00de1565dc98]
#
# patch "ChangeLog"
# from [259eb3350818f249dada218ce2ffb43a71a4971e]
# to [cf7af27d617c006696a08efcd68a9bd9fd401a7a]
#
# patch "Makefile.am"
# from [1086b6f0ea35d96bdd46455c7d97c5934fb77e5a]
# to [d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1]
#
# patch "NEWS"
# from [4109c836eec71571ad7f8cca182bd780771e13a6]
# to [ef3bd56b18d1386927ffb58c2bb20ef4070712dd]
#
# patch "automate.cc"
# from [68d579fc833b4a0ec52a0c8e5b130af7517ab7ed]
# to [d86c347f85ee7ce7a59f699c8e51feaa1fa57bfb]
#
# patch "commands.cc"
# from [2f64f75b9afb4a86bac84bcc6cacaba86866be2b]
# to [dbf77e72442ab85b8b4390b8fb1316ca8145d507]
#
# patch "configure.ac"
# from [3db7a41acaf0a99ca96e19c12c2f96e5eaea45b1]
# to [0bbe01c42c3d25e72176fda5c606e1e4c3ec3e6d]
#
# patch "cset.cc"
# from [7596f4bf16c8591f073c6c18df29668474c499c8]
# to [ac5f2a4848a4c5661496ec4f5af706de1fb6a454]
#
# patch "cset.hh"
# from [077036ac38849e3b74dcdce595fdb5ee2762f282]
# to [f2d58803ea89b51b5029a349c30acc3c6c3cf580]
#
# patch "database.cc"
# from [bd5cc9b0df537b2aab8520160761bbe8605ec6d8]
# to [4c830b7b46f89cdc384cae08e54bfeac62335eb7]
#
# patch "database.hh"
# from [dd9695e867200e94e2d10b9e9bd74bd423c0ac10]
# to [4ea836110ca59b61655724a3eb2dcd1c9a5a34cb]
#
# patch "debian/changelog"
# from [016bdc7c1c824ca135635243a5b2b8fc98b65428]
# to [75eaeb6f09dbe2ab13fc811a92a0abfaa2780363]
#
# patch "enumerator.cc"
# from [31a5efd62fdaaada910d5b15b7fe31648a0ad17a]
# to [33a06c9ebfb955efb197f5eafb2e8d9beaee8a1d]
#
# patch "enumerator.hh"
# from [b2662b4dea76a8d832663ed48342920248449f70]
# to [1880dae7a6147b0ddd8064bfc4679334b520aeab]
#
# patch "lua.cc"
# from [78722201fdc513bfee248ce6b30b1b1ae593250e]
# to [8284c5010bee38f15141c3e60eeeeb7c288ee20c]
#
# patch "lua.hh"
# from [0d1c63ed6c7b36665ad92780ed88afa1edff3194]
# to [a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea]
#
# patch "monotone.1"
# from [f7f22f2d6e5bebf0d526d15651869113fe9c6ead]
# to [6a829e2dda9696f2b3949e266a24ed560c33bf71]
#
# patch "monotone.spec"
# from [31854929161128485e8ca1cb1e16d2b0d2bab8a1]
# to [b00e73feb017514c7dd84e700e9dd539585ecf57]
#
# patch "monotone.texi"
# from [59eb4911052af4a3a1743caf529acfe14dad092b]
# to [355d07f84caee318dd69f37ff6274842ca2d2c70]
#
# patch "netsync.cc"
# from [8c4cbdeb2898f87f5f74457e7148a4cc0afde674]
# to [8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa]
#
# patch "paths.cc"
# from [227025632497d6849fc4946feeded4d7980f7008]
# to [c13e9b0c44a37a70e6c7e6d5c8b8869e363ccab9]
#
# patch "paths.hh"
# from [727b9cfba7c9d150dfd7144d0d38744beb8dda7f]
# to [054a74b153b42a34140f2776f468bf79c844fa64]
#
# patch "po/sv.po"
# from [e347bfacd741eafd3202feda54aa54e24b3a7bfb]
# to [754e90276863a8b1a53cad17c575bb93ffcdd5b4]
#
# patch "revision.cc"
# from [8cda143f1b14ea5d67e40c9dc325b5ec6f2fd1a7]
# to [ca74a6db1747f8c8cf213167ec226df0e30c0b84]
#
# patch "revision.hh"
# from [5e3733994a6c92c4f15f0d78aa26669458443d46]
# to [ee41c7c61df986d551aebd2445a6232150a9c8b0]
#
# patch "roster.cc"
# from [e1c0e9fe71f80b5bd457801d3cf4eb3240872c22]
# to [4547e72b235da17471b9781c3416e7eac2904027]
#
# patch "roster.hh"
# from [6811b78a4a979e2146ba44e6c3a3023dec0b4c53]
# to [0f6d33d17d3d1c804be21f2e8025d86e47f087f9]
#
# patch "sanity.cc"
# from [7b7dd4d379a294fa3d79c0bb0f39dde2ae48d315]
# to [b31758131617cacbc373a95c25cab49e15ffedc3]
#
# patch "sanity.hh"
# from [ae8401c8dc9afd96ed17ebdb5362fa3cf735d405]
# to [3d91a4abd21f2af06ea78724a922b3b52fa0838f]
#
# patch "sqlite/alter.c"
# from [26d755f2143719dd3f5b8aaf6cbe3c7f95332528]
# to [faf98b04050d674d06df21bcf23ded5bbff7b5b7]
#
# patch "sqlite/analyze.c"
# from [21a4cd125bedd3cb15857595c45c2a49c0556d26]
# to [7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a]
#
# patch "sqlite/attach.c"
# from [4b21689700a72ae281fa85dbaff06b2a62bd49ee]
# to [d73a3505de3fb9e373d0a158978116c4212031d0]
#
# patch "sqlite/auth.c"
# from [31e2304bef67f44d635655f44234387ea7d21454]
# to [9ae84d2d94eb96195e04515715e08e85963e96c2]
#
# patch "sqlite/btree.c"
# from [236126155d5607da945d33514218cbec762d887e]
# to [f45f57e6cbd3b3db947cdd699db64e5215d20b2a]
#
# patch "sqlite/btree.h"
# from [1ed561263ca0e335bc3e81d761c9d5ff8c22f61e]
# to [5663c4f43e8521546ccebc8fc95acb013b8f3184]
#
# patch "sqlite/build.c"
# from [aa9591839c00731370c1ba53a9c0045f70d764c4]
# to [feaa61e769d7887ffeaa060d746638c7b3e994ef]
#
# patch "sqlite/callback.c"
# from [9a1162c8f9dae9fad6d548339669aacb5f6cf76b]
# to [1bf497306c32229114f826707054df7ebe10abf2]
#
# patch "sqlite/complete.c"
# from [641713ef01657f74037840abb9c0a4552c07b0d0]
# to [7d1a44be8f37de125fcafd3d3a018690b3799675]
#
# patch "sqlite/date.c"
# from [7444b0900a28da77e57e3337a636873cff0ae940]
# to [c70a4f88e495ae2c523f6ef3848c26a021c96de8]
#
# patch "sqlite/delete.c"
# from [29dac493f4d83b05f91233b116827c133bcdab72]
# to [56ab34c3a384caa5d5ea06f5739944957e2e4213]
#
# patch "sqlite/expr.c"
# from [bb2cf5d5b065eaa23d5ae2620f6de0568768147d]
# to [1149c3380bfce27703f5e9bec7dfb8e51baaf9d9]
#
# patch "sqlite/func.c"
# from [f63d417248808ff2632a3b576536abffcc21d858]
# to [96b26601c092b7b43a13e440e3f988b32a385f6a]
#
# patch "sqlite/hash.c"
# from [2b1b13f7400e179631c83a1be0c664608c8f021f]
# to [8747cf51d12de46512880dfcf1b68b4e24072863]
#
# patch "sqlite/insert.c"
# from [1f51566d7cf4b243a2792f5fda37343d6e9377fa]
# to [7e931b7f06afbcefcbbaab175c02eff8268db33f]
#
# patch "sqlite/keywordhash.h"
# from [32380a4bfe997d18e3ecd5b85fd948cf7b52aec8]
# to [53d6b6630b71e2ec402f2c2ff85e3f7e8e88a3cc]
#
# patch "sqlite/legacy.c"
# from [d58ea507bce885298a2c8c3cbb0f4bff5d47830b]
# to [86b669707b3cefd570e34154e2f6457547d1df4f]
#
# patch "sqlite/main.c"
# from [422014201f22aa17b96c76650163178a91a825af]
# to [2693776249865dc69b97904205638e84a34a059c]
#
# patch "sqlite/opcodes.c"
# from [9855bca95408a841cfbeb92135596bc18d7c034a]
# to [1c881baf37c8d67fb9a9a9eb76ba01d98d8a3fd2]
#
# patch "sqlite/opcodes.h"
# from [9918b6dfce41b2465940c5f6631afd418584dfb3]
# to [77c3b5ca782504a8d2c92e86839664f74d38fcca]
#
# patch "sqlite/os.h"
# from [c51f2747f7bd1840447e2c7d26db749604626814]
# to [93035a0e3b9dd05cdd0aaef32ea28ca28e02fe78]
#
# patch "sqlite/os_common.h"
# from [1ff88c7e7e6bd3e5f85443106c91cc26a4f8600b]
# to [061fba8511a656b118551424f64e366ad0d4cb3b]
#
# patch "sqlite/os_unix.c"
# from [407dd07818d13807c396acf3f7570af81cbb666c]
# to [73c5e722a661ed98d8919f204911e4e34e51fa41]
#
# patch "sqlite/os_win.c"
# from [fbccc85e7011174068c27d54256746321a1f0059]
# to [566bf7b41b72556fd7dca390bceaa2769dc395e9]
#
# patch "sqlite/pager.c"
# from [b74ebe5aca00ad5f831e19ae17193fe7b83a7ddf]
# to [b5b380ea7a36f84e50c3adc1a414820a0eb3baa6]
#
# patch "sqlite/pager.h"
# from [e7b41ce8e7b5f629d456708b7ad9a8c8ede37140]
# to [e0acb095b3ad0bca48f2ab00c87346665643f64f]
#
# patch "sqlite/parse.c"
# from [13d6d5853fcaddd632125185f51a4705558950fb]
# to [a31a0cb5fd9be3781389e4b2784b197d03226dc4]
#
# patch "sqlite/parse.h"
# from [c3a865a73a9e4988142a3008f99d3cc91fdf77b4]
# to [20eb1ccb1fa5d4e4493dd0ca916ad74b515eefcf]
#
# patch "sqlite/pragma.c"
# from [126149668aa7086e86cfa3e32c8523513c19dd63]
# to [4496cc77dc35824e1c978c3d1413b8a5a4c777d3]
#
# patch "sqlite/prepare.c"
# from [fc098db25d2a121affb08686cf04833fd50452d4]
# to [40ae23c8aeb641dc7b9bb271eb5e295b815154a7]
#
# patch "sqlite/printf.c"
# from [bd421c1ad5e01013c89af63c60eab02852ccd15e]
# to [c7d6ad9efb71c466305297a448308f467b6e2b6e]
#
# patch "sqlite/random.c"
# from [90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4]
# to [d40f8d356cecbd351ccfab6eaedd7ec1b54f5261]
#
# patch "sqlite/select.c"
# from [034c7f7447b8711f85bef578a437ea12ca7cac53]
# to [daee9b20702ba51cf3807fc1b130edd8846e3e48]
#
# patch "sqlite/sqlite3.h"
# from [44d8c045175afc3da51063660eab529d9ccbd07a]
# to [6b9ed927e0a9a3c6051a372929c97c2ac87ab314]
#
# patch "sqlite/sqliteInt.h"
# from [0606b9cc31efabadf5b3d40478c193fa89fa6662]
# to [0121298397ac14eb468ab1ba9d488ac7ed7d88a1]
#
# patch "sqlite/table.c"
# from [25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9]
# to [486dcfce532685b53b5a2b5da8bba0ded6fb2316]
#
# patch "sqlite/tokenize.c"
# from [e1faf5637f3f4f90933785a0ecf64595f3ac3530]
# to [9ae9a59238eb97fbc61baea280563b91100518fb]
#
# patch "sqlite/trigger.c"
# from [f51dec15921629591cb98bf2e350018e268b109a]
# to [4d3644cbd16959b568c95ae73493402be8021b08]
#
# patch "sqlite/update.c"
# from [ac506fb7400158f826ec6c3a0dbe65e7ed3928d5]
# to [14be4ba2f438919b4217085c02feff569e6cf1f2]
#
# patch "sqlite/utf.c"
# from [bda5eb85039ef16f2d17004c1e18c96e1ab0a80c]
# to [1199766bbb0157931a83aa6eede6b6381177be64]
#
# patch "sqlite/util.c"
# from [55caaffbb2716f9928ab452d20f3e9cbbeab872d]
# to [82ee598519b8193184bdeab06b51a4ffa05ad60b]
#
# patch "sqlite/vacuum.c"
# from [829d9e1a6d7c094b80e0899686670932eafd768c]
# to [3865673cc66acd0717ecd517f6b8fdb2a5e7924b]
#
# patch "sqlite/vdbe.c"
# from [3f1adcf4535dd35e4244d19d332fb6b515491c0d]
# to [fee677e05236e483d6c75d1d4229955fc1b89193]
#
# patch "sqlite/vdbeInt.h"
# from [7bedbb9553a10e86b53f75d99e197f3f00a732bf]
# to [eb3f86ab08ef11635bc78eb88c3ff13f923c233b]
#
# patch "sqlite/vdbeapi.c"
# from [85bbe1d0243a89655433d60711b4bd71979b59cd]
# to [dcb2636f49b4807e34960d52a2fc257b3a751140]
#
# patch "sqlite/vdbeaux.c"
# from [2b728d82cf2095386a90051b66e7faf1a143f27d]
# to [9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797]
#
# patch "sqlite/vdbemem.c"
# from [ff426ff6e72aa3f0300a56ec8c7f18099be96b43]
# to [2034e93b32c14bda6e306bb54e3a8e930b963027]
#
# patch "sqlite/where.c"
# from [3ed72ca029b3010a76e3a41b7b02ec1bdf849f00]
# to [8409e00fa2cb5fce873b4c911165cfed097e9c49]
#
# patch "std_hooks.lua"
# from [1740ad529749fadac6c115b8373ca26e9f932ad6]
# to [8f01e338e8056c62de500694210fd22dacac6122]
#
# patch "tests/t_add_owndb.at"
# from [1a63fac0aa5c37fb17934cdb1cd79062e4c284c4]
# to [74dcb2ff61d7a8cb9c787ddabcbd74aa10ea2eb8]
#
# patch "tests/t_cvsimport.at"
# from [42e05f340ace04dd4bfdc4e948ab651669f8d2b8]
# to [72f1079d6cb4ac5810d17e8ecf709e97cec1460b]
#
# patch "tests/t_cvsimport3.at"
# from [7a5e68124be1da212a3b89c64f098446891952e2]
# to [f986d11da315b23a88364d9ed55b2e702fc21dc5]
#
# patch "tests/t_cvsimport_deleted_invar.at"
# from [f6cef14b364d39403eaf99f2a18ad255047f4ca7]
# to [c01438bad0867f343040ad9c9f76f0f6803957a0]
#
# patch "tests/t_cvsimport_manifest_cycle.at"
# from [690f76368733c0e909bde2a46f8edea144f7569b]
# to [367b143477d97f31b5fe948cbc3b3b4960424aac]
#
# patch "tests/t_cvsimport_samelog.at"
# from [515ea15748990c4be6f61a9a811266b58fb331e7]
# to [ad82fe334cab4c3cf15409c91498ab99a413cf96]
#
# patch "tests/t_database_check_normalized.at"
# from [a226dd38826693885d4b9209528dac5fced42d6f]
# to [903b3a090390261102a713b0339e99322d728f16]
#
# patch "tests/t_diff_outside_workspace.at"
# from [28c8bf8ea6fc2088a754308386f6ab936506dc77]
# to [91e929a8e18167fc073b033b782d50c04d0dabad]
#
# patch "tests/t_drop_missing.at"
# from [b57855a8b89e7f7c8c7cab3ae9fdf660bc4c0111]
# to [7d7b49bf0e6aee2bb8a7bf96202f464367673274]
#
# patch "tests/t_mt_ignore.at"
# from [70d452af35a31d73ed28834e8f710d7a2220b140]
# to [979d32a72c8573f493f549ecf34039562014ca05]
#
# patch "tests/t_netsync_permissions.at"
# from [a02747cf46bece412d85d63694356704a482c8ff]
# to [9a8356b76404d50e044f74e5f59d6e055ad64d1e]
#
# patch "tests/t_rename.at"
# from [b95e23675e65c4c3c9bd2b3490d08ce117b11836]
# to [f9830fde9e91d2b2c97e3ec7d4c423d3e12d2726]
#
# patch "tests/t_singlecvs.at"
# from [d98391bad7a3290996b9a4354e173ccd3277b001]
# to [32bf2cf13d8cb1e5e93e04a979d2202f3172a24a]
#
# patch "testsuite.at"
# from [2cd96ae551245bab68f4982936338bade0beef18]
# to [781e96c61a849b6f628e1aa691189b64f4d1bf08]
#
# patch "vocab.cc"
# from [084a7a4538c3e0b062b901d0ba891fd6b66cfdfe]
# to [c3824a3441b679e4e8c2c8f29fa412bcf2d2d1c3]
#
# patch "vocab.hh"
# from [596953ad6326b68846702a85c22977f434e760e9]
# to [018407f5255129c875a8ccdfaae93c2645d1ac05]
#
# patch "win32/monotone.iss"
# from [77fa8d3df108c2bad33e0f51d5770f3642b258db]
# to [48ab358ef0443f95fd1db2d14767914ffb6cbe60]
#
# patch "work.cc"
# from [974c1d8a5295fd7317898e60abc636fdcc82ba65]
# to [265e6d058be85a58414c208164fbe9592b1d3e74]
#
============================================================
--- sqlite/os.c 59f05de8c5777c34876607114a2fbe55ae578235
+++ sqlite/os.c 59f05de8c5777c34876607114a2fbe55ae578235
@@ -0,0 +1,92 @@
+/*
+** 2005 November 29
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains OS interface code that is common to all
+** architectures.
+*/
+#define _SQLITE_OS_C_ 1
+#include "sqliteInt.h"
+#include "os.h"
+
+/*
+** The following routines are convenience wrappers around methods
+** of the OsFile object. This is mostly just syntactic sugar. All
+** of this would be completely automatic if SQLite were coded using
+** C++ instead of plain old C.
+*/
+int sqlite3OsClose(OsFile **pId){
+ OsFile *id;
+ if( pId!=0 && (id = *pId)!=0 ){
+ return id->pMethod->xClose(pId);
+ }else{
+ return SQLITE_OK;
+ }
+}
+int sqlite3OsOpenDirectory(OsFile *id, const char *zName){
+ return id->pMethod->xOpenDirectory(id, zName);
+}
+int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
+ return id->pMethod->xRead(id, pBuf, amt);
+}
+int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
+ return id->pMethod->xWrite(id, pBuf, amt);
+}
+int sqlite3OsSeek(OsFile *id, i64 offset){
+ return id->pMethod->xSeek(id, offset);
+}
+int sqlite3OsTruncate(OsFile *id, i64 size){
+ return id->pMethod->xTruncate(id, size);
+}
+int sqlite3OsSync(OsFile *id, int fullsync){
+ return id->pMethod->xSync(id, fullsync);
+}
+void sqlite3OsSetFullSync(OsFile *id, int value){
+ id->pMethod->xSetFullSync(id, value);
+}
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+/* This method is currently only used while interactively debugging the
+** pager. More specificly, it can only be used when sqlite3DebugPrintf() is
+** included in the build. */
+int sqlite3OsFileHandle(OsFile *id){
+ return id->pMethod->xFileHandle(id);
+}
+#endif
+int sqlite3OsFileSize(OsFile *id, i64 *pSize){
+ return id->pMethod->xFileSize(id, pSize);
+}
+int sqlite3OsLock(OsFile *id, int lockType){
+ return id->pMethod->xLock(id, lockType);
+}
+int sqlite3OsUnlock(OsFile *id, int lockType){
+ return id->pMethod->xUnlock(id, lockType);
+}
+int sqlite3OsLockState(OsFile *id){
+ return id->pMethod->xLockState(id);
+}
+int sqlite3OsCheckReservedLock(OsFile *id){
+ return id->pMethod->xCheckReservedLock(id);
+}
+
+#ifdef SQLITE_ENABLE_REDEF_IO
+/*
+** A function to return a pointer to the virtual function table.
+** This routine really does not accomplish very much since the
+** virtual function table is a global variable and anybody who
+** can call this function can just as easily access the variable
+** for themselves. Nevertheless, we include this routine for
+** backwards compatibility with an earlier redefinable I/O
+** interface design.
+*/
+struct sqlite3OsVtbl *sqlite3_os_switch(void){
+ return &sqlite3Os;
+}
+#endif
============================================================
--- tests/t_commit_validate.at 2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3
+++ tests/t_commit_validate.at 2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3
@@ -0,0 +1,31 @@
+# -*- Autoconf -*-
+# vim: tw=0
+
+AT_SETUP([commit validation lua hook])
+
+MONOTONE_SETUP
+
+AT_DATA(commit_validate.lua, [
+function validate_commit_message(message, info)
+ if (not string.find(info, "input.txt")) then
+ return false, "Wrong info message"
+ end
+ if (message == "denyme") then
+ return false, "input.txt"
+ end
+
+ return true, ""
+end
+])
+
+AT_DATA(input.txt, [version 0 of the file
+])
+
+AT_CHECK(MONOTONE add input.txt, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "denyme", 1, [ignore], [monotone: beginning commit on branch 'testbranch'
+monotone: misuse: log message rejected: input.txt
+])
+AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "allowme", 0, ignore, ignore)
+
+AT_CLEANUP
============================================================
--- tests/t_ls_changed.at 1fc5edbd5d67ff60df161f44864efced6c08670a
+++ tests/t_ls_changed.at 1fc5edbd5d67ff60df161f44864efced6c08670a
@@ -0,0 +1,44 @@
+# -*- Autoconf -*-
+
+AT_SETUP([listing changed files])
+
+MONOTONE_SETUP
+
+AT_DATA(foo, [the foo file
+])
+AT_DATA(bar, [the bar file
+])
+AT_DATA(baz, [the baz file
+])
+AT_CHECK(MONOTONE add foo bar baz, [], [ignore], [ignore])
+AT_CHECK(MONOTONE --branch=testbranch commit --message='First commit', [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE ls changed, [], [stdout], [])
+AT_CHECK(cmp stdout /dev/null, [], [ignore])
+
+AT_CHECK(MONOTONE drop foo, [], [ignore], [ignore])
+AT_CHECK(MONOTONE rename --execute bar bartender, [], [ignore], [ignore])
+AT_CHECK(MONOTONE ls changed, [], [stdout], [])
+AT_CHECK(CANONICALISE(stdout))
+AT_DATA(ls_foobar, [bar
+foo
+])
+AT_CHECK(cmp stdout ls_foobar, [], [ignore])
+AT_CHECK(MONOTONE --branch=testbranch commit --message='Second commit', [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE ls changed, [], [stdout], [])
+AT_CHECK(cmp stdout /dev/null, [], [ignore])
+
+AT_DATA(baz, [the baz file, modified
+])
+AT_CHECK(MONOTONE ls changed, [], [stdout], [])
+AT_CHECK(CANONICALISE(stdout))
+AT_DATA(ls_baz, [baz
+])
+AT_CHECK(cmp stdout ls_baz, [], [ignore])
+AT_CHECK(MONOTONE --branch=testbranch commit --message='Third commit', [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE ls changed, [], [stdout], [])
+AT_CHECK(cmp stdout /dev/null, [], [ignore])
+
+AT_CLEANUP
============================================================
--- AUTHORS be2883d201fdd61b63582334f52312a640e012a1
+++ AUTHORS 66d90072b355ef6e2b66f56c0dfa00de1565dc98
@@ -72,6 +72,7 @@ contributing authors, including:
Roland McGrath <roland@redhat.com>
Daniel Carosone <dan@geek.com.au>
Vinzenz Feenstra <evilissimo@c-plusplus.de>
+ Blake Kaplan <mrbkap@gmail.com>
Several people have also contributed to the translation of monotone
into non-English languages; their work is available in the po/
============================================================
--- ChangeLog 259eb3350818f249dada218ce2ffb43a71a4971e
+++ ChangeLog cf7af27d617c006696a08efcd68a9bd9fd401a7a
@@ -1,3 +1,167 @@
+2006-02-12 Nathaniel Smith <njs@pobox.com>
+
+ * netsync.cc (serve_connections): Revert garbage that I
+ accidentally checked in last time...
+
+2006-02-12 Nathaniel Smith <njs@pobox.com>
+
+ * NEWS: Add things done since last time I did this...
+
+2006-02-12 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * {cset,paths,revision,roster,sanity,vocab}.{cc,hh}: GCC 4.1
+ compile fixes.
+
+2006-02-11 Richard Levitte <richard@levitte.org>
+
+ * NEWS: Removed my notice about netsync, as I just noticed it
+ was already mentioned under Bugs:.
+
+2006-02-11 Nathaniel Smith <njs@pobox.com>
+
+ * configure.ac, debian/changelog, monotone.spec:
+ * win32/monotone.iss: Bump version to 0.26pre2.
+
+2006-02-11 Nathaniel Smith <njs@pobox.com>
+
+ * NEWS: Add mention of validate_commit_message.
+
+2006-02-11 Blake Kaplan <mrbkap@gmail.com>
+
+ * monotone.texi (Hooks): Added new subsection about validation
+ hooks, and describe validate_commit_message in it.
+
+ * std_hooks.lua (validate_commit_message): Change the second
+ argument to match the documentation.
+
+2006-02-11 Matt Johnston <matt@ucc.asn.au>
+
+ * database.hh: increase checkpoint batch size from 100 to 1000
+
+2006-02-11 Matt Johnston <matt@ucc.asn.au>
+
+ * NEWS: Fix rename example.
+
+2006-02-11 Richard Levitte <richard@levitte.org>
+
+ * NEWS: Update with the netsync change.
+
+2006-02-11 Nathaniel Smith <njs@pobox.com>
+
+ * NEWS: Draft for 0.26pre2.
+
+2006-02-11 Richard Levitte <richard@levitte.org>
+
+ * netsync.cc (serve_connections): Enclose more or less everything
+ in a try-catch block to catch if using IPv6 failed, and to try
+ with just IPv4 in that case. This is important for those who
+ copy a IPv6-enabled binary to a system that doesn't use IPv6.
+
+ * po/sv.po: Adapt translation to the newly changed messages.
+
+2006-02-10 Derek Scherger <derek@echologic.com>
+
+ * tests/t_drop_missing.at:
+ * tests/t_rename.at:
+ * work.cc (visit_file): attempt to improve a couple of messages;
+ remove some unrequired \n's
+
+2006-02-10 Derek Scherger <derek@echologic.com>
+
+ * netsync.cc (process_anonymous_cmd, process_auth_cmd): don't
+ report misleading permission denied errors for branches that are
+ not being served
+ * paths.cc (find_and_go_to_workspace): delete stale comment
+ * tests/t_netsync_permissions.at: add test pull of branch that is
+ not served
+
+2006-02-11 Timothy Brownawell <tbrownaw@gmail.com>
+
+ Adding your db is silly and confusing (what should revert do?).
+ So, it's not allowed any more (the db file is ignored, regardless of
+ what the ignore hook says).
+ * tests/t_add_owndb.at: remove XFAIL, use 'ls known' instead of
+ 'ls unknown'
+ * testsuite.at: don't put the db in the ignore hook
+ * database.{cc,hh}: is_dbfile(), check if a path is the database file
+ * work.cc: check is_dbfile where we check the ignore hook when
+ walking the filesystem
+ * tests/t_mt_ignore.at: fix for having the db always be ignored
+
+2006-02-10 Richard Levitte <richard@levitte.org>
+
+ * monotone.texi (Hooks): Change the example for
+ get_revisions_cert_trust to check "branch" certs instead of
+ "ancestor" ones, and thereby match the effect of the "approve"
+ command.
+
+2006-02-10 Matt Johnston <matt@ucc.asn.au>
+
+ * commands.cc (CMD(checkout)): wrapping in a transaction makes
+ a big difference.
+
+2006-02-09 Nathaniel Smith <njs@pobox.com>
+
+ * Makefile.am (SQLITE_SOURCES): Remove header files lost in
+ latest SQLite upstream import.
+
+2006-02-09 Graydon Hoare <graydon@pobox.com>
+
+ * lua.cc (hook_validate_commit_message): make validated the
+ default.
+
+2006-02-09 Richard Levitte <richard@levitte.org>
+
+ * tests/t_cvsimport.at, tests/t_cvsimport3.at,
+ tests/t_cvsimport_deleted_invar.at,
+ tests/t_cvsimport_manifest_cycle.at, tests/t_cvsimport_samelog.at,
+ tests/t_singlecvs.at: Changed to cope with the strictness of
+ CVSNT. It doesn't create a CSVROOT/history file automagically,
+ but CVSROOT/modules is created automatically both by the older CVS
+ and by CVSNT. You can't check out a group of files using revision
+ numbers with CVSNT. You MUST stand in the work directory for some
+ command with CVSNT. Finally, with CVSNT, 'cvs init' generates the
+ following message if you're a normal user, at least on Debian:
+
+ cvs init: Unable to register repository.
+ cvs init: Your login may not have sufficient permissions to modify the
+ cvs init: global server settings.
+ cvs init: Repository /home/levitte/cvsfoo initialised
+
+2006-02-09 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * testsuite.at: Remove duplicate line.
+
+2006-02-08 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * sqlite/*: Import SQLite 3.3.3.
+ * Makefile.am: Adjust for new and removed files in import.
+ * NEWS: Make a note of the SQLite database format change.
+ * database.cc (database::load): Rewrite so that we don't need any
+ local changes to SQLite.
+
+2006-02-08 Richard Levitte <richard@levitte.org>
+
+ * testsuite.at, tests/t_ls_changed.at: News test, for "list
+ changed".
+
+ * monotone.texi, monotone.1: Document "list changed".
+
+ * po/sv.po: Correct translations of changed messages, translate
+ new messages.
+
+ * commands.cc (ls_changed, CMD(list)): Add a new command, "list
+ changed", to list changed files, always sorted in lexical order.
+
+2006-02-06 Blake Kaplan <mrbkap@gmail.com>
+
+ * commands.cc CMD(commit): Call a new lua hook to validate the commit
+ message. Don't ignore -m "" when it's passed on the command line.
+ * lua.cc, lua.hh: Add a new hook that validates a given commit message
+ and passes in the added files, deleted files, and modified files.
+ * std_hooks.lua: Give a default hook to validate commit messages. This
+ currently disallows empty messages, as monotone currently does.
+
2006-02-05 Benoît Dejean <benoit@placenet.org>
* ui.cc (tick_write_count::write_ticks): Reverted lexical_cast,
============================================================
--- Makefile.am 1086b6f0ea35d96bdd46455c7d97c5934fb77e5a
+++ Makefile.am d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1
@@ -172,7 +172,7 @@ SQLITE_SOURCES = \
sqlite/build.c sqlite/date.c sqlite/delete.c sqlite/expr.c sqlite/func.c \
sqlite/hash.c sqlite/insert.c \
sqlite/legacy.c sqlite/main.c sqlite/opcodes.c \
- sqlite/os_unix.c sqlite/os_win.c \
+ sqlite/os.c sqlite/os_unix.c sqlite/os_win.c \
sqlite/pager.c sqlite/parse.c sqlite/pragma.c sqlite/printf.c \
sqlite/random.c sqlite/select.c sqlite/table.c sqlite/tokenize.c \
sqlite/trigger.c sqlite/update.c sqlite/utf.c \
@@ -183,8 +183,8 @@ SQLITE_SOURCES = \
sqlite/analyze.c sqlite/vdbefifo.c \
sqlite/complete.c \
\
- sqlite/btree.h sqlite/config.h sqlite/hash.h sqlite/opcodes.h sqlite/os.h \
- sqlite/os_common.h sqlite/os_unix.h sqlite/os_win.h \
+ sqlite/btree.h sqlite/hash.h sqlite/opcodes.h sqlite/os.h \
+ sqlite/os_common.h \
sqlite/parse.h sqlite/sqlite3.h sqlite/sqliteInt.h sqlite/vdbe.h sqlite/vdbeInt.h \
sqlite/pager.h
============================================================
--- NEWS 4109c836eec71571ad7f8cca182bd780771e13a6
+++ NEWS ef3bd56b18d1386927ffb58c2bb20ef4070712dd
@@ -1,3 +1,72 @@
+Sat Feb 11 13:32:51 PST 2006
+
+ 0.26pre2 release. Inching towards 0.26. If you are using
+ 0.25 or earlier, then make sure to read the very important
+ notes for 0.26pre1, below. In particular, like 0.26pre1, this
+ is a pre-release for testing. Do not package it. DO NOT USE
+ THIS RELEASE UNLESS YOU WANT TO BE A DAREDEVIL.
+
+ (Though, in fact, in a month of usage, only one bug has been
+ found in the new history code, and it was both minor and
+ harmless. It has additionally been fixed.)
+
+ Database changes:
+
+ - SQLite 3.3.3 has been imported. 3.3 introduces a new database
+ format that is not backwards compatible with earlier 3.x releases.
+ New databases will be created using this new format. Existing
+ databases remain compatible, and are not converted automatically.
+ Existing databases can be converted by performing a database
+ vacuum ('monotone db execute vacuum').
+
+ New features:
+
+ - New hook validate_commit_message -- use to verify that all
+ commit messages meet arbitrary user-defined rules.
+
+ UI improvements:
+
+ - rename (and mv) commands now accept a broader range of
+ syntax:
+ monotone rename foo some_dir
+ -> renames foo to some_dir/foo
+ monotone rename foo bar baz some_dir
+ -> moves foo, bar, and baz to some_dir/foo,
+ some_dir/bar, and some_dir/baz
+ - Print a warning if it looks like a user has made a quoting
+ mistake on push/pull/sync/serve (windows cmd.exe has
+ confusing rules here).
+ - New command "ls changed".
+ - New option "--next" to log, which displays descendents of
+ the start revision.
+ - Updating to an arbitrary revision now works again (as it did
+ in 0.25 and earlier). This allows one to, for instance,
+ switch a working copy to another head, or back up to an
+ earlier version, while preserving uncommitted changes.
+ - New option --brief to annotate, gives somewhat more friendly
+ output.
+ - Fixed bug that made ticker output from netsync inaccurate.
+ - In 'log', --no-merges is now the default, use --merges to
+ override.
+ - If the database is in the working copy, then it is always
+ ignored.
+
+ Bugs:
+
+ - 'serve' with no --bind should now work on systems where the
+ C library has IPv6 support, but the kernel does not.
+ - Compile fixes for GCC 4.1 pre-releases.
+
+ Other:
+ - Better detection when users have not run "rosterify", and
+ more helpful suggestions on what to do in this case.
+ - Documentation, translation, error message,
+ etc. improvements.
+ - Updates to contrib/mtbrowse.sh, simple shell-based monotone
+ interface.
+ - Updates to many other contrib/ files, mostly to maintain
+ compatibility with monotone changes.
+
Sun Jan 8 01:08:56 PST 2006
0.26pre1 release. Massive rewrites, released for shakedown.
============================================================
--- automate.cc 68d579fc833b4a0ec52a0c8e5b130af7517ab7ed
+++ automate.cc d86c347f85ee7ce7a59f699c8e51feaa1fa57bfb
@@ -283,7 +283,7 @@ automate_toposort(std::vector<utf8> args
revs.insert(rid);
}
std::vector<revision_id> sorted;
- toposort(revs, sorted, app);
+ toposort(revs, sorted, app.db);
for (std::vector<revision_id>::const_iterator i = sorted.begin();
i != sorted.end(); ++i)
output << (*i).inner()() << std::endl;
@@ -329,7 +329,7 @@ automate_ancestry_difference(std::vector
ancestry_difference(a, bs, ancestors, app);
std::vector<revision_id> sorted;
- toposort(ancestors, sorted, app);
+ toposort(ancestors, sorted, app.db);
for (std::vector<revision_id>::const_iterator i = sorted.begin();
i != sorted.end(); ++i)
output << (*i).inner()() << std::endl;
============================================================
--- commands.cc 2f64f75b9afb4a86bac84bcc6cacaba86866be2b
+++ commands.cc dbf77e72442ab85b8b4390b8fb1316ca8145d507
@@ -1,4 +1,5 @@
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
@@ -1417,6 +1418,8 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY
// we have a special case for "checkout .", i.e., to current dir
bool checkout_dot = false;
+ transaction_guard guard(app.db, false);
+
if (args.size() > 1 || app.revision_selectors.size() > 1)
throw usage(name);
@@ -1519,6 +1522,7 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY
remove_work_cset();
update_any_attrs(app);
maybe_update_inodeprints(app);
+ guard.commit();
}
ALIAS(co, checkout)
@@ -1736,19 +1740,78 @@ ls_missing (app_state & app, vector<utf8
}
-CMD(list, N_("informative"),
+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)
+{
+ revision_set rs;
+ revision_id rid;
+ roster_t old_roster, new_roster;
+ data tmp;
+ std::set<file_path, lt_file_path> files;
+
+ app.require_workspace();
+ get_working_revision_and_rosters(app, args, rs, old_roster, new_roster);
+
+ I(rs.edges.size() == 1);
+ cset const & cs = edge_changes(rs.edges.begin());
+
+ for (path_set::const_iterator i = cs.nodes_deleted.begin();
+ i != cs.nodes_deleted.end(); ++i)
+ {
+ if (app.restriction_includes(*i))
+ files.insert(file_path(*i));
+ }
+ for (std::map<split_path, split_path>::const_iterator i = cs.nodes_renamed.begin();
+ i != cs.nodes_renamed.end(); ++i)
+ {
+ if (app.restriction_includes(i->first))
+ files.insert(file_path(i->first));
+ }
+ for (path_set::const_iterator i = cs.dirs_added.begin();
+ i != cs.dirs_added.end(); ++i)
+ {
+ if (app.restriction_includes(*i))
+ files.insert(file_path(*i));
+ }
+ for (std::map<split_path, file_id>::const_iterator i = cs.files_added.begin();
+ i != cs.files_added.end(); ++i)
+ {
+ if (app.restriction_includes(i->first))
+ files.insert(file_path(i->first));
+ }
+ for (std::map<split_path, std::pair<file_id, file_id> >::const_iterator
+ i = cs.deltas_applied.begin(); i != cs.deltas_applied.end(); ++i)
+ {
+ if (app.restriction_includes(i->first))
+ files.insert(file_path(i->first));
+ }
+
+ copy(files.begin(), files.end(),
+ ostream_iterator<const file_path>(cout, "\n"));
+}
+
+
+CMD(list, N_("informative"),
N_("certs ID\n"
- "keys [PATTERN]\n"
- "branches\n"
- "epochs [BRANCH [...]]\n"
- "tags\n"
- "vars [DOMAIN]\n"
- "known\n"
- "unknown\n"
- "ignored\n"
- "missing"),
- N_("show database objects, or the current workspace manifest,\n"
- "or unknown, intentionally ignored, or missing state files"),
+ "keys [PATTERN]\n"
+ "branches\n"
+ "epochs [BRANCH [...]]\n"
+ "tags\n"
+ "vars [DOMAIN]\n"
+ "known\n"
+ "unknown\n"
+ "ignored\n"
+ "missing\n"
+ "changed"),
+ N_("show database objects, or the current workspace manifest, or known,\n"
+ "unknown, intentionally ignored, missing, or changed state files"),
OPT_DEPTH % OPT_EXCLUDE)
{
if (args.size() == 0)
@@ -1777,6 +1840,8 @@ CMD(list, N_("informative"),
ls_unknown_or_ignored(app, true, removed);
else if (idx(args, 0)() == "missing")
ls_missing(app, removed);
+ else if (idx(args, 0)() == "changed")
+ ls_changed(app, removed);
else
throw usage(name);
}
@@ -2126,6 +2191,11 @@ CMD(db, N_("database"),
build_changesets_from_manifest_ancestry(app);
else if (idx(args, 0)() == "rosterify")
build_roster_style_revs_from_manifest_style_revs(app);
+ else if (idx(args, 0)() == "flip")
+ {
+ app.db.make_fwd_deltas("files", "file_deltas");
+ app.db.make_fwd_deltas("rosters", "roster_deltas");
+ }
else
throw usage(name);
}
@@ -2258,12 +2328,12 @@ process_commit_message_args(bool & given
N(app.message().length() == 0 || app.message_file().length() == 0,
F("--message and --message-file are mutually exclusive"));
- if (app.message().length() > 0)
+ if (app.is_explicit_option(OPT_MESSAGE))
{
log_message = app.message();
given = true;
}
- else if (app.message_file().length() > 0)
+ else if (app.is_explicit_option(OPT_MSGFILE))
{
data dat;
read_data_for_command_line(app.message_file(), dat);
@@ -2274,7 +2344,6 @@ process_commit_message_args(bool & given
given = false;
}
-
CMD(commit, N_("workspace"), N_("[PATH]..."),
N_("commit workspace to database"),
OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE %
@@ -2340,6 +2409,16 @@ CMD(commit, N_("workspace"), N_("[PATH].
write_user_log(data(log_message));
}
+ // If the hook doesn't exist, allow the message to be used.
+ bool message_validated;
+ string reason, new_manifest_text;
+
+ dump(rs, new_manifest_text);
+
+ app.lua.hook_validate_commit_message(log_message, new_manifest_text,
+ message_validated, reason);
+ N(message_validated, F("log message rejected: %s\n") % reason);
+
{
transaction_guard guard(app.db);
packet_db_writer dbw(app);
============================================================
--- configure.ac 3db7a41acaf0a99ca96e19c12c2f96e5eaea45b1
+++ configure.ac 0bbe01c42c3d25e72176fda5c606e1e4c3ec3e6d
@@ -2,7 +2,7 @@ AC_PREREQ(2.58)
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.58)
-AC_INIT(monotone, 0.26pre1, monotone-devel@nongnu.org)
+AC_INIT(monotone, 0.26pre2, monotone-devel@nongnu.org)
AM_INIT_AUTOMAKE(1.7.1)
AC_CONFIG_SRCDIR([app_state.cc])
AC_CONFIG_TESTDIR([tests])
============================================================
--- cset.cc 7596f4bf16c8591f073c6c18df29668474c499c8
+++ cset.cc ac5f2a4848a4c5661496ec4f5af706de1fb6a454
@@ -461,7 +461,7 @@ read_cset(data const & dat, cset & cs)
I(src.lookahead == EOF);
}
-void
+template <> void
dump(cset const & cs, std::string & out)
{
data dat;
============================================================
--- cset.hh 077036ac38849e3b74dcdce595fdb5ee2762f282
+++ cset.hh f2d58803ea89b51b5029a349c30acc3c6c3cf580
@@ -123,7 +123,7 @@ read_cset(data const & dat, cset & cs);
void
read_cset(data const & dat, cset & cs);
-void
+template <> void
dump(cset const & cs, std::string & out);
============================================================
--- database.cc bd5cc9b0df537b2aab8520160761bbe8605ec6d8
+++ database.cc 4c830b7b46f89cdc384cae08e54bfeac62335eb7
@@ -119,6 +119,16 @@ database::database(system_path const & f
transaction_level(0)
{}
+bool
+database::is_dbfile(any_path const & file)
+{
+ system_path fn(file);// why is this needed?
+ bool same = (filename.as_internal() == fn.as_internal());
+ if (same)
+ L(FL("'%s' is the database file") % file);
+ return same;
+}
+
void
database::check_schema()
{
@@ -432,8 +442,8 @@ database::load(istream & in)
void
database::load(istream & in)
{
- char buf[constants::bufsz];
- string tmp;
+ string line;
+ string sql_stmt;
check_filename();
@@ -444,20 +454,16 @@ database::load(istream & in)
while(in)
{
- in.read(buf, constants::bufsz);
- tmp.append(buf, in.gcount());
+ getline(in, line, ';');
+ sql_stmt += line + ';';
- const char* last_statement = 0;
- sqlite3_complete_last(tmp.c_str(), &last_statement);
- if (last_statement == 0)
- continue;
- string::size_type len = last_statement + 1 - tmp.c_str();
- sqlite3_exec(__sql, tmp.substr(0, len).c_str(), NULL, NULL, NULL);
- tmp.erase(0, len);
+ if (sqlite3_complete(sql_stmt.c_str()))
+ {
+ sqlite3_exec(__sql, sql_stmt.c_str(), NULL, NULL, NULL);
+ sql_stmt.clear();
+ }
}
- if (!tmp.empty())
- sqlite3_exec(__sql, tmp.c_str(), NULL, NULL, NULL);
assert_sqlite3_ok(__sql);
}
@@ -788,6 +794,17 @@ database::delta_exists(hexenc<id> const
return res.size() > 0;
}
+bool
+database::delta_exists(hexenc<id> const & ident,
+ hexenc<id> const & base,
+ string const & table)
+{
+ results res;
+ query q("SELECT id FROM " + table + " WHERE id = ? AND base = ?");
+ fetch(res, one_col, any_rows, q % text(ident()) % text(base()));
+ return res.size() > 0;
+}
+
unsigned long
database::count(string const & table)
{
@@ -1164,23 +1181,10 @@ database::put_version(hexenc<id> const &
string const & data_table,
string const & delta_table)
{
+ // TODO: add an invariant or something perhaps
- data old_data, new_data;
- delta reverse_delta;
-
- get_version(old_id, old_data, data_table, delta_table);
- patch(old_data, del, new_data);
- diff(new_data, old_data, reverse_delta);
-
transaction_guard guard(*this);
- if (exists(old_id, data_table))
- {
- // descendent of a head version replaces the head, therefore old head
- // must be disposed of
- drop(old_id, data_table);
- }
- put(new_id, new_data, data_table);
- put_delta(old_id, new_id, reverse_delta, delta_table);
+ put_delta(new_id, old_id, del, delta_table);
guard.commit();
}
@@ -1361,6 +1365,29 @@ database::get_file_version(file_id const
dat = tmp;
}
+void
+database::get_file_delta(file_id const & id,
+ file_id const & base,
+ file_delta & del)
+{
+ if (delta_exists(id.inner(), base.inner(), "file_deltas"))
+ {
+ delta d;
+ get_delta(id.inner(), base.inner(), d, "file_deltas");
+ del = file_delta(d);
+ }
+ else
+ {
+ L(FL("get_file_delta failed for '%s'->'%s'") % base % id);
+ file_data dat, base_dat;
+ get_file_version(base, base_dat);
+ get_file_version(id, dat);
+ delta d;
+ diff(base_dat.inner(), dat.inner(), d);
+ del = file_delta(d);
+ }
+}
+
void
database::get_manifest_version(manifest_id const & id,
manifest_data & dat)
@@ -1467,6 +1494,81 @@ database::get_revision(revision_id const
dat = rdat;
}
+void
+database::make_fwd_deltas(string const & data_table, string const & delta_table)
+{
+ transaction_guard guard(*this);
+
+ set< hexenc<id> > del_bases, all_ids;
+ set< pair< hexenc<id>, hexenc<id> > > dels;
+
+ // id, base
+ get_ids(data_table, all_ids);
+ {
+ results res;
+ fetch(res, 2, any_rows, query("SELECT id, base FROM " + delta_table));
+
+ for (size_t i = 0; i < res.size(); ++i)
+ {
+ all_ids.insert(hexenc<id>(res[i][0]));
+ del_bases.insert(hexenc<id>(res[i][1]));
+ dels.insert( make_pair(res[i][0], res[i][1]) );
+ }
+ }
+
+ set< hexenc<id> > new_bases;
+
+ set_difference(all_ids.begin(), all_ids.end(), del_bases.begin(), del_bases.end(),
+ inserter(new_bases, new_bases.begin()));
+
+ // create some empty temporary tables
+ string tmp_data_table("tmp_" + data_table);
+ string tmp_delta_table("tmp_" + delta_table);
+
+ execute(query("CREATE TABLE " + tmp_data_table + " AS SELECT * FROM " + data_table + " WHERE 1=0"));
+ execute(query("CREATE TABLE " + tmp_delta_table + " AS SELECT * FROM " + delta_table + " WHERE 1=0"));
+
+ ticker full("full", "g", 1);
+ for ( set< hexenc<id> >::const_iterator i = new_bases.begin(); i != new_bases.end(); i++)
+ {
+ MM(*i);
+ data dat;
+ get_version(*i, dat, data_table, delta_table);
+ put(*i, dat, tmp_data_table);
+ ++full;
+ }
+
+ ticker flips("flips", "f", 1);
+
+ for ( set< pair< hexenc<id>, hexenc<id> > >::const_iterator i = dels.begin(); i != dels.end(); i++)
+ {
+ ++flips;
+ hexenc<id> new_id = i->second;
+ hexenc<id> new_base = i->first;
+ MM(new_id);
+ MM(new_base);
+
+ data base, dat;
+ get_version(new_id, dat, data_table, delta_table);
+ get_version(new_base, base, data_table, delta_table);
+ delta del;
+ diff(base, dat, del);
+
+ put_delta(new_id, new_base, del, tmp_delta_table);
+ }
+
+ execute(query("DELETE FROM " + data_table));
+ execute(query("DELETE FROM " + delta_table));
+
+ execute(query("INSERT INTO " + data_table + " SELECT * FROM " + tmp_data_table));
+ execute(query("INSERT INTO " + delta_table + " SELECT * FROM " + tmp_delta_table));
+
+ execute(query("DROP TABLE " + tmp_data_table));
+ execute(query("DROP TABLE " + tmp_delta_table));
+
+ guard.commit();
+}
+
void
database::deltify_revision(revision_id const & rid)
{
@@ -1559,7 +1661,8 @@ database::put_revision(revision_id const
% text(new_id.inner()()));
}
- deltify_revision(new_id);
+ // TODO: some different version?
+ // deltify_revision(new_id);
// Phase 4: write the roster data and commit
put_roster(new_id, ros, mm);
@@ -2624,7 +2727,6 @@ database::get_roster(revision_id const &
read_roster_and_marking(dat, roster, marks);
}
-
void
database::put_roster(revision_id const & rev_id,
roster_t & roster,
@@ -2632,7 +2734,6 @@ database::put_roster(revision_id const &
{
MM(rev_id);
data old_data, new_data;
- delta reverse_delta;
hexenc<id> old_id, new_id;
write_roster_and_marking(roster, marks, new_data);
@@ -2661,13 +2762,13 @@ database::put_roster(revision_id const &
// Else we have a new roster the database hasn't seen yet; our task is to
// add it, and deltify all the incoming edges (if they aren't already).
- put(new_id, new_data, data_table);
std::set<revision_id> parents;
get_revision_parents(rev_id, parents);
// Now do what deltify would do if we bothered (we have the
// roster written now, so might as well do it here).
+ bool delta_written = false;
for (std::set<revision_id>::const_iterator i = parents.begin();
i != parents.end(); ++i)
{
@@ -2675,14 +2776,18 @@ database::put_roster(revision_id const &
continue;
revision_id old_rev = *i;
get_roster_id_for_revision(old_rev, old_id);
- if (exists(new_id, data_table))
- {
- get_version(old_id, old_data, data_table, delta_table);
- diff(new_data, old_data, reverse_delta);
- drop(old_id, data_table);
- put_delta(old_id, new_id, reverse_delta, delta_table);
- }
+ get_version(old_id, old_data, data_table, delta_table);
+ delta del;
+ diff(old_data, new_data, del);
+ put_delta(new_id, old_id, del, delta_table);
+ delta_written = true;
+ break;
}
+
+ // in case the parents were all null/didn't exist
+ if (!delta_written)
+ put(new_id, new_data, data_table);
+
guard.commit();
}
============================================================
--- database.hh dd9695e867200e94e2d10b9e9bd74bd423c0ac10
+++ database.hh 4ea836110ca59b61655724a3eb2dcd1c9a5a34cb
@@ -110,6 +110,9 @@ class database
std::string const & table);
bool delta_exists(hexenc<id> const & ident,
std::string const & table);
+ bool database::delta_exists(hexenc<id> const & ident,
+ hexenc<id> const & base,
+ std::string const & table);
unsigned long count(std::string const & table);
unsigned long space_usage(std::string const & table,
@@ -205,6 +208,7 @@ public:
database(system_path const & file);
void set_filename(system_path const & file);
+ bool is_dbfile(any_path const & file);
void initialize();
void debug(std::string const & sql, std::ostream & out);
void dump(std::ostream &);
@@ -243,6 +247,11 @@ public:
file_id const & new_id,
file_delta const & del);
+
+ void get_file_delta(file_id const & id,
+ file_id const & base,
+ file_delta & del);
+
// get plain version if it exists, or reconstruct version
// from deltas (if they exist).
void get_manifest_version(manifest_id const & id,
@@ -259,6 +268,8 @@ public:
void get_revision_manifest(revision_id const & cid,
manifest_id & mid);
+ void make_fwd_deltas(std::string const & data_table, std::string const & delta_table);
+
void deltify_revision(revision_id const & rid);
void get_revision(revision_id const & id,
@@ -475,7 +486,7 @@ public:
size_t checkpointed_bytes;
public:
transaction_guard(database & d, bool exclusive=true,
- size_t checkpoint_batch_size=100,
+ size_t checkpoint_batch_size=1000,
size_t checkpoint_batch_bytes=0xfffff);
~transaction_guard();
void do_checkpoint();
============================================================
--- debian/changelog 016bdc7c1c824ca135635243a5b2b8fc98b65428
+++ debian/changelog 75eaeb6f09dbe2ab13fc811a92a0abfaa2780363
@@ -1,3 +1,9 @@
+monotone (0.26pre2-0.1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Nathaniel Smith <njs@pobox.com> Sat, 11 Feb 2006 13:36:27 -0800
+
monotone (0.26pre1-0.1) unstable; urgency=low
* New upstream release.
============================================================
--- enumerator.cc 31a5efd62fdaaada910d5b15b7fe31648a0ad17a
+++ enumerator.cc 33a06c9ebfb955efb197f5eafb2e8d9beaee8a1d
@@ -27,10 +27,14 @@ revision_enumerator::revision_enumerator
set<revision_id> const & terminal)
: cb(cb), app(app), terminal_nodes(terminal)
{
+ // TODO: needs sorting out with the toposort stuff.
+ I(false);
+ /*
for (set<revision_id>::const_iterator i = initial.begin();
i != initial.end(); ++i)
revs.push_back(*i);
- load_graphs();
+ */
+ load_revs();
}
revision_enumerator::revision_enumerator(enumerator_callbacks & cb,
@@ -38,147 +42,188 @@ revision_enumerator::revision_enumerator
: cb(cb), app(app)
{
revision_id root;
- revs.push_back(root);
- load_graphs();
+ load_revs();
}
void
-revision_enumerator::load_graphs()
+revision_enumerator::load_revs()
{
- app.db.get_revision_ancestry(graph);
- for (multimap<revision_id, revision_id>::const_iterator i = graph.begin();
- i != graph.end(); ++i)
+ // TODO: this totally disrespects the initial and terminal stuff.
+ // It should probably be integrated into the toposort code itself.
+ vector<revision_id> topo_vec;
+ toposort(topo_vec, app.db);
+ for (vector<revision_id>::const_iterator r = topo_vec.begin();
+ r != topo_vec.end(); r++)
{
- inverse_graph.insert(make_pair(i->second, i->first));
+ if (null_id(*r))
+ continue;
+ topo_revs.push_back(*r);
}
}
-bool
-revision_enumerator::all_parents_enumerated(revision_id const & child)
-{
- typedef multimap<revision_id, revision_id>::const_iterator ci;
- pair<ci,ci> range = inverse_graph.equal_range(child);
- for (ci i = range.first; i != range.second; ++i)
- {
- if (i->first == child)
- {
- if (enumerated_nodes.find(i->second) == enumerated_nodes.end())
- return false;
- }
- }
- return true;
-}
-
bool
revision_enumerator::done()
{
- return revs.empty() && items.empty();
+ return topo_revs.empty() && items.empty();
}
-void
-revision_enumerator::step()
+void
+revision_enumerator::process_bunch()
{
- while (!done())
+ // we build up a set of files and revs to send
+ vector<revision_id> bunch_revs;
+ set<file_id> bunch_files;
+ multimap<file_id, file_id> bunch_file_deltas;
+
+ // files that should be sent first
+ set<file_id> top_files;
+ // files that will be sent either as full files are as the dst of deltas
+ set<file_id> dst_files;
+
+ while (bunch_revs.size() < 100 && !topo_revs.empty())
{
- if (items.empty() && !revs.empty())
+ revision_id r = topo_revs.front();
+ topo_revs.pop_front();
+ if (!cb.process_this_rev(r))
+ continue;
+
+ bunch_revs.push_back(r);
+
+ revision_set rs;
+ app.db.get_revision(r, rs);
+ for (edge_map::const_iterator i = rs.edges.begin();
+ i != rs.edges.end(); ++i)
{
- revision_id r = revs.front();
- revs.pop_front();
-
- // It's possible we've enumerated this node elsewhere since last
- // time around. Cull rather than reprocess.
- if (enumerated_nodes.find(r) != enumerated_nodes.end())
- continue;
-
- if (!all_parents_enumerated(r))
+ cset const & cs = edge_changes(i);
+
+ // Queue up all the file-adds
+ for (map<split_path, file_id>::const_iterator fa = cs.files_added.begin();
+ fa != cs.files_added.end(); ++fa)
{
- revs.push_back(r);
- continue;
+ if (cb.queue_this_file(fa->second.inner()))
+ {
+ dst_files.insert(fa->second);
+ top_files.insert(fa->second);
+ bunch_files.insert(fa->second);
+ }
}
-
- if (terminal_nodes.find(r) == terminal_nodes.end())
+
+ // Queue up all the file-deltas
+ for (map<split_path, std::pair<file_id, file_id> >::const_iterator fd
+ = cs.deltas_applied.begin();
+ fd != cs.deltas_applied.end(); ++fd)
{
- typedef multimap<revision_id, revision_id>::const_iterator ci;
- pair<ci,ci> range = graph.equal_range(r);
- for (ci i = range.first; i != range.second; ++i)
+ if (cb.queue_this_file(fd->second.second.inner()))
{
- if (i->first == r)
- if (enumerated_nodes.find(i->first) == enumerated_nodes.end())
- revs.push_back(i->second);
+ if (dst_files.find(fd->second.first) == dst_files.end())
+ {
+ top_files.insert(fd->second.first);
+ }
+
+ bunch_file_deltas.insert(make_pair(fd->second.first,
+ fd->second.second));
+ dst_files.insert(fd->second.second);
}
}
+ }
+ }
- enumerated_nodes.insert(r);
+ // XXX required?
+ set<file_id> sent_files;
- if (null_id(r))
- continue;
+ // now we can queue up the file items in order.
+ for (set<file_id>::const_iterator t = top_files.begin();
+ t != top_files.end(); t++)
+ {
+ if (sent_files.find(*t) != sent_files.end())
+ {
+ L(FL("already sent top_file %s") % t->inner()());
+ continue;
+ }
- if (cb.process_this_rev(r))
- {
- L(FL("revision_enumerator::step expanding "
- "contents of rev '%d'\n") % r);
+ L(FL("top_file %s") % t->inner()());
- revision_set rs;
- app.db.get_revision(r, rs);
- for (edge_map::const_iterator i = rs.edges.begin();
- i != rs.edges.end(); ++i)
+ if (bunch_files.find(*t) != bunch_files.end())
+ {
+ // a full file to send.
+ enumerator_item item;
+ item.tag = enumerator_item::fdata;
+ item.ident_a = t->inner();
+ items.push_back(item);
+ sent_files.insert(*t);
+ L(FL("send full_file %s") % t->inner()());
+ }
+
+ // XXX: doing BFS now, should try DFS too.
+ deque<file_id> frontier;
+ frontier.push_back(*t);
+
+ while (!frontier.empty())
+ {
+ file_id f = frontier.front();
+ frontier.pop_front();
+
+ L(FL("frontier %s") % f.inner()());
+
+ for (multimap<file_id,file_id>::const_iterator
+ d = bunch_file_deltas.lower_bound(f);
+ d != bunch_file_deltas.upper_bound(f);
+ d++)
+ {
+ if (sent_files.find(d->second) != sent_files.end())
{
- cset const & cs = edge_changes(i);
-
- // Queue up all the file-adds
- for (map<split_path, file_id>::const_iterator fa = cs.files_added.begin();
- fa != cs.files_added.end(); ++fa)
- {
- if (cb.queue_this_file(fa->second.inner()))
- {
- enumerator_item item;
- item.tag = enumerator_item::fdata;
- item.ident_a = fa->second.inner();
- items.push_back(item);
- }
- }
-
- // Queue up all the file-deltas
- for (map<split_path, std::pair<file_id, file_id> >::const_iterator fd
- = cs.deltas_applied.begin();
- fd != cs.deltas_applied.end(); ++fd)
- {
- if (cb.queue_this_file(fd->second.second.inner()))
- {
- enumerator_item item;
- item.tag = enumerator_item::fdelta;
- item.ident_a = fd->second.first.inner();
- item.ident_b = fd->second.second.inner();
- items.push_back(item);
- }
- }
+ L(FL("already sent delta %s") % d->second.inner()());
+ continue;
}
-
- // Queue up the rev itself
- {
- enumerator_item item;
- item.tag = enumerator_item::rev;
- item.ident_a = r.inner();
- items.push_back(item);
- }
+ sent_files.insert(d->second);
+ frontier.push_back(d->second);
+
+ enumerator_item item;
+ item.tag = enumerator_item::fdelta;
+ item.ident_a = d->first.inner();
+ item.ident_b = d->second.inner();
+ items.push_back(item);
+ L(FL("file_delta %s->%s") % d->first.inner()() % d->second.inner()());
}
-
- // Queue up some or all of the rev's certs
- vector<hexenc<id> > hashes;
- app.db.get_revision_certs(r, hashes);
- for (vector<hexenc<id> >::const_iterator i = hashes.begin();
- i != hashes.end(); ++i)
+ }
+ }
+
+ // and the revs
+ for (vector<revision_id>::const_iterator r = bunch_revs.begin();
+ r != bunch_revs.end(); r++)
+ {
+ enumerator_item item;
+ item.tag = enumerator_item::rev;
+ item.ident_a = r->inner();
+ items.push_back(item);
+
+ // Queue up some or all of the rev's certs
+ vector<hexenc<id> > hashes;
+ app.db.get_revision_certs(*r, hashes);
+ for (vector<hexenc<id> >::const_iterator i = hashes.begin();
+ i != hashes.end(); ++i)
+ {
+ if (cb.queue_this_cert(*i))
{
- if (cb.queue_this_cert(*i))
- {
- enumerator_item item;
- item.tag = enumerator_item::cert;
- item.ident_a = *i;
- items.push_back(item);
- }
+ enumerator_item item;
+ item.tag = enumerator_item::cert;
+ item.ident_a = *i;
+ items.push_back(item);
}
}
+ }
+}
+void
+revision_enumerator::step()
+{
+ while (!done())
+ {
+ if (items.empty() && !topo_revs.empty())
+ {
+ process_bunch();
+ }
+
if (!items.empty())
{
L(FL("revision_enumerator::step extracting item\n"));
============================================================
--- enumerator.hh b2662b4dea76a8d832663ed48342920248449f70
+++ enumerator.hh 1880dae7a6147b0ddd8064bfc4679334b520aeab
@@ -50,10 +50,8 @@ revision_enumerator
app_state & app;
std::set<revision_id> terminal_nodes;
std::set<revision_id> enumerated_nodes;
- std::deque<revision_id> revs;
std::deque<enumerator_item> items;
- std::multimap<revision_id, revision_id> graph;
- std::multimap<revision_id, revision_id> inverse_graph;
+ std::deque<revision_id> topo_revs;
revision_enumerator(enumerator_callbacks & cb,
app_state & app,
@@ -61,8 +59,8 @@ revision_enumerator
std::set<revision_id> const & terminal);
revision_enumerator(enumerator_callbacks & cb,
app_state & app);
- void load_graphs();
- bool all_parents_enumerated(revision_id const & child);
+ void load_revs();
+ void process_bunch();
void step();
bool done();
};
============================================================
--- lua.cc 78722201fdc513bfee248ce6b30b1b1ae593250e
+++ lua.cc 8284c5010bee38f15141c3e60eeeeb7c288ee20c
@@ -1,4 +1,5 @@
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
@@ -1382,6 +1383,25 @@ lua_hooks::hook_get_linesep_conv(file_pa
return ll.ok();
}
+bool
+lua_hooks::hook_validate_commit_message(std::string const & message,
+ std::string const & new_manifest_text,
+ bool & validated,
+ std::string & reason)
+{
+ validated = true;
+ return Lua(st)
+ .func("validate_commit_message")
+ .push_str(message)
+ .push_str(new_manifest_text)
+ .call(2, 2)
+ .extract_str(reason)
+ // XXX When validated, the extra returned string is superfluous.
+ .pop()
+ .extract_bool(validated)
+ .ok();
+}
+
bool
lua_hooks::hook_note_commit(revision_id const & new_id,
revision_data const & rdat,
============================================================
--- lua.hh 0d1c63ed6c7b36665ad92780ed88afa1edff3194
+++ lua.hh a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea
@@ -106,6 +106,12 @@ public:
bool hook_get_linesep_conv(file_path const & p,
std::string & db, std::string & ext);
+ // validation hooks
+ bool hook_validate_commit_message(std::string const & message,
+ std::string const & new_manifest_text,
+ bool & validated,
+ std::string & reason);
+
// notification hooks
bool hook_note_commit(revision_id const & new_id,
revision_data const & rdat,
============================================================
--- monotone.1 f7f22f2d6e5bebf0d526d15651869113fe9c6ead
+++ monotone.1 6a829e2dda9696f2b3949e266a24ed560c33bf71
@@ -77,6 +77,10 @@ List files in revision's manifest, but n
\fBlist missing \fI[<pathname...]\fP
List files in revision's manifest, but not in workspace.
.TP
+\fBlist changed \fI[<pathname...]\fP
+List files in workspace that have changed compared to the base
+revision.
+.TP
\fBfdata\fP \fI<id>\fP
Write file data packet to stdout.
.TP
============================================================
--- monotone.spec 31854929161128485e8ca1cb1e16d2b0d2bab8a1
+++ monotone.spec b00e73feb017514c7dd84e700e9dd539585ecf57
@@ -1,6 +1,6 @@ Name: monotone
Summary: monotone is a distributed version control tool
Name: monotone
-Version: 0.26pre1
+Version: 0.26pre2
Release: 1
License: GPL
Group: Development/Tools
@@ -63,6 +63,9 @@ fi
%changelog
+* Sat Feb 11 2006 nathaniel smith <njs@pobox.com>
+- 0.26pre2 release
+
* Thu Jan 8 2006 nathaniel smith <njs@pobox.com>
- 0.26pre1 release
============================================================
--- monotone.texi 59eb4911052af4a3a1743caf529acfe14dad092b
+++ monotone.texi 355d07f84caee318dd69f37ff6274842ca2d2c70
@@ -2708,6 +2708,7 @@ @section Restrictions
@item @command{list unknown}
@item @command{list ignored}
@item @command{list missing}
+@item @command{list changed}
@end itemize
Including either the old or new name of a renamed file or directory will
@@ -4406,6 +4407,22 @@ @section Informative
Specifying only the pathname "." will restrict the search for missing
files to the current subdirectory of the workspace.
+@item monotone list changed
+@itemx monotone list changed @var{pathname...}
+
+This command lists all files in your workspace that have changed
+compared to the base revision, including files that are dropped, added
+or renamed.
+
+Specifying pathnames to the @command{list changed} command restricts
+the set of paths that are checked for changes. Files not included in the
+specified set of pathnames will not be listed.
+
+From within a subdirectory of the workspace the @command{list
+changed} command will, by default, search the entire workspace.
+Specifying only the pathname "." will restrict the search for known
+files to the current subdirectory of the workspace.
+
@end ftable
@@ -6350,8 +6367,8 @@ @subsection Trust Evaluation Hooks
if t == nil then return false end
- if (name ~= "ancestor" and table.getn(t) >= 1)
- or (name == "ancestor" and table.getn(t) >= 2)
+ if (name ~= "branch" and table.getn(t) >= 1)
+ or (name == "branch" and table.getn(t) >= 2)
then
return true
else
@@ -6363,10 +6380,10 @@ @subsection Trust Evaluation Hooks
In this example, any revision certificate is trusted if it is signed
by at least one of three ``trusted'' keys, unless it is an
-@code{ancestor} certificate, in which case it must be signed by
+@code{branch} certificate, in which case it must be signed by
@emph{two} or more trusted keys. This is one way of requiring that
-ancestry assertions go through an extra ``reviewer'' before they are
-accepted.
+the revision has been approved by an extra ``reviewer'' who used the
+@code{approve} command.
@item accept_testresult_change (@var{old_results}, @var{new_results})
@@ -6673,6 +6690,25 @@ @subsection Attribute Handling
@end ftable
+@subsection Validation Hooks
+
+If there is a policy decision to make, Monotone defines certain hooks to
+allow a client to validate or reject certain behaviors.
+
+@ftable @code
+@item validate_commit_message (@var{message}, @var{changeset_text})
+
+This hook is called after the user has entered his/her commit message.
+@var{message} is the commit message that the user has entered and
+@var{changeset_text} is the full text of the changes for this revision,
+which can be parsed with the parse_basic_io function. If the hook finds the
+commit message satisfactory, it can return @code{true, ""}. If it finds
+fault, then it can return @code{false, reason} where @var{reason} is the
+reason the message was rejected. By default, this hook rejects empty log
+messages.
+
+@end ftable
+
@page
@node Additional Lua Functions
@section Additional Lua Functions
@@ -7547,6 +7583,12 @@ @subsection Commands
List files in revision's manifest, but not in workspace.
@comment TROFF INPUT: .TP
+@item @b{list changed} @i{[<pathname>...]}
+@itemx @b{ls changed} @i{[<pathname>...]}
+List files in workspace that have changed compared to the base
+revision.
+@comment TROFF INPUT: .TP
+
@item @b{fdata} @i{<id>}
Write file data packet to stdout.
@comment TROFF INPUT: .TP
============================================================
--- netsync.cc 8c4cbdeb2898f87f5f74457e7148a4cc0afde674
+++ netsync.cc 8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa
@@ -591,15 +591,12 @@ session::note_file_delta(file_id const &
{
if (role == sink_role)
return;
- file_data fd1, fd2;
- delta del;
- id fid1, fid2;
- decode_hexenc(src.inner(), fid1);
- decode_hexenc(dst.inner(), fid2);
- app.db.get_file_version(src, fd1);
- app.db.get_file_version(dst, fd2);
- diff(fd1.inner(), fd2.inner(), del);
- queue_delta_cmd(file_item, fid1, fid2, del);
+ file_delta del;
+ app.db.get_file_delta(dst, src, del);
+ id src_id, dst_id;
+ decode_hexenc(src.inner(), src_id);
+ decode_hexenc(dst.inner(), dst_id);
+ queue_delta_cmd(file_item, src_id, dst_id, del.inner());
file_items_sent.insert(dst);
}
@@ -1318,13 +1315,18 @@ session::process_anonymous_cmd(protocol_
i != branchnames.end(); i++)
{
if (their_matcher(*i))
- if (our_matcher(*i) && app.lua.hook_get_netsync_read_permitted(*i))
- ok_branches.insert(utf8(*i));
- else
+ if (!our_matcher(*i))
{
+ error((F("not serving branch '%s'") % *i).str());
+ return true;
+ }
+ else if (!app.lua.hook_get_netsync_read_permitted(*i))
+ {
error((F("anonymous access to branch '%s' denied by server") % *i).str());
return true;
}
+ else
+ ok_branches.insert(utf8(*i));
}
P(F("allowed anonymous read permission for '%s' excluding '%s'\n")
@@ -1410,15 +1412,22 @@ session::process_auth_cmd(protocol_role
{
if (their_matcher(*i))
{
- if (our_matcher(*i) && app.lua.hook_get_netsync_read_permitted(*i, their_id))
- ok_branches.insert(utf8(*i));
- else
+ if (!our_matcher(*i))
{
+ error((F("not serving branch '%s'") % *i).str());
+ return true;
+
+ }
+ else if (!app.lua.hook_get_netsync_read_permitted(*i, their_id))
+ {
W(F("denied '%s' read permission for '%s' excluding '%s' because of branch '%s'\n")
% their_id % their_include_pattern % their_exclude_pattern % *i);
+
error((F("access to branch '%s' denied by server") % *i).str());
return true;
}
+ else
+ ok_branches.insert(utf8(*i));
}
}
@@ -2563,102 +2572,138 @@ serve_connections(protocol_role role,
#else
bool use_ipv6=false;
#endif
- Netxx::Address addr(use_ipv6);
+ // This will be true when we try to bind while using IPv6. See comments
+ // further down.
+ bool try_again=false;
- if (!app.bind_address().empty())
- addr.add_address(app.bind_address().c_str(), default_port);
- else
- addr.add_all_addresses (default_port);
+ do
+ {
+ try
+ {
+ try_again = false;
+ Netxx::Address addr(use_ipv6);
- Netxx::StreamServer server(addr, timeout);
- const char *name = addr.get_name();
- P(F("beginning service on %s : %s\n")
- % (name != NULL ? name : "all interfaces")
- % lexical_cast<string>(addr.get_port()));
+ if (!app.bind_address().empty())
+ addr.add_address(app.bind_address().c_str(), default_port);
+ else
+ addr.add_all_addresses (default_port);
+
+ // If se use IPv6 and the initiasation 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.
+ // On failure, Netxx::NetworkException is thrown, and we catch
+ // it further down.
+ try_again=use_ipv6;
+
+ Netxx::StreamServer server(addr, timeout);
+
+ // If we came this far, whatever we used (IPv6 or IPv4) was
+ // accepted, so we don't need to try again any more.
+ try_again=false;
+
+ const char *name = addr.get_name();
+ P(F("beginning service on %s : %s\n")
+ % (name != NULL ? name : "all interfaces")
+ % lexical_cast<string>(addr.get_port()));
- map<Netxx::socket_type, shared_ptr<session> > sessions;
- set<Netxx::socket_type> armed_sessions;
+ map<Netxx::socket_type, shared_ptr<session> > sessions;
+ set<Netxx::socket_type> armed_sessions;
- shared_ptr<transaction_guard> guard;
+ shared_ptr<transaction_guard> guard;
- while (true)
- {
- probe.clear();
- armed_sessions.clear();
+ while (true)
+ {
+ probe.clear();
+ armed_sessions.clear();
- if (sessions.size() >= session_limit)
- W(F("session limit %d reached, some connections "
- "will be refused\n") % session_limit);
- else
- probe.add(server);
+ if (sessions.size() >= session_limit)
+ W(F("session limit %d reached, some connections "
+ "will be refused\n") % session_limit);
+ else
+ probe.add(server);
- arm_sessions_and_calculate_probe(probe, sessions, armed_sessions);
+ arm_sessions_and_calculate_probe(probe, sessions, armed_sessions);
- L(FL("i/o probe with %d armed\n") % armed_sessions.size());
- Netxx::Probe::result_type res = probe.ready(sessions.empty() ? forever
- : (armed_sessions.empty() ? timeout
- : instant));
- Netxx::Probe::ready_type event = res.second;
- Netxx::socket_type fd = res.first;
+ L(FL("i/o probe with %d armed\n") % armed_sessions.size());
+ Netxx::Probe::result_type res = probe.ready(sessions.empty() ? forever
+ : (armed_sessions.empty() ? timeout
+ : instant));
+ Netxx::Probe::ready_type event = res.second;
+ Netxx::socket_type fd = res.first;
- if (!guard)
- guard = shared_ptr<transaction_guard>(new transaction_guard(app.db));
+ if (!guard)
+ guard = shared_ptr<transaction_guard>(new transaction_guard(app.db));
- I(guard);
+ I(guard);
- if (fd == -1)
- {
- if (armed_sessions.empty())
- L(FL("timed out waiting for I/O (listening on %s : %s)\n")
- % addr.get_name() % lexical_cast<string>(addr.get_port()));
- }
+ if (fd == -1)
+ {
+ if (armed_sessions.empty())
+ L(FL("timed out waiting for I/O (listening on %s : %s)\n")
+ % addr.get_name() % lexical_cast<string>(addr.get_port()));
+ }
- // we either got a new connection
- else if (fd == server)
- handle_new_connection(addr, server, timeout, role,
- include_pattern, exclude_pattern,
- sessions, app);
+ // we either got a new connection
+ else if (fd == server)
+ handle_new_connection(addr, server, timeout, role,
+ include_pattern, exclude_pattern,
+ sessions, app);
- // or an existing session woke up
- else
- {
- map<Netxx::socket_type, shared_ptr<session> >::iterator i;
- i = sessions.find(fd);
- if (i == sessions.end())
- {
- L(FL("got woken up for action on unknown fd %d\n") % fd);
- }
- else
- {
- shared_ptr<session> sess = i->second;
- bool live_p = true;
+ // or an existing session woke up
+ else
+ {
+ map<Netxx::socket_type, shared_ptr<session> >::iterator i;
+ i = sessions.find(fd);
+ if (i == sessions.end())
+ {
+ L(FL("got woken up for action on unknown fd %d\n") % fd);
+ }
+ else
+ {
+ shared_ptr<session> sess = i->second;
+ bool live_p = true;
- if (event & Netxx::Probe::ready_read)
- handle_read_available(fd, sess, sessions,
- armed_sessions, live_p);
+ if (event & Netxx::Probe::ready_read)
+ handle_read_available(fd, sess, sessions,
+ armed_sessions, live_p);
- if (live_p && (event & Netxx::Probe::ready_write))
- handle_write_available(fd, sess, sessions, live_p);
+ if (live_p && (event & Netxx::Probe::ready_write))
+ handle_write_available(fd, sess, sessions, live_p);
- if (live_p && (event & Netxx::Probe::ready_oobd))
+ if (live_p && (event & Netxx::Probe::ready_oobd))
+ {
+ P(F("got OOB from peer %s, disconnecting\n")
+ % sess->peer_id);
+ sessions.erase(i);
+ }
+ }
+ }
+ process_armed_sessions(sessions, armed_sessions, *guard);
+ reap_dead_sessions(sessions, timeout_seconds);
+
+ if (sessions.empty())
{
- P(F("got OOB from peer %s, disconnecting\n")
- % sess->peer_id);
- sessions.erase(i);
+ // Let the guard die completely if everything's gone quiet.
+ guard->commit();
+ guard.reset();
}
}
}
- process_armed_sessions(sessions, armed_sessions, *guard);
- reap_dead_sessions(sessions, timeout_seconds);
-
- if (sessions.empty())
+ catch (Netxx::NetworkException &e)
{
- // Let the guard die completely if everything's gone quiet.
- guard->commit();
- guard.reset();
+ // If we tried with IPv6 and failed, we want to try again using IPv4.
+ if (try_again)
+ {
+ use_ipv6 = false;
+ }
+ // In all other cases, just rethrow the exception.
+ else
+ throw;
}
}
+ while(try_again);
}
============================================================
--- paths.cc 227025632497d6849fc4946feeded4d7980f7008
+++ paths.cc c13e9b0c44a37a70e6c7e6d5c8b8869e363ccab9
@@ -302,6 +302,7 @@ file_path::split(split_path & sp) const
}
}
+template <>
void dump(split_path const & sp, std::string & out)
{
std::ostringstream oss;
@@ -473,7 +474,6 @@ find_and_go_to_workspace(system_path con
bool
find_and_go_to_workspace(system_path const & search_root)
{
- // unimplemented
fs::path root(search_root.as_external(), fs::native);
fs::path bookdir(bookkeeping_root.as_external(), fs::native);
fs::path current(fs::initial_path());
============================================================
--- paths.hh 727b9cfba7c9d150dfd7144d0d38744beb8dda7f
+++ paths.hh 054a74b153b42a34140f2776f468bf79c844fa64
@@ -115,7 +115,7 @@ null_name(path_component pc)
return pc == the_null_component;
}
-void dump(split_path const & sp, std::string & out);
+template <> void dump(split_path const & sp, std::string & out);
// It's possible this will become a proper virtual interface in the future,
// but since the implementation is exactly the same in all cases, there isn't
============================================================
--- po/sv.po e347bfacd741eafd3202feda54aa54e24b3a7bfb
+++ po/sv.po 754e90276863a8b1a53cad17c575bb93ffcdd5b4
@@ -144,8 +144,8 @@ msgstr ""
msgstr ""
"Project-Id-Version: monotone 0.26pre1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-01-28 23:06+0100\n"
-"PO-Revision-Date: 2006-01-28 23:59+0100\n"
+"POT-Creation-Date: 2006-02-11 08:32+0100\n"
+"PO-Revision-Date: 2006-02-11 08:43+0100\n"
"Last-Translator: Joel Rosdahl <joel@rosdahl.net>\n"
"Language-Team: Richard Levitte <richard@levitte.org>\n"
"MIME-Version: 1.0\n"
@@ -283,39 +283,39 @@ msgstr "flera grencert funna för revisi
"multiple branch certs found for revision %s, please provide a branch name"
msgstr "flera grencert funna för revision %s, var god ange en gren"
-#: commands.cc:159
+#: commands.cc:160
#, c-format
msgid "command '%s' has multiple ambiguous expansions:\n"
msgstr "kommandot '%s' har mer än en betydelse:\n"
-#: commands.cc:202
+#: commands.cc:203
msgid "commands:"
msgstr "kommandon:"
-#: commands.cc:253
+#: commands.cc:254
#, c-format
msgid "unknown command '%s'\n"
msgstr "okänt kommando '%s'\n"
-#: commands.cc:300
+#: commands.cc:301
#, c-format
msgid "pid file '%s' already exists"
msgstr "pid-filen '%s' finns redan"
-#: commands.cc:324 commands.cc:1294 commands.cc:1364 commands.cc:1739
-#: commands.cc:2648 commands.cc:3192 commands.cc:3423 commands.cc:3462
+#: commands.cc:325 commands.cc:1295 commands.cc:1365 commands.cc:1801
+#: commands.cc:2722 commands.cc:3266 commands.cc:3497 commands.cc:3536
msgid "informative"
msgstr "informativ"
-#: commands.cc:324
+#: commands.cc:325
msgid "command [ARGS...]"
msgstr "kommandon [ARGUMENT...]"
-#: commands.cc:324
+#: commands.cc:325
msgid "display command help"
msgstr "skriv ut hjälptext"
-#: commands.cc:403
+#: commands.cc:404
msgid ""
"Enter a description of this change.\n"
"Lines beginning with `MT:' are removed automatically.\n"
@@ -323,16 +323,16 @@ msgstr ""
"Mata in en beskrivning av denna ändring.\n"
"Rader som börjar med 'MT:' kommer att tas bort automatiskt.\n"
-#: commands.cc:410
+#: commands.cc:411
#, c-format
msgid "edit of log message failed"
msgstr "redigering av loggmeddelandet misslyckades"
-#: commands.cc:419
+#: commands.cc:420
msgid "note: "
msgstr "obs: "
-#: commands.cc:420
+#: commands.cc:421
#, c-format
msgid ""
"branch '%s' has multiple heads\n"
@@ -341,59 +341,59 @@ msgstr ""
"grenen '%s' har mer än ett löv\n"
"kanske borde du överväga 'monotone merge'"
-#: commands.cc:480 commands.cc:736 commands.cc:1382 commands.cc:1457
-#: commands.cc:1823 commands.cc:2698 commands.cc:2726 commands.cc:2729
-#: commands.cc:2865 commands.cc:3445
+#: 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
#, c-format
msgid "no such revision '%s'"
msgstr "det finns ingen revision med identiteten '%s'"
-#: commands.cc:487
+#: commands.cc:488
#, c-format
msgid "expanding selection '%s'\n"
msgstr "expanderar valet '%s'\n"
-#: commands.cc:495
+#: commands.cc:496
#, c-format
msgid "no match for selection '%s'"
msgstr "det finns inget som matchar '%s'"
-#: commands.cc:498
+#: commands.cc:499
#, c-format
msgid "selection '%s' has multiple ambiguous expansions: \n"
msgstr "valet '%s' har mer än en möjlig betydelse: \n"
-#: commands.cc:505
+#: commands.cc:506
#, c-format
msgid "expanded to '%s'\n"
msgstr "expanderar till '%s'\n"
-#: commands.cc:516
+#: commands.cc:517
#, c-format
msgid "non-hex digits in id"
msgstr "något tecken i identiteten är inte hexadecimalt"
-#: commands.cc:525
+#: commands.cc:526
#, c-format
msgid "partial id '%s' does not have an expansion"
msgstr "den partiella identiteten '%s' matchar inte befintliga identiteter"
-#: commands.cc:528
+#: commands.cc:529
#, c-format
msgid "partial id '%s' has multiple ambiguous expansions:\n"
msgstr "den partiella identiteten '%s' har mer än en uttydning:\n"
-#: commands.cc:535
+#: commands.cc:536
#, c-format
msgid "expanded partial id '%s' to '%s'\n"
msgstr "expanderade partiell identitet '%s' till '%s'\n"
-#: commands.cc:562 netsync.cc:1709
+#: commands.cc:563 netsync.cc:1722
#, c-format
msgid "no public key '%s' found in database"
msgstr "den publika nyckeln '%s' finns inte i databasen"
-#: commands.cc:572
+#: commands.cc:573
#, c-format
msgid ""
"Key : %s\n"
@@ -406,87 +406,87 @@ msgstr ""
"Namn : %s\n"
"Värde : %s\n"
-#: commands.cc:606
+#: commands.cc:607
msgid "ok"
msgstr "ok"
-#: commands.cc:609
+#: commands.cc:610
msgid "bad"
msgstr "felaktig"
-#: commands.cc:612
+#: commands.cc:613
msgid "unknown"
msgstr "okänd"
-#: commands.cc:699
+#: commands.cc:700
#, c-format
msgid "(*) - only in %s/"
msgstr "(*) - enbart i %s/"
-#: commands.cc:722
+#: commands.cc:723
#, c-format
msgid "no keys found\n"
msgstr "hittade inga nycklar\n"
-#: commands.cc:724
+#: commands.cc:725
#, c-format
msgid "no keys found matching '%s'\n"
msgstr "hittade inga nycklar som matchar '%s'\n"
-#: commands.cc:742
+#: commands.cc:743
#, c-format
msgid "revision %s already has children. We cannot kill it."
msgstr "revisionen %s har barn. Vi kan inte ta bort den."
-#: commands.cc:882 commands.cc:906 commands.cc:943 commands.cc:964
-#: commands.cc:1000
+#: commands.cc:883 commands.cc:907 commands.cc:944 commands.cc:965
+#: commands.cc:1001
msgid "key and cert"
msgstr "nyckel och cert"
-#: commands.cc:882 commands.cc:906 commands.cc:943
+#: commands.cc:883 commands.cc:907 commands.cc:944
msgid "KEYID"
msgstr "NYCKELID"
-#: commands.cc:882
+#: commands.cc:883
msgid "generate an RSA key-pair"
msgstr "skapa ett RSA-nyckelpar"
-#: commands.cc:897
+#: commands.cc:898
#, c-format
msgid "key '%s' already exists"
msgstr "nyckeln '%s' finns redan"
-#: commands.cc:900
+#: commands.cc:901
#, c-format
msgid "generating key-pair '%s'"
msgstr "skapar nyckelparet '%s'"
-#: commands.cc:902
+#: commands.cc:903
#, c-format
msgid "storing key-pair '%s' in %s/"
msgstr "lagrar nyckelparet '%s' i %s/"
-#: commands.cc:906
+#: commands.cc:907
msgid "drop a public and private key"
msgstr "släng publik och privat nyckel"
-#: commands.cc:920
+#: commands.cc:921
#, c-format
msgid "dropping public key '%s' from database\n"
msgstr "tar bort den publika nyckeln '%s' ur databasen\n"
-#: commands.cc:930
+#: commands.cc:931
#, c-format
msgid "dropping key pair '%s' from keystore\n"
msgstr "tar bort nyckelparet '%s' från nyckellagret\n"
-#: commands.cc:937
+#: commands.cc:938
#, c-format
msgid "public or private key '%s' does not exist in keystore or database"
msgstr ""
"den publika eller privata nyckeln '%s' finns inte i nyckellager eller databas"
-#: commands.cc:939
+#: commands.cc:940
#, c-format
msgid ""
"public or private key '%s' does not exist in keystore, and no database was "
@@ -495,33 +495,33 @@ msgstr ""
"den publika eller privata nyckeln '%s' finns inte i nyckellager och ingen "
"databas angavs"
-#: commands.cc:944
+#: commands.cc:945
msgid "change passphrase of a private RSA key"
msgstr "ändra lösen till en privat RSA-nyckel"
-#: commands.cc:954
+#: commands.cc:955
#, c-format
msgid "key '%s' does not exist in the keystore"
msgstr "nyckeln '%s' finns inte i nyckellagret"
-#: commands.cc:961
+#: commands.cc:962
#, c-format
msgid "passphrase changed\n"
msgstr "lösen ändrat\n"
-#: commands.cc:964
+#: commands.cc:965
msgid "REVISION CERTNAME [CERTVAL]"
msgstr "REVISION CERTNAMN [CERTVÄRDE]"
-#: commands.cc:965
+#: commands.cc:966
msgid "create a cert for a revision"
msgstr "skapa ett cert för en revision"
-#: commands.cc:1000
+#: commands.cc:1001
msgid "REVISION NAME VALUE SIGNER1 [SIGNER2 [...]]"
msgstr "REVISION NAMN VÄRDE SIGNERARE1 [SIGNERARE2 [...]]"
-#: commands.cc:1001
+#: commands.cc:1002
msgid ""
"test whether a hypothetical cert would be trusted\n"
"by current settings"
@@ -529,7 +529,7 @@ msgstr ""
"kontrollera ifall ett hypotetiskt cert skulle vara pålitligt\n"
"enligt nuvarande inställningar"
-#: commands.cc:1034
+#: commands.cc:1035
#, c-format
msgid ""
"if a cert on: %s\n"
@@ -544,101 +544,101 @@ msgstr ""
"signerades av: %s\n"
"skulle det vara: %s\n"
-#: commands.cc:1043
+#: commands.cc:1044
msgid "trusted"
msgstr "pålitligt"
-#: commands.cc:1043
+#: commands.cc:1044
msgid "UNtrusted"
msgstr "Opålitligt"
-#: commands.cc:1046 commands.cc:1059 commands.cc:1072 commands.cc:1089
-#: commands.cc:1140
+#: commands.cc:1047 commands.cc:1060 commands.cc:1073 commands.cc:1090
+#: commands.cc:1141
msgid "review"
msgstr "granskning"
-#: commands.cc:1046
+#: commands.cc:1047
msgid "REVISION TAGNAME"
msgstr "REVISION TAGNAMN"
-#: commands.cc:1047
+#: commands.cc:1048
msgid "put a symbolic tag cert on a revision version"
msgstr "sätt ett symboliskt tagg-cert på en revision"
-#: commands.cc:1059
+#: commands.cc:1060
msgid "ID (pass|fail|true|false|yes|no|1|0)"
msgstr "ID (pass|fail|true|false|yes|no|1|0)"
-#: commands.cc:1060
+#: commands.cc:1061
msgid "note the results of running a test on a revision"
msgstr "notera ett testresultat för en revision"
-#: commands.cc:1072 commands.cc:1089
+#: commands.cc:1073 commands.cc:1090
msgid "REVISION"
msgstr "REVISION"
-#: commands.cc:1073
+#: commands.cc:1074
msgid "approve of a particular revision"
msgstr "godkänn en specifik revision"
-#: commands.cc:1084
+#: commands.cc:1085
#, c-format
msgid "need --branch argument for approval"
msgstr "för godkännande behöver en gren anges med --branch"
-#: commands.cc:1090
+#: commands.cc:1091
msgid "disapprove of a particular revision"
msgstr "underkänn en specifik revision"
-#: commands.cc:1103
+#: commands.cc:1104
#, c-format
msgid "revision '%s' has %d changesets, cannot invert\n"
msgstr "revisionen '%s' har %d föräldrar, kan inte invertera\n"
-#: commands.cc:1107
+#: commands.cc:1108
#, c-format
msgid "need --branch argument for disapproval"
msgstr "för underkännande behöver en gren anges med --branch"
-#: commands.cc:1140
+#: commands.cc:1141
msgid "REVISION [COMMENT]"
msgstr "REVISION [KOMMENTAR]"
-#: commands.cc:1141
+#: commands.cc:1142
msgid "comment on a particular revision"
msgstr "kommentera en specifik revision"
-#: commands.cc:1151
+#: commands.cc:1152
#, c-format
msgid "edit comment failed"
msgstr "misslyckades med att redigera kommentaren"
-#: commands.cc:1154
+#: commands.cc:1155
#, c-format
msgid "empty comment"
msgstr "tom kommentar"
-#: commands.cc:1167 commands.cc:1195 commands.cc:1220 commands.cc:1341
-#: commands.cc:2159 commands.cc:2278 commands.cc:2801 commands.cc:3240
+#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:1342
+#: commands.cc:2224 commands.cc:2342 commands.cc:2875 commands.cc:3314
msgid "workspace"
msgstr "arbetskopia"
-#: commands.cc:1167 commands.cc:1195 commands.cc:1294 commands.cc:2278
-#: commands.cc:2648 commands.cc:3240
+#: commands.cc:1168 commands.cc:1196 commands.cc:1295 commands.cc:2342
+#: commands.cc:2722 commands.cc:3314
msgid "[PATH]..."
msgstr "[SÖKVÄG]..."
-#: commands.cc:1168
+#: commands.cc:1169
#, fuzzy
msgid "add files to workspace"
msgstr "lägg till filer i arbetskopian"
-#: commands.cc:1196
+#: commands.cc:1197
#, fuzzy
msgid "drop files from workspace"
msgstr "överge filer i arbetskopian"
-#: commands.cc:1221
+#: commands.cc:1222
msgid ""
"SRC DEST\n"
"SRC1 [SRC2 [...]] DEST_DIR"
@@ -646,83 +646,83 @@ msgstr ""
"KÄLLA MÅL\n"
"KÄLLA1 [KÄLLA2 [...]] MÅLKATALOG"
-#: commands.cc:1223
+#: commands.cc:1224
#, fuzzy
msgid "rename entries in the workspace"
msgstr "byt namn på filer i arbetskopian"
-#: commands.cc:1248 commands.cc:1261 commands.cc:3343 commands.cc:3783
+#: commands.cc:1249 commands.cc:1262 commands.cc:3417 commands.cc:3857
msgid "debug"
msgstr "felsökning"
-#: commands.cc:1248
+#: commands.cc:1249
msgid "load file contents into db"
msgstr "ladda in filinnehållet i databasen"
-#: commands.cc:1261
+#: commands.cc:1262
msgid "<parent> <left> <right>"
msgstr "<förälder> <vänster> <höger>"
-#: commands.cc:1262
+#: commands.cc:1263
msgid "merge 3 files and output result"
msgstr "slå ihop 3 filer och skriv ut resultatet"
-#: commands.cc:1272
+#: commands.cc:1273
#, c-format
msgid "ancestor file id does not exist"
msgstr "förälderns filidentitet finns inte"
-#: commands.cc:1275
+#: commands.cc:1276
#, c-format
msgid "left file id does not exist"
msgstr "vänster fils identitet finns inte"
-#: commands.cc:1278
+#: commands.cc:1279
#, c-format
msgid "right file id does not exist"
msgstr "höger fils identitet finns inte"
-#: commands.cc:1289
+#: commands.cc:1290
#, c-format
msgid "merge failed"
msgstr "ihopslagningen misslyckades"
-#: commands.cc:1294
+#: commands.cc:1295
#, fuzzy
msgid "show status of workspace"
msgstr "visa arbetskopians status"
-#: commands.cc:1341
+#: commands.cc:1342
msgid "[PATH]"
msgstr "[SÖKVÄG]"
-#: commands.cc:1342
+#: commands.cc:1343
msgid "calculate identity of PATH or stdin"
msgstr "räkna ut identiteten för SÖKVÄG eller stdin"
-#: commands.cc:1365
+#: commands.cc:1366
msgid "FILENAME"
msgstr "FILNAMN"
-#: commands.cc:1366
+#: commands.cc:1367
msgid "write file from database to stdout"
msgstr "skriv ut angiven fil från databasen"
-#: commands.cc:1394 commands.cc:1396 commands.cc:3454
+#: commands.cc:1395 commands.cc:1397 commands.cc:3528
#, c-format
msgid "no file '%s' found in revision '%s'\n"
msgstr "filen '%s' finns inte i revisionen '%s'\n"
-#: commands.cc:1408 commands.cc:1527 commands.cc:3002 commands.cc:3051
-#: commands.cc:3140 commands.cc:3147 commands.cc:3696
+#: commands.cc:1409 commands.cc:1531 commands.cc:3076 commands.cc:3125
+#: commands.cc:3214 commands.cc:3221 commands.cc:3770
msgid "tree"
msgstr "träd"
-#: commands.cc:1408
+#: commands.cc:1409
msgid "[DIRECTORY]\n"
msgstr "[KATALOG]\n"
-#: commands.cc:1409
+#: commands.cc:1410
msgid ""
"check out a revision from database into directory.\n"
"If a revision is given, that's the one that will be checked out.\n"
@@ -734,62 +734,62 @@ msgstr ""
"kommer lövet i grenen (implicit eller angiven) att hämtas. Om\n"
"ingen katalog anges kommer grenens namn att användas som katalognamn."
-#: commands.cc:1426 commands.cc:1445
+#: commands.cc:1429 commands.cc:1448
#, c-format
msgid "need --branch argument for branch-based checkout"
msgstr "--branch behövs för att kunna hämta en revision med given gren"
-#: commands.cc:1439
+#: commands.cc:1442
#, c-format
msgid "checkout directory '%s' already exists"
msgstr "arbetskatalogen '%s' finns redan"
-#: commands.cc:1448 commands.cc:1540 commands.cc:3015 commands.cc:3085
-#: commands.cc:3088
+#: commands.cc:1451 commands.cc:1544 commands.cc:3089 commands.cc:3159
+#: commands.cc:3162
#, c-format
msgid "branch '%s' is empty\n"
msgstr "grenen '%s' är tom\n"
-#: commands.cc:1449
+#: commands.cc:1452
#, c-format
msgid "branch %s has multiple heads"
msgstr "grenen %s har flera löv"
-#: commands.cc:1475
+#: commands.cc:1478
#, c-format
msgid "revision %s is not a member of branch %s\n"
msgstr "revisionen %s är inte med i grenen %s\n"
-#: commands.cc:1509
+#: commands.cc:1512
#, c-format
msgid "no file %s found in database for %s"
msgstr "det finns ingen fil %s för %s i databasen"
-#: commands.cc:1527
+#: commands.cc:1531
msgid "show unmerged head revisions of branch"
msgstr "visa ej ihopslagna lövrevisioner i grenen"
-#: commands.cc:1535 commands.cc:3011
+#: commands.cc:1539 commands.cc:3085
#, c-format
msgid "please specify a branch, with --branch=BRANCH"
msgstr "var god ange en gren med --branch=GREN"
-#: commands.cc:1542
+#: commands.cc:1546
#, c-format
msgid "branch '%s' is currently merged:\n"
msgstr "grenen '%s' har för tillfället ett löv:\n"
-#: commands.cc:1544
+#: commands.cc:1548
#, c-format
msgid "branch '%s' is currently unmerged:\n"
msgstr "grenen '%s' har för tillfället mer än ett löv:\n"
-#: commands.cc:1583
+#: commands.cc:1587
#, c-format
msgid "no epoch for branch %s\n"
msgstr "ingen epok i grenen %s\n"
-#: commands.cc:1740
+#: commands.cc:1802
msgid ""
"certs ID\n"
"keys [PATTERN]\n"
@@ -800,7 +800,8 @@ msgid ""
"known\n"
"unknown\n"
"ignored\n"
-"missing"
+"missing\n"
+"changed"
msgstr ""
"certs ID\n"
"keys [MÖNSTER]\n"
@@ -811,162 +812,162 @@ msgstr ""
"known\n"
"unknown\n"
"ignored\n"
-"missing"
+"missing\n"
+"changed"
-#: commands.cc:1750
-#, fuzzy
+#: commands.cc:1813
msgid ""
-"show database objects, or the current workspace manifest,\n"
-"or unknown, intentionally ignored, or missing state files"
+"show database objects, or the current workspace manifest, or known,\n"
+"unknown, intentionally ignored, missing, or changed state files"
msgstr ""
-"visa databasobjekten, arbetskopians manifest, okända filer, medvetet\n"
-"ignorerade filer eller saknade tillståndsfiler"
+"visa databasobjekten, arbetskopians manifest, okända filer, kända\n"
+"filer, medvetet ignorerade filer, saknade filer eller ändrade filer"
-#: commands.cc:1786 commands.cc:1810 commands.cc:1829 commands.cc:1848
-#: commands.cc:1866 commands.cc:1894 commands.cc:1912
+#: commands.cc:1851 commands.cc:1875 commands.cc:1894 commands.cc:1913
+#: commands.cc:1931 commands.cc:1959 commands.cc:1977
msgid "packet i/o"
msgstr "paket-I/O"
-#: commands.cc:1786
+#: commands.cc:1851
msgid "OLDID NEWID"
msgstr "GAMMALT-ID NYTT-ID"
-#: commands.cc:1787
+#: commands.cc:1852
msgid "write file delta packet to stdout"
msgstr "skriv ut datapaket för fildelta till stdout"
-#: commands.cc:1801 commands.cc:1803 commands.cc:1842
+#: commands.cc:1866 commands.cc:1868 commands.cc:1907
#, c-format
msgid "no such file '%s'"
msgstr "filen '%s' finns inte"
-#: commands.cc:1810 commands.cc:1829 commands.cc:1848 commands.cc:1866
-#: commands.cc:1894
+#: commands.cc:1875 commands.cc:1894 commands.cc:1913 commands.cc:1931
+#: commands.cc:1959
msgid "ID"
msgstr "ID"
-#: commands.cc:1810
+#: commands.cc:1875
msgid "write revision data packet to stdout"
msgstr "skriv ut datapaket för revision till stdout"
-#: commands.cc:1829
+#: commands.cc:1894
msgid "write file data packet to stdout"
msgstr "skriv ut datapaket för fil till stdout"
-#: commands.cc:1848
+#: commands.cc:1913
msgid "write cert packets to stdout"
msgstr "skriv ut datapaket för cert till stdout"
-#: commands.cc:1866
+#: commands.cc:1931
msgid "write public key packet to stdout"
msgstr "skriv it datapaket för publik nyckel till stdout"
-#: commands.cc:1888
+#: commands.cc:1953
#, c-format
msgid "public key '%s' does not exist"
msgstr "den publika nyckeln '%s' finns inte"
-#: commands.cc:1894
+#: commands.cc:1959
msgid "write private key packet to stdout"
msgstr "skriv it datapaket för privat nyckel till stdout"
-#: commands.cc:1902
+#: commands.cc:1967
#, c-format
msgid "public and private key '%s' do not exist in keystore"
msgstr "den publika och privata nyckeln '%s' finns inte i nyckellagret"
-#: commands.cc:1913
+#: commands.cc:1978
msgid "read packets from files or stdin"
msgstr "läs paket från filer eller stdin"
-#: commands.cc:1921
+#: commands.cc:1986
#, c-format
msgid "no packets found on stdin"
msgstr "inga paket hittade i stdin"
-#: commands.cc:1932
+#: commands.cc:1997
#, c-format
msgid "no packets found in given file"
msgid_plural "no packets found in given files"
msgstr[0] "inga paket funna i den angivna filen"
msgstr[1] "inga paket funna i de angivna filerna"
-#: commands.cc:1936
+#: commands.cc:2001
#, c-format
msgid "read %d packet"
msgid_plural "read %d packets"
msgstr[0] "läste %d paket"
msgstr[1] "läste %d paket"
-#: commands.cc:1965
+#: commands.cc:2030
#, c-format
msgid "setting default server to %s\n"
msgstr "sätter standardserver till %s\n"
-#: commands.cc:1971
+#: commands.cc:2036
#, c-format
msgid "no hostname given"
msgstr "inget värdnamn angivet"
-#: commands.cc:1973
+#: commands.cc:2038
#, c-format
msgid "no server given and no default server set"
msgstr "ingen server angiven och ingen standardserver är satt"
-#: commands.cc:1991
+#: commands.cc:2056
#, c-format
msgid "setting default branch include pattern to '%s'\n"
msgstr "sätter standardmönstret för grenar att ta med till '%s'\n"
-#: commands.cc:1997
+#: commands.cc:2062
#, c-format
msgid "setting default branch exclude pattern to '%s'\n"
msgstr "sätter standardmönstret för grenar att INTE ta med till '%s'\n"
-#: commands.cc:2003
+#: commands.cc:2068
#, c-format
msgid "no branch pattern given"
msgstr "inget grenmönster angivet"
-#: commands.cc:2005
+#: commands.cc:2070
#, c-format
msgid "no branch pattern given and no default pattern set"
msgstr "inget grenmönster angivet och inget standardmönster satt"
-#: commands.cc:2021 commands.cc:2036 commands.cc:2050 commands.cc:2065
+#: commands.cc:2086 commands.cc:2101 commands.cc:2115 commands.cc:2130
msgid "network"
msgstr "nätverk"
-#: commands.cc:2021 commands.cc:2036 commands.cc:2050
+#: commands.cc:2086 commands.cc:2101 commands.cc:2115
msgid "[ADDRESS[:PORTNUMBER] [PATTERN]]"
msgstr "[ADRESS[:PORTNUMMER] [MÖNSTER]]"
-#: commands.cc:2022
+#: commands.cc:2087
msgid "push branches matching PATTERN to netsync server at ADDRESS"
msgstr "skicka grenar som matchar MÖNSTER till netsync-server på ADRESS"
-#: commands.cc:2037
+#: commands.cc:2102
msgid "pull branches matching PATTERN from netsync server at ADDRESS"
msgstr "hämta grenar som matchar MÖNSTER till netsync-server på ADRESS"
-#: commands.cc:2044
+#: commands.cc:2109
#, c-format
msgid "doing anonymous pull; use -kKEYNAME if you need authentication\n"
msgstr "hämtar anonymt; använd -kNYCKELNAMN om du behöver autentisera\n"
-#: commands.cc:2051
+#: commands.cc:2116
msgid "sync branches matching PATTERN with netsync server at ADDRESS"
msgstr "synkronisera grenar som matchar MÖNSTER till netsync-server på ADRESS"
-#: commands.cc:2065
+#: commands.cc:2130
msgid "PATTERN ..."
msgstr "MÖNSTER ..."
-#: commands.cc:2066
+#: commands.cc:2131
msgid "serve the branches specified by PATTERNs to connecting clients"
msgstr "servera de grenar som matchar MÖNSTER till anslutande klienter"
-#: commands.cc:2079
+#: commands.cc:2144
#, c-format
msgid ""
"need permission to store persistent passphrase (see hook persist_phrase_ok())"
@@ -974,11 +975,11 @@ msgstr ""
"behöver tillstånd att använda ett permanent lösenord (se lua-rutinen\n"
"persist_phrase_ok())"
-#: commands.cc:2091
+#: commands.cc:2156
msgid "database"
msgstr "databas"
-#: commands.cc:2092
+#: commands.cc:2157
msgid ""
"init\n"
"info\n"
@@ -1010,11 +1011,11 @@ msgstr ""
"rosterify\n"
"set_epoch GREN EPOK\n"
-#: commands.cc:2106
+#: commands.cc:2171
msgid "manipulate database state"
msgstr "gör ändringar direkt i databasen"
-#: commands.cc:2159
+#: commands.cc:2224
msgid ""
"set PATH ATTR VALUE\n"
"get PATH [ATTR]\n"
@@ -1024,41 +1025,41 @@ msgstr ""
"get SÖKVÄG [ATTR]\n"
"drop SÖKVÄG [ATTR]"
-#: commands.cc:2160
+#: commands.cc:2225
msgid "set, get or drop file attributes"
msgstr "sätt, hämta eller ta bort attribut"
-#: commands.cc:2176
+#: commands.cc:2241
#, c-format
msgid "Unknown path '%s'"
msgstr "Okänd sökväg '%s'"
-#: commands.cc:2205
+#: commands.cc:2270
#, c-format
msgid "Path '%s' does not have attribute '%s'\n"
msgstr "Sökvägen '%s' har inget attribut '%s'\n"
-#: commands.cc:2259
+#: commands.cc:2324
#, c-format
msgid "--message and --message-file are mutually exclusive"
msgstr "--message och --message-file får inte anges samtidigt"
-#: commands.cc:2279
+#: commands.cc:2343
#, fuzzy
msgid "commit workspace to database"
msgstr "arkivera arbetskopian i databasen"
-#: commands.cc:2297
+#: commands.cc:2361
#, c-format
msgid "no changes to commit\n"
msgstr "inga ändringar att arkivera\n"
-#: commands.cc:2311
+#: commands.cc:2375
#, c-format
msgid "beginning commit on branch '%s'\n"
msgstr "börjar arkivering av ändringar i grenen '%s'\n"
-#: commands.cc:2320
+#: commands.cc:2384
#, c-format
msgid ""
"MT/log is non-empty and log message was specified on command line\n"
@@ -1069,27 +1070,32 @@ msgstr ""
"kanske ta bort eller flytta på MT/log\n"
"eller ta bort --message/--message-file från kommandoraden?"
-#: commands.cc:2332
+#: commands.cc:2396
#, c-format
msgid "empty log message; commit canceled"
msgstr "tomt loggmeddelande; arkivering avbryts"
-#: commands.cc:2349
+#: commands.cc:2415
#, c-format
+msgid "log message rejected: %s\n"
+msgstr "loggmeddelandet förkastas: %s\n"
+
+#: commands.cc:2423
+#, c-format
msgid "revision %s already in database\n"
msgstr "revisionen %s finns redan i databasen\n"
-#: commands.cc:2387 commands.cc:2404 commands.cc:2423
+#: commands.cc:2461 commands.cc:2478 commands.cc:2497
#, c-format
msgid "file '%s' modified during commit, aborting"
msgstr "filen '%s' ändrades under arkivering, avbryter"
-#: commands.cc:2449
+#: commands.cc:2523
#, c-format
msgid "committed revision %s\n"
msgstr "arkiverade revisionen %s\n"
-#: commands.cc:2455
+#: commands.cc:2529
#, c-format
msgid ""
"note: this revision creates divergence\n"
@@ -1098,7 +1104,7 @@ msgstr ""
"obs: den här revisionen skapade divergens\n"
"obs: du kan tänkas vilja (eller kanske inte) köra 'monotone merge'"
-#: commands.cc:2649
+#: commands.cc:2723
#, fuzzy
msgid ""
"show current diffs on stdout.\n"
@@ -1111,7 +1117,7 @@ msgstr ""
"revisionen. Om två revisioner anges visas skillnaden mellan dem. Om\n"
"inget format anges används unified."
-#: commands.cc:2665
+#: commands.cc:2739
#, c-format
msgid ""
"--diff-args requires --external\n"
@@ -1120,16 +1126,16 @@ msgstr ""
"--diff-args kräver att även --external anges\n"
"lägg till --external eller ta bort --diff-args?"
-#: commands.cc:2707
+#: commands.cc:2781
#, c-format
msgid "current revision has no ancestor"
msgstr "denna revision har ingen förälder"
-#: commands.cc:2770
+#: commands.cc:2844
msgid "no changes"
msgstr "inga ändringar"
-#: commands.cc:2802
+#: commands.cc:2876
#, fuzzy
msgid ""
"update workspace.\n"
@@ -1144,12 +1150,12 @@ msgstr ""
"Om en revision har angivits så uppdateras arbetskopian till den,\n"
"i annat fall uppdateras den till lövet i grenen."
-#: commands.cc:2840
+#: commands.cc:2914
#, fuzzy, c-format
msgid "this workspace is a new project; cannot update"
msgstr "denna arbetskatalog är ett nytt projekt; kan inte uppdatera"
-#: commands.cc:2847
+#: commands.cc:2921
#, c-format
msgid ""
"your request matches no descendents of the current revision\n"
@@ -1160,32 +1166,32 @@ msgstr ""
"faktum är att den inte ens matchar nuvarande revision\n"
"du kanske vill ange --revision=<revision i annan gren>"
-#: commands.cc:2852
+#: commands.cc:2926
#, c-format
msgid "multiple update candidates:\n"
msgstr "mer än en uppdateringskandidat:\n"
-#: commands.cc:2856
+#: commands.cc:2930
#, c-format
msgid "choose one with 'monotone update -r<id>'\n"
msgstr "välj en med 'monotone update -r<id>'\n"
-#: commands.cc:2857
+#: commands.cc:2931
#, c-format
msgid "multiple candidates remain after selection"
msgstr "mer än en kandidat efter urval"
-#: commands.cc:2872
+#: commands.cc:2946
#, c-format
msgid "already up to date at %s\n"
msgstr "redan uppdaterad till %s\n"
-#: commands.cc:2880
+#: commands.cc:2954
#, c-format
msgid "selected update target %s\n"
msgstr "valt uppdateringsmål är %s\n"
-#: commands.cc:2892
+#: commands.cc:2966
#, c-format
msgid ""
"revision %s is not a member of branch %s\n"
@@ -1194,140 +1200,140 @@ msgstr ""
"revisionen %s är inte i grenen %s\n"
"försök igen med en explicit --branch\n"
-#: commands.cc:2992
+#: commands.cc:3066
#, c-format
msgid "updated to base revision %s\n"
msgstr "uppdaterad till revisionen %s\n"
-#: commands.cc:3002
+#: commands.cc:3076
msgid "merge unmerged heads of branch"
msgstr "slå ihop ej ihopslagna löv i grenen"
-#: commands.cc:3016
+#: commands.cc:3090
#, c-format
msgid "branch '%s' is merged\n"
msgstr "löven i grenen '%s' är ihopslagna\n"
-#: commands.cc:3022
+#: commands.cc:3096
#, c-format
msgid "starting with revision 1 / %d\n"
msgstr "börjar med revision 1 av %d\n"
-#: commands.cc:3026
+#: commands.cc:3100
#, c-format
msgid "merging with revision %d / %d\n"
msgstr "slår ihop med revision %d av %d\n"
-#: commands.cc:3027 commands.cc:3028 commands.cc:3095 commands.cc:3170
-#: commands.cc:3171
+#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3244
+#: commands.cc:3245
#, c-format
msgid "[source] %s\n"
msgstr "[källa] %s\n"
-#: commands.cc:3045 commands.cc:3136 commands.cc:3189
+#: commands.cc:3119 commands.cc:3210 commands.cc:3263
#, c-format
msgid "[merged] %s\n"
msgstr "[ihopslagen] %s\n"
-#: commands.cc:3048
+#: commands.cc:3122
#, fuzzy, c-format
msgid "note: your workspaces have not been updated\n"
msgstr "obs: dina arbetskopior har inte uppdaterats\n"
-#: commands.cc:3051
+#: commands.cc:3125
msgid "SOURCE-BRANCH DEST-BRANCH"
msgstr "KÄLLGREN MÅLGREN"
-#: commands.cc:3052
+#: commands.cc:3126
msgid "merge from one branch to another asymmetrically"
msgstr "slå ihop asymmetriskt från en gren till en annan"
-#: commands.cc:3086 commands.cc:3089
+#: commands.cc:3160 commands.cc:3163
#, c-format
msgid "branch '%s' is not merged\n"
msgstr "löven i grenen '%s' är inte ihopslagna\n"
-#: commands.cc:3094
+#: commands.cc:3168
#, c-format
msgid "propagating %s -> %s\n"
msgstr "propagerar %s -> %s\n"
-#: commands.cc:3096
+#: commands.cc:3170
#, c-format
msgid "[target] %s\n"
msgstr "[mål] %s\n"
-#: commands.cc:3101
+#: commands.cc:3175
#, c-format
msgid "branch '%s' is up-to-date with respect to branch '%s'\n"
msgstr "grenen '%s' är uppdaterad med avseende på grenen '%s'\n"
-#: commands.cc:3103
+#: commands.cc:3177
#, c-format
msgid "no action taken\n"
msgstr "inget utfördes\n"
-#: commands.cc:3107
+#: commands.cc:3181
#, c-format
msgid "no merge necessary; putting %s in branch '%s'\n"
msgstr "ingen ihopslagning behövs; sätter %s i grenen '%s'\n"
-#: commands.cc:3140
+#: commands.cc:3214
msgid "refresh the inodeprint cache"
msgstr "uppdatera inodeprint-cachen"
-#: commands.cc:3148
+#: commands.cc:3222
msgid "LEFT-REVISION RIGHT-REVISION DEST-BRANCH"
msgstr "VÄNSTERREVISION HÖGERREVISION MÅLGREN"
-#: commands.cc:3149
+#: commands.cc:3223
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:3163
+#: commands.cc:3237
#, c-format
msgid "%s and %s are the same revision, aborting"
msgstr "%s och %s är samma revision, avbryter"
-#: commands.cc:3165 commands.cc:3167
+#: commands.cc:3239 commands.cc:3241
#, c-format
msgid "%s is already an ancestor of %s"
msgstr "%s är redan förfader till %s"
-#: commands.cc:3192
+#: commands.cc:3266
msgid "(revision|file|key) PARTIAL-ID"
msgstr "(revision|file|key) PARTIAL-ID"
-#: commands.cc:3193
+#: commands.cc:3267
msgid "complete partial id"
msgstr "utöka den partiella identiteten"
-#: commands.cc:3202
+#: commands.cc:3276
#, c-format
msgid "non-hex digits in partial id"
msgstr "något tecken i den partiella identiteten är inte hexadecimalt"
-#: commands.cc:3241
+#: commands.cc:3315
#, fuzzy
msgid "revert file(s), dir(s) or entire workspace (\".\")"
msgstr "återställ fil(er), katalog(er) eller hela arbetskopian (\".\")"
-#: commands.cc:3318
+#: commands.cc:3392
#, c-format
msgid "reverting %s"
msgstr "återställer %s"
-#: commands.cc:3322
+#: commands.cc:3396
#, c-format
msgid "no file version %s found in database for %s"
msgstr "filversionen %s finns inte i databasen för %s"
-#: commands.cc:3343
+#: commands.cc:3417
msgid "RCSFILE..."
msgstr "RCSFIL..."
-#: commands.cc:3344
+#: commands.cc:3418
msgid ""
"parse versions in RCS files\n"
"this command doesn't reconstruct or import revisions.you probably want "
@@ -1337,36 +1343,36 @@ msgstr ""
"detta kommando importerar inte revisioner; du vill antagligen använda\n"
"cvs_import"
-#: commands.cc:3360
+#: commands.cc:3434
msgid "rcs"
msgstr "rcs"
-#: commands.cc:3360
+#: commands.cc:3434
msgid "CVSROOT"
msgstr "CVSROOT"
-#: commands.cc:3360
+#: commands.cc:3434
msgid "import all versions in CVS repository"
msgstr "importera alla revisioner i ett CVS-arkiv"
-#: commands.cc:3423
+#: commands.cc:3497
msgid "PATH"
msgstr "SÖKVÄG"
-#: commands.cc:3424
+#: commands.cc:3498
msgid "print annotated copy of the file from REVISION"
msgstr "skriv ut filen ur REVISION med extra detaljer"
-#: commands.cc:3444
+#: commands.cc:3518
#, c-format
msgid "no revision for file '%s' in database"
msgstr "filen '%s' har ingen revision i databasen"
-#: commands.cc:3462
+#: commands.cc:3536
msgid "[FILE] ..."
msgstr "[FIL] ..."
-#: commands.cc:3463
+#: commands.cc:3537
msgid ""
"print history in reverse order (filtering by 'FILE'). If one or more\n"
"revisions are given, use them as a starting point."
@@ -1375,35 +1381,35 @@ msgstr ""
"arbetskatalogen om inga filer angivits. Om en eller flera revisioner\n"
"har angivits används de som utgångspunkter."
-#: commands.cc:3510
+#: commands.cc:3584
#, c-format
msgid "Unknown file '%s' for log command"
msgstr "Okänd fil '%s'"
-#: commands.cc:3528
+#: commands.cc:3602
#, c-format
msgid "only one of --last/--next allowed"
msgstr "enbart en av --last eller --next tillåten"
-#: commands.cc:3696
+#: commands.cc:3770
msgid "[DIRECTORY]"
msgstr "[KATALOG]"
-#: commands.cc:3696
+#: commands.cc:3770
#, fuzzy
msgid "setup a new workspace directory, default to current"
msgstr "initiera en ny arbetskatalog (nuvarande om katalog ej anges)"
-#: commands.cc:3702
+#: commands.cc:3776
#, c-format
msgid "need --branch argument for setup"
msgstr "du måste ange en gren med --branch till kommandot \"setup\""
-#: commands.cc:3716
+#: commands.cc:3790
msgid "automation"
msgstr "automatisering"
-#: commands.cc:3717
+#: commands.cc:3791
msgid ""
"interface_version\n"
"heads [BRANCH]\n"
@@ -1447,40 +1453,40 @@ msgstr ""
"get_revision [REVID]\n"
"keys\n"
-#: commands.cc:3737
+#: commands.cc:3811
msgid "automation interface"
msgstr "automatiseringsgränssnitt"
-#: commands.cc:3751 commands.cc:3767
+#: commands.cc:3825 commands.cc:3841
msgid "vars"
msgstr "variabler"
-#: commands.cc:3751
+#: commands.cc:3825
msgid "DOMAIN NAME VALUE"
msgstr "DOMÄN NAMN VÄRDE"
-#: commands.cc:3752
+#: commands.cc:3826
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:3767
+#: commands.cc:3841
msgid "DOMAIN NAME"
msgstr "DOMÄN NAMN"
-#: commands.cc:3768
+#: commands.cc:3842
msgid "remove the database variable NAME in domain DOMAIN"
msgstr "ta bort databasvariabeln NAMN från domänen DOMÄN"
-#: commands.cc:3779
+#: commands.cc:3853
#, 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:3783
+#: commands.cc:3857
msgid "REVID"
msgstr "REVID"
-#: commands.cc:3784
+#: commands.cc:3858
msgid "dump the roster associated with the given REVID"
msgstr "skriv ut den roster som hör ihop med angivet REVID"
@@ -1496,7 +1502,7 @@ msgstr "markeringar"
msgid "markings"
msgstr "markeringar"
-#: database_check.cc:319 database_check.cc:507 netsync.cc:2706
+#: database_check.cc:319 database_check.cc:507 netsync.cc:2719
#: rcs_import.cc:1226
msgid "revisions"
msgstr "revisioner"
@@ -1505,7 +1511,7 @@ msgstr "föräldraskap"
msgid "ancestry"
msgstr "föräldraskap"
-#: database_check.cc:451 netsync.cc:2710
+#: database_check.cc:451 netsync.cc:2723
msgid "keys"
msgstr "nycklar"
@@ -1869,7 +1875,7 @@ msgstr "kan inte skapa %s; den finns red
msgid "cannot create %s; it already exists"
msgstr "kan inte skapa %s; den finns redan"
-#: database.cc:515
+#: database.cc:511
#, c-format
msgid ""
"schema version : %s\n"
@@ -1910,52 +1916,52 @@ msgstr ""
" cert : %u\n"
" total : %u\n"
-#: database.cc:569
+#: database.cc:565
#, c-format
msgid "database schema version: %s"
msgstr "databasens schemaversion: %s"
-#: database.cc:646
+#: database.cc:642
#, c-format
msgid "multiple statements in query: %s\n"
msgstr "multipla kommandon i databasfråga: %s\n"
-#: database.cc:652
+#: database.cc:648
#, 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:710
+#: database.cc:706
#, c-format
msgid "null result in query: %s\n"
msgstr "inget resultat med databasfråga: %s\n"
-#: database.cc:728
+#: database.cc:724
#, 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:1775
+#: database.cc:1771
#, c-format
msgid "another key with name '%s' already exists"
msgstr "det finns redan en annan nyckel med namnet '%s'"
-#: database.cc:2819
+#: database.cc:2815
#, c-format
msgid "no database specified"
msgstr "ingen databas angiven"
-#: database.cc:2827
+#: database.cc:2823
#, c-format
msgid "database %s does not exist"
msgstr "databasen %s finns inte"
-#: database.cc:2828
+#: database.cc:2824
#, c-format
msgid "%s is a directory, not a database"
msgstr "%s är en katalog, inte en databas"
-#: database.cc:2853
+#: database.cc:2849
#, c-format
msgid "could not open database '%s': %s"
msgstr "kunde inte öppna databasen '%s': %s"
@@ -2179,37 +2185,37 @@ msgstr "lösen för '%s' stämmer inte"
msgid "passphrase for '%s' is incorrect"
msgstr "lösen för '%s' stämmer inte"
-#: lua.cc:538 lua.cc:567 lua.cc:582
+#: lua.cc:539 lua.cc:568 lua.cc:583
#, c-format
msgid "%s called with an invalid parameter"
msgstr "%s anropades med inkorrekt parameter"
-#: lua.cc:585
+#: lua.cc:586
#, c-format
msgid "Directory '%s' does not exists"
msgstr "Katalogen '%s' finns inte"
-#: lua.cc:586 rcs_import.cc:1217
+#: lua.cc:587 rcs_import.cc:1217
#, c-format
msgid "'%s' is not a directory"
msgstr "'%s' är inte en katalog"
-#: lua.cc:605 lua.cc:9