The unified diff between revisions [b954a1fc..] and [dd2f27b8..] is displayed below. It can also be downloaded as a raw diff.
#
#
# add_file "tests/t_cvsimport_branch.at"
# content [d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8]
#
# add_file "tests/t_db_kill_rev_locally_2.at"
# content [296391166304e8c739fcc7968ae5f58a36b91265]
#
# add_file "tests/t_log_nofiles_merges.at"
# content [958b5e4229b1afd2c7ec131d0a239b28d792815f]
#
# add_file "tests/t_log_to_file.at"
# content [4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c]
#
# add_file "tests/t_revert_new_project.at"
# content [ac8b9497aa5d1a89d01be066365bddb8b3889baf]
#
# patch "ChangeLog"
# from [36ddfbc60c098baecae82e3be37bb02055100506]
# to [e130fcd32c009c5f7ad8b31d5736aed3e9f67c09]
#
# patch "Makefile.am"
# from [d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1]
# to [380383c22ef6bb6b1d7203b215dbed739c249c63]
#
# patch "app_state.cc"
# from [18045740e735562c70e3a482927003729014844f]
# to [d6bd147ff69418001cff7cfd08e7ec18deca23ab]
#
# patch "app_state.hh"
# from [7fa51b357c748547e5d71dbc84fb35077c148177]
# to [7fb16348486ca507f22a99d6aca9ba2dc4a658c0]
#
# patch "commands.cc"
# from [dbf77e72442ab85b8b4390b8fb1316ca8145d507]
# to [8d15447176db8827209c2feeaaf0b0eaa7e2e1fd]
#
# patch "contrib/monotone.bash_completion"
# from [d942f24e3f430c7e12fceeb7a58e088e45211971]
# to [c5fff50c3c591f9dd72f80c3812c506571e3ab74]
#
# patch "contrib/usher.cc"
# from [cb295e80eb1af0bd7d55cde7da973c340a05deb2]
# to [599b754c575694458973cf7ecd5be5fd5a03c06d]
#
# patch "cset.cc"
# from [ac5f2a4848a4c5661496ec4f5af706de1fb6a454]
# to [a8497f9a82330f842cda2f242e97ef48e3a6b9fb]
#
# patch "cset.hh"
# from [f2d58803ea89b51b5029a349c30acc3c6c3cf580]
# to [7bd817258ac15fa2b6e4c3473e9b97858721969d]
#
# patch "database.cc"
# from [2fc44fac19123c10272d86d0295b91f58a8ad6b1]
# to [70d4d8f0c43de5e18bb023fc2c87805c0cdfa659]
#
# patch "enumerator.cc"
# from [33a06c9ebfb955efb197f5eafb2e8d9beaee8a1d]
# to [05baab83e8b397403e54ed13a6c514c81feb7b4f]
#
# patch "enumerator.hh"
# from [1880dae7a6147b0ddd8064bfc4679334b520aeab]
# to [5cc476581aed97dd306843e60c057ab1053cf0da]
#
# patch "lua.cc"
# from [8284c5010bee38f15141c3e60eeeeb7c288ee20c]
# to [a9045fcf6d8283a12a96f422b79fb54ae2da727c]
#
# patch "lua.hh"
# from [a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea]
# to [5691c7c116dc402741a8a9ba7f5ab7d2ebe7b2e0]
#
# patch "monotone.cc"
# from [92399bda2cd0fba92739636d7b0955c1c43bea23]
# to [6626e22d6ef4d9c8d3380a2f498599dd57bc6d3d]
#
# patch "monotone.texi"
# from [355d07f84caee318dd69f37ff6274842ca2d2c70]
# to [1fcc35f2ac3ca9ba692509cd29f6f5ff01b6616a]
#
# patch "netsync.cc"
# from [8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa]
# to [0edebb049f6f44132b6c97be4663efc113efeee8]
#
# patch "options.hh"
# from [6dc48543e2cb20ea82ded241dc5bb6088c3cb09c]
# to [16194449c59ae0307ab9bbf15ae879f0f8063fdd]
#
# patch "po/sv.po"
# from [754e90276863a8b1a53cad17c575bb93ffcdd5b4]
# to [e065ecfd2c28c0ea89877c3c95ceeae23190b320]
#
# patch "roster.cc"
# from [4547e72b235da17471b9781c3416e7eac2904027]
# to [5313de9037e0af779b593f9f432155891a70374a]
#
# patch "roster.hh"
# from [0f6d33d17d3d1c804be21f2e8025d86e47f087f9]
# to [0647777b7cab5a2c17419998351f049eadc706d5]
#
# patch "roster_merge.cc"
# from [4dec4aecf9c67f0ba369c9430bb492a3d93170bf]
# to [aa38469bceafec9e94d2ba9c291cf08d6fc90e06]
#
# patch "roster_merge.hh"
# from [e9c290f799091e5ecb70e291daae0bff72df2d48]
# to [9227745f9aeb67c68ca363dc1df62537c8bcb873]
#
# patch "sanity.cc"
# from [b31758131617cacbc373a95c25cab49e15ffedc3]
# to [36f79a9ba2cf13f0f96eb85a36ee0ca1619c39df]
#
# patch "sanity.hh"
# from [3d91a4abd21f2af06ea78724a922b3b52fa0838f]
# to [88009f27365f17c86b8dd104021fbcc1cc08a497]
#
# patch "sqlite/alter.c"
# from [faf98b04050d674d06df21bcf23ded5bbff7b5b7]
# to [451b34fc4eb2475ca76a2e86b21e1030a9428091]
#
# patch "sqlite/btree.c"
# from [f45f57e6cbd3b3db947cdd699db64e5215d20b2a]
# to [23bbfb4745e549ca224f6c933a6e9bc106d77f56]
#
# patch "sqlite/btree.h"
# from [5663c4f43e8521546ccebc8fc95acb013b8f3184]
# to [40055cfc09defd1146bc5b922399c035f969e56d]
#
# patch "sqlite/build.c"
# from [feaa61e769d7887ffeaa060d746638c7b3e994ef]
# to [b46cd7d0e2daca775d9de0cba8abae1b1625caf4]
#
# patch "sqlite/date.c"
# from [c70a4f88e495ae2c523f6ef3848c26a021c96de8]
# to [cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e]
#
# patch "sqlite/delete.c"
# from [56ab34c3a384caa5d5ea06f5739944957e2e4213]
# to [ca404d5fd5f678e32f2f46377ad802cd0219aa99]
#
# patch "sqlite/expr.c"
# from [1149c3380bfce27703f5e9bec7dfb8e51baaf9d9]
# to [9c957fabf95ef62288151eecd5c490a629470666]
#
# patch "sqlite/func.c"
# from [96b26601c092b7b43a13e440e3f988b32a385f6a]
# to [93d004b453a5d9aa754e673eef75d3c9527e0f54]
#
# patch "sqlite/insert.c"
# from [7e931b7f06afbcefcbbaab175c02eff8268db33f]
# to [67b3dc11831c58d8703eb502355ad3704ee18f66]
#
# patch "sqlite/main.c"
# from [2693776249865dc69b97904205638e84a34a059c]
# to [9a42464c44a6532003391486e802e65e88789cfc]
#
# patch "sqlite/os_common.h"
# from [061fba8511a656b118551424f64e366ad0d4cb3b]
# to [108cd719c96a2b714b64e02aeabbd40684274e6a]
#
# patch "sqlite/os_unix.c"
# from [73c5e722a661ed98d8919f204911e4e34e51fa41]
# to [378a89aaf15d83b901c1b73350e91ddecf743986]
#
# patch "sqlite/os_win.c"
# from [566bf7b41b72556fd7dca390bceaa2769dc395e9]
# to [c67a2c46d929cf54c8f80ec5e6079cf684a141a9]
#
# patch "sqlite/pager.c"
# from [b5b380ea7a36f84e50c3adc1a414820a0eb3baa6]
# to [c438aa5fc248e0523e80591eeae33a3993c47278]
#
# patch "sqlite/pager.h"
# from [e0acb095b3ad0bca48f2ab00c87346665643f64f]
# to [425a9e52d5404158de016799715cbc2c3d685178]
#
# patch "sqlite/parse.c"
# from [a31a0cb5fd9be3781389e4b2784b197d03226dc4]
# to [56d45a7fd03e7c499e1a0bacb81916956b9ec8d7]
#
# patch "sqlite/pragma.c"
# from [4496cc77dc35824e1c978c3d1413b8a5a4c777d3]
# to [31d3e1b74cab2172807894e70c674d6a577501fd]
#
# patch "sqlite/prepare.c"
# from [40ae23c8aeb641dc7b9bb271eb5e295b815154a7]
# to [cf0fc8ebaf94409955ecb09ffeb0099c9ef44693]
#
# patch "sqlite/select.c"
# from [daee9b20702ba51cf3807fc1b130edd8846e3e48]
# to [7d069e875d0eec05129c7e8b9c99422d7c9c6321]
#
# patch "sqlite/sqlite3.h"
# from [6b9ed927e0a9a3c6051a372929c97c2ac87ab314]
# to [d0605a62334179d9c38bf587ac38b777d6daee2b]
#
# patch "sqlite/sqliteInt.h"
# from [0121298397ac14eb468ab1ba9d488ac7ed7d88a1]
# to [f61b60f243f1709c943c62cfb6d7a50209080e38]
#
# patch "sqlite/table.c"
# from [486dcfce532685b53b5a2b5da8bba0ded6fb2316]
# to [f64ec4fbfe333f8df925bc6ba494f55e05b0e75e]
#
# patch "sqlite/tokenize.c"
# from [9ae9a59238eb97fbc61baea280563b91100518fb]
# to [382b3bb0ca26eb9153b5d20b246ef512a114a24f]
#
# patch "sqlite/update.c"
# from [14be4ba2f438919b4217085c02feff569e6cf1f2]
# to [050a7e0ddaac03dec5271712eee62f1a9e699049]
#
# patch "sqlite/util.c"
# from [82ee598519b8193184bdeab06b51a4ffa05ad60b]
# to [405f46fef062b476826d2c171ec21def29563b75]
#
# patch "sqlite/vdbe.c"
# from [fee677e05236e483d6c75d1d4229955fc1b89193]
# to [0a7fd81609429bae2b3c326687b02a60a9c01c49]
#
# patch "sqlite/vdbe.h"
# from [8729a4ee16ff9aeab2af9667df3cf300ff978e13]
# to [80ba1c391ec28180dd07a630577f50b22c2062da]
#
# patch "sqlite/vdbeapi.c"
# from [dcb2636f49b4807e34960d52a2fc257b3a751140]
# to [7dc662e7c905ce666bb506dced932e0307115cbf]
#
# patch "sqlite/vdbeaux.c"
# from [9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797]
# to [95f4ed0bc8ed45f16823d84504310495b5dc587d]
#
# patch "sqlite/where.c"
# from [8409e00fa2cb5fce873b4c911165cfed097e9c49]
# to [c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6]
#
# patch "std_hooks.lua"
# from [8f01e338e8056c62de500694210fd22dacac6122]
# to [87a925a89f17ae312390049e28296bbb9f7ee170]
#
# patch "test_hooks.lua"
# from [391ca756f0e4bd4325ffba83caf9a698b1713e23]
# to [c8ca29aac8840285176dc56724352917a3b52bf2]
#
# patch "tests/t_netsync_permissions.at"
# from [9a8356b76404d50e044f74e5f59d6e055ad64d1e]
# to [14dc033954a1e36979893b0f9b4d5daf4be18b82]
#
# patch "testsuite.at"
# from [7f433b14b3bd2a67eeacc49577a64e35d97ed02f]
# to [c8be08d87b48f90c833c326e708aaa06423b1b75]
#
# patch "ui.cc"
# from [f412b8a06dfed701085469c14e62e359369469cf]
# to [7bef43275fba7bdf4c2dc03ee191776dc2a57834]
#
# patch "ui.hh"
# from [496479433aee1e5ff51e96a22ae7cb662d71c4b8]
# to [5a1e338407beeda0b373e5296d9106d4a6d9f35f]
#
# patch "unit_tests.cc"
# from [cd6c9924afd3ab76ba8bfb91ff23990f3a1cc565]
# to [5f4e6b96f89134edb6d35c799b26932587dc3679]
#
# patch "unit_tests.hh"
# from [b2611fdb586f062e99b396dd5985db3b1f884360]
# to [1f0dbf6a811b8bcb25b0a0071239cf7809867037]
#
# patch "work.cc"
# from [265e6d058be85a58414c208164fbe9592b1d3e74]
# to [39e5c9ecd7f5209dbcbb7e631d6fc044296a4a67]
#
# patch "work.hh"
# from [723c827976adf80b589df8c0e2629ed7fafb907e]
# to [2e87d93b08c16ef877483f69594636c480d0f97f]
#
============================================================
--- tests/t_cvsimport_branch.at d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8
+++ tests/t_cvsimport_branch.at d5bcc9ee933be0f2711d9e81f005dfbd8d1ca3e8
@@ -0,0 +1,127 @@
+# -*- Autoconf -*-
+
+AT_SETUP([importing CVS branches with correct ancestory])
+
+MONOTONE_SETUP
+
+AT_XFAIL_IF(true)
+
+AT_DATA(file1.0, [version 0 of test file1
+])
+
+AT_DATA(file1.1, [version 1 of test file1
+])
+
+AT_DATA(file1.2, [version 2 of test file1
+])
+
+AT_DATA(file2.0, [version 0 of test file2
+])
+
+AT_DATA(file2.1, [version 1 of test file2
+])
+
+AT_DATA(changelog.0, [first changelog entry
+])
+
+AT_DATA(changelog.1, [second changelog
+
+first changelog entry
+])
+
+AT_DATA(changelog.2, [third changelog -not on branch-
+
+second changelog
+
+first changelog entry
+])
+
+AT_DATA(changelog.3, [third changelog -on branch-
+
+second changelog
+
+first changelog entry
+])
+
+AT_DATA(branchlist, [test
+test.branched
+])
+
+F1SHA0=`SHA1(file1.0)`
+F1SHA1=`SHA1(file1.1)`
+F1SHA2=`SHA1(file1.2)`
+F2SHA0=`SHA1(file2.0)`
+T2SHA1=`SHA1(file2.1)`
+CSHA0=`SHA1(changelog.0)`
+CSHA1=`SHA1(changelog.1)`
+CSHA2=`SHA1(changelog.2)`
+CSHA3=`SHA1(changelog.3)`
+
+# build the cvs repository
+
+CVSROOT=`pwd`/cvs-repository
+AT_CHECK(cvs -q -d $CVSROOT init, [0], [ignore], [ignore])
+AT_CHECK(test -e $CVSROOT)
+AT_CHECK(test -e $CVSROOT/CVSROOT)
+AT_CHECK(test -e $CVSROOT/CVSROOT/modules)
+
+# checkout the empty repository and commit some files
+
+AT_CHECK(cvs -d $CVSROOT co ., [], [ignore], [ignore])
+AT_CHECK(mkdir testdir)
+AT_CHECK(cp file1.0 testdir/file1)
+AT_CHECK(cp file2.0 testdir/file2)
+AT_CHECK(cp changelog.0 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT add testdir, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/file1, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/file2, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT add testdir/changelog, [], [ignore], [ignore])
+AT_CHECK(cvs -d $CVSROOT commit -m 'initial import' testdir/file1 testdir/file2 testdir/changelog, [], [ignore], [ignore])
+
+# commit first changes
+AT_CHECK(cp file1.1 testdir/file1)
+AT_CHECK(cp changelog.1 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'first commit' testdir/file1 testdir/changelog, [], [ignore], [ignore])
+
+# now we create a branch
+AT_CHECK(cd testdir; cvs -d $CVSROOT tag -b branched, [], [ignore], [ignore])
+AT_CHECK(cd testdir; cvs -d $CVSROOT up -r branched, [], [ignore], [ignore])
+
+# alter the files on the branch
+AT_CHECK(cp file2.1 testdir/file2)
+AT_CHECK(cp changelog.3 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'commit on branch' testdir/file2 testdir/changelog, [], [ignore], [ignore])
+
+# and create some mainline changes after the branch
+AT_CHECK(cvs -d $CVSROOT up -A, [], [ignore], [ignore])
+AT_CHECK(cp file1.2 testdir/file1)
+AT_CHECK(cp changelog.2 testdir/changelog)
+AT_CHECK(cvs -d $CVSROOT commit -m 'commit on mainline after branch' testdir/file1 testdir/changelog, [], [ignore], [ignore])
+
+# import into monotone and check presence of files
+AT_CHECK(MONOTONE --branch=test cvs_import $CVSROOT/testdir, [], [ignore], [ignore])
+
+# check if all branches were imported
+AT_CHECK(MONOTONE list branches, [], [stdout], [ignore])
+AT_CHECK(cmp stdout branchlist)
+
+# checkout the imported repository into maindir and branchdir
+AT_CHECK(MONOTONE checkout --branch=test maindir, [], [ignore], [ignore])
+AT_CHECK(MONOTONE checkout --branch=test.branched branchdir, [], [ignore], [ignore])
+
+# check for correctness of the files in the main tree
+AT_CHECK(cmp file1.2 maindir/file1)
+AT_CHECK(cmp file2.0 maindir/file2)
+AT_CHECK(cmp changelog.2 maindir/changelog)
+
+# check for correctness of the files in the branch
+AT_CHECK(cmp file1.1 branchdir/file1)
+AT_CHECK(cmp file2.1 branchdir/file2)
+AT_CHECK(cmp changelog.3 branchdir/changelog)
+
+# get the log of the branch to check for correct branchpoint
+AT_CHECK(cd branchdir; MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep "commit on branch" stdout, [], [ignore], [ignore])
+AT_CHECK(grep "initial import" stdout, [], [ignore], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_db_kill_rev_locally_2.at 296391166304e8c739fcc7968ae5f58a36b91265
+++ tests/t_db_kill_rev_locally_2.at 296391166304e8c739fcc7968ae5f58a36b91265
@@ -0,0 +1,32 @@
+AT_SETUP([db kill_rev_locally command 2])
+MONOTONE_SETUP
+
+# start off with three revisions
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+ANCESTOR=`BASE_REVISION`
+
+SET_FILE(testfile, [stuff stuff
+])
+COMMIT(testbranch)
+CHILD1=`BASE_REVISION`
+
+SET_FILE(testfile, [blahdy blah blay
+])
+COMMIT(testbranch)
+CHILD2=`BASE_REVISION`
+
+# kill head revision
+AT_CHECK(MONOTONE automate get_revision $CHILD2, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db kill_rev_locally $CHILD2, [], [ignore], [ignore])
+AT_CHECK(MONOTONE automate get_revision $CHILD2, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE db check, [], ignore, ignore)
+
+# head is an older revision now, let's kill that too
+AT_CHECK(MONOTONE automate get_revision $CHILD1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE db kill_rev_locally $CHILD1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE automate get_revision $CHILD1, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE db check, [], ignore, ignore)
+
+AT_CLEANUP
============================================================
--- tests/t_log_nofiles_merges.at 958b5e4229b1afd2c7ec131d0a239b28d792815f
+++ tests/t_log_nofiles_merges.at 958b5e4229b1afd2c7ec131d0a239b28d792815f
@@ -0,0 +1,41 @@
+AT_SETUP([log --no-files and --merges])
+MONOTONE_SETUP
+
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+R1=`BASE_REVISION`
+
+# check that changed (added) file is listed in the log output
+AT_CHECK(MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep testfile stdout, [], [ignore])
+
+# and that it has been excluded by --no-files
+AT_CHECK(MONOTONE log --no-files, [], [stdout], [ignore])
+AT_CHECK(grep testfile stdout, [1], [ignore])
+
+# add create some divergence...
+SET_FILE(testfile, [stuff stuff
+])
+COMMIT(testbranch)
+
+REVERT_TO($R1)
+
+ADD_FILE(nufile, [moo moo
+])
+COMMIT(testbranch)
+
+# ...and now merge it cleanly
+AT_CHECK(MONOTONE merge, [], [ignore], [ignore])
+AT_CHECK(MONOTONE update, [], [ignore], [ignore])
+R2=`BASE_REVISION`
+
+# check that merge is excluded from log output
+AT_CHECK(MONOTONE log, [], [stdout], [ignore])
+AT_CHECK(grep '^Revision' stdout | grep $R2, [1], [ignore])
+
+# and that it has been included by --merges
+AT_CHECK(MONOTONE log --merges, [], [stdout], [ignore])
+AT_CHECK(grep '^Revision' stdout | grep $R2, [], [ignore])
+
+AT_CLEANUP
============================================================
--- tests/t_log_to_file.at 4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c
+++ tests/t_log_to_file.at 4a9ad6b478915e87c07d13d7d15b8bdb6ae0a92c
@@ -0,0 +1,17 @@
+# -*- Autoconf -*-
+
+AT_SETUP([check --log])
+
+MONOTONE_SETUP
+
+AT_DATA(input.txt, [random content
+])
+
+AT_CHECK(MONOTONE add input.txt, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE --branch=testbranch --log=log.log commit -m "test", [], [stdout], [ignore])
+
+AT_CHECK(QGREP('^monotone:' stdout), [1])
+AT_CHECK(QGREP('^monotone:' log.log), [0])
+
+AT_CLEANUP
============================================================
--- tests/t_revert_new_project.at ac8b9497aa5d1a89d01be066365bddb8b3889baf
+++ tests/t_revert_new_project.at ac8b9497aa5d1a89d01be066365bddb8b3889baf
@@ -0,0 +1,32 @@
+# -*- Autoconf -*-
+
+AT_SETUP([revert file in new project])
+
+AT_XFAIL_IF(true)
+
+MONOTONE_SETUP
+
+
+# reverting one of one files
+AT_DATA(testfile0, [version 0 of first test file
+])
+
+AT_CHECK(MONOTONE add testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE revert testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE status, [], [stdout], [ignore])
+AT_CHECK(grep testfile0 stdout, [1], [ignore])
+
+
+# reverting one of two files
+AT_DATA(testfile0, [version 0 of first test file
+])
+AT_DATA(testfile1, [version 0 of second test file
+])
+
+AT_CHECK(MONOTONE add testfile0 testfile1, [], [ignore], [ignore])
+AT_CHECK(MONOTONE revert testfile0, [], [ignore], [ignore])
+AT_CHECK(MONOTONE status, [], [stdout], [ignore])
+AT_CHECK(grep testfile0 stdout, [1], [ignore])
+
+
+AT_CLEANUP
============================================================
--- ChangeLog 36ddfbc60c098baecae82e3be37bb02055100506
+++ ChangeLog e130fcd32c009c5f7ad8b31d5736aed3e9f67c09
@@ -1,3 +1,224 @@
+2006-02-23 Matt Johnston <matt@ucc.asn.au>
+
+ * enumerator.{cc,hh}: avoid transferring deltas on both sides of merge
+ revisions, and prefer deltas to data when both are available.
+ See
+ https://savannah.nongnu.org/bugs/?func=detailitem&item_id=15846
+
+2006-02-21 Nathaniel Smith <njs@pobox.com>
+
+ * work.cc (detach_node): This time for sure!
+
+2006-02-21 Nathaniel Smith <njs@pobox.com>
+
+ * work.cc (detach_node): Oops, x != y != !(x == y).
+
+2006-02-21 Nathaniel Smith <njs@pobox.com>
+
+ * work.cc (detach_node): Check if we are passed the root dir, and
+ error out if so.
+
+2006-02-21 Matt Johnston <matt@ucc.asn.au>
+
+ * commands.cc (pid_file): newline-terminate the pid
+
+2006-02-21 Richard Levitte <richard@levitte.org>
+
+ * contrib/usher.cc (server::set_hosts): Erasing the list node that
+ we're iterating on, then trying to go to the next node doesn't
+ work. Save the iterator, then increment it before erasing the
+ node using the saved value. No more segfaults.
+
+2006-02-21 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * sanity.hh: Work around roster_merge.cc compilation failure with
+ GCC 3.4.
+
+2006-02-20 Richard Levitte <richard@levitte.org>
+
+ * monotone.cc (cpp_main), options.hh, ui.cc (redirect_log_to),
+ ui.hh (struct user_interface): Add --log option, to redirect the
+ log lines to a file.
+
+ * monotone.texi (OPTIONS): Document it.
+
+ * po/sv.po: Translate help for this option to Swedish.
+
+ * testsuite.at, tests/t_log_to_file.at: Test it.
+
+2006-02-20 Matt Johnston <matt@ucc.asn.au>
+
+ * database.cc (remove_version): get rid of dangling deltas,
+ don't try to put data or deltas if they already exist.
+ * tests/t_db_kill_rev_locally_2.at: un-XFAIL
+
+2006-02-20 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * testsuite.at: Add an ADD_FILE variant that allows use of
+ alternate databases.
+
+ * tests/t_netsync_permissions.at: Missed some cases of the
+ database locking race.
+
+2006-02-19 Nathaniel Smith <njs@pobox.com>
+
+ * ChangeLog: Fixup after xxdiff lossage.
+
+2006-02-19 Nathaniel Smith <njs@pobox.com>
+
+ * roster_merge.cc (make_lifecycle_objs): Fix test bug.
+
+2006-02-19 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * testsuite.at: Add a REVERT_TO variant that allows use of
+ alternate databases.
+
+ * tests/t_netsync_permissions.at: Attempt to avoid a database
+ locking race in this test that is causing spurious failures by
+ using the new REVERT_TO variant to cause revert to be performed
+ using the "client" database.
+
+2006-02-19 Nathaniel Smith <njs@pobox.com>
+
+ * roster.cc (shallow_equal): Publically expose.
+ * roster.cc, roster_merge.cc: Various compile fixes.
+
+2006-02-19 Nathaniel Smith <njs@pobox.com>
+
+ * roster_merge.{hh,cc}: Make terminology more consistent.
+ "marking_map" type -> "markings" name, "marking_t" type ->
+ "marking" name.
+
+2006-02-19 Nathaniel Smith <njs@pobox.com>
+
+ * roster.{hh,cc} (testing_node_id_source): Make this node source
+ available to unit tests in other files.
+ * roster_merge.cc (test_roster_merge_node_lifecycle): New test.
+ Still quite ugly.
+
+2006-02-18 Nathaniel Smith <njs@pobox.com>
+
+ * roster_merge.cc (roster_merge): Remove obsolete FIXME.
+
+2005-10-19 Matthew A. Nicholson <matt@matt-land.com>
+
+ * contrib/monotone.bash_completion: Update for 0.25.
+
+2006-02-19 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * cset.hh (struct editable_tree): Add commit() member function to
+ editable_tree.
+
+ * cset.cc (cset::apply_to): Call editable_tree::commit() after
+ applying any other changes.
+
+ * roster.hh, roster.cc: Empty implementation of
+ editable_roster_base::commit().
+
+ * work.hh, work.cc: Implementation of
+ editable_working_tree::commit() that ensures all detached nodes
+ have been reattached.
+
+ * work.hh (struct editable_working_tree): Add map for tracking
+ path name mappings across node detach operations.
+
+ * work.cc (editable_working_tree::detach_node): Insert path name
+ mappings into map.
+ (editable_working_tree::drop_detached_node,
+ editable_working_tree::attach_node): Report add/drop/rename
+ operations during workspace updates.
+
+ * lua.cc: Use the safer luaL_check* rather than lua_to* in
+ monotone_*_for_lua functions.
+
+2006-02-18 Markus Schiltknecht <markus@bluegap.ch>
+
+ * tests/t_cvsimport_branch.at, testsuite.at: New XFAIL test for
+ cvs_import branch reconstruction.
+
+2006-02-18 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * tests/t_log_nofiles_merges.at: Add test for the log options
+ --no-files and --merges.
+
+ * testsuite.at: Add t_log_nofiles_merges.at.
+
+2006-02-13 Nathaniel Smith <njs@pobox.com>
+
+ * roster_merge.cc (log_conflicts): Tweak string.
+ Add list of tests needed.
+
+2006-02-13 Nathaniel Smith <njs@pobox.com>
+
+ * roster_merge.cc (is_clean): Simplify.
+ (add_roster_merge_tests):
+ * unit_tests.cc (init_unit_test_suite):
+ * unit_tests.hh (add_roster_merge_tests): Add unit test
+ boilerplate.
+
+2006-02-18 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * tests/t_db_kill_rev_locally_2.at: Add an XFAIL test for a
+ kill_rev_locally bug reported by Daniel Carosone.
+
+ * testsuite.at: Add t_db_kill_rev_locally_2.at.
+
+ * sqlite/parse.h: Regenerated parse.h from pristine SQLite 3.3.4
+ source. The version committed in the 3.3.4 import had a bunch of
+ duplicate entries.
+
+ * commands.cc (CMD(identify)): This isn't really a "workspace"
+ command--stick it under "debug" for lack of a better place.
+
+ * commands.cc (CMD(refresh_inodeprints)): Check for a valid
+ workspace rather than failing with an invariant when run outside
+ of a workspace.
+
+ * tests/t_revert_new_project.at: Add an XFAIL test for a bug where
+ reverting a file added in a new project will leave the workspace
+ in a bad state until MT/work is removed manually.
+
+ * testsuite.at: Add t_revert_new_project.at.
+
+ * app_state.cc, app_state.hh, commands.cc, monotone.cc,
+ options.hh: Add '--no-files' option to log to allow users to
+ exclude the list of files changed in each revision from the log
+ output.
+
+ * monotone.texi: Document '--no-files', and '--next' and '--diffs'
+ while there.
+
+2006-02-17 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * lua.cc, lua.hh, monotone.texi, std_hooks.lua, test_hooks.lua,
+ testsuite.at: Remove unused non_blocking_rng_ok hook.
+
+ * sqlite/*: Import SQLite 3.3.4.
+
+2006-02-16 Patrick Mauritz <oxygene@studentenbude.ath.cx>
+
+ * netsync.cc (handle_new_connection): Netxx::Address.get_name()
+ returns NULL every now and then. if so, continue with "" instead
+
+ * sqlite/parse.c: move #line under all #include directives so
+ the compiler can't be confused by it.
+
+2006-02-14 Richard Levitte <richard@levitte.org>
+
+ * Makefile.am (htmldir): Add variables so monotone.html is created
+ and installed automatically.
+ This is prompted by debian/monotone.html, which indicates
+ monotone.html should be available.
+
+ * netsync.cc (serve_connections): Correct spelling.
+
+2006-02-13 Matthew Gregan <kinetik@orcon.net.nz>
+
+ * sanity.cc (sanity::dump_buffer): Fix a SEGV when we're in an
+ error unwind and about to ask the user to mail us the crash
+ log--we must use FL() rather than F() here, since by the time this
+ is called we can't rely on the i18n infrastructure being alive.
+
2006-02-12 Nathaniel Smith <njs@pobox.com>
* netsync.cc (serve_connections): Revert garbage that I
============================================================
--- Makefile.am d4ad27fc9fa7d8d2b82c512a67adbd237b7fcca1
+++ Makefile.am 380383c22ef6bb6b1d7203b215dbed739c249c63
@@ -241,6 +241,9 @@ lib3rdparty_a_SOURCES = $(BOOST_SANDBOX_
$(LUA_SOURCES) \
$(SQLITE_SOURCES)
+htmldir = $(datadir)/doc/monotone
+html_DATA = monotone.html
+
# flags
if BUILD_PCH
============================================================
--- app_state.cc 18045740e735562c70e3a482927003729014844f
+++ app_state.cc d6bd147ff69418001cff7cfd08e7ec18deca23ab
@@ -36,7 +36,7 @@ app_state::app_state()
depth(-1), last(-1), next(-1), diff_format(unified_diff), diff_args_provided(false),
use_lca(false), execute(false), bind_address(""), bind_port(""),
missing(false), unknown(false),
- confdir(get_default_confdir()), have_set_key_dir(false)
+ confdir(get_default_confdir()), have_set_key_dir(false), no_files(false)
{
db.set_app(this);
lua.set_app(this);
============================================================
--- app_state.hh 7fa51b357c748547e5d71dbc84fb35077c148177
+++ app_state.hh 7fb16348486ca507f22a99d6aca9ba2dc4a658c0
@@ -73,6 +73,7 @@ public:
system_path confdir;
bool have_set_key_dir;
std::set<std::string> attrs_to_drop;
+ bool no_files;
std::map<int, bool> explicit_option_map; // set if the value of the flag was explicitly given on the command line
void set_is_explicit_option (int option_id);
============================================================
--- commands.cc dbf77e72442ab85b8b4390b8fb1316ca8145d507
+++ commands.cc 8d15447176db8827209c2feeaaf0b0eaa7e2e1fd
@@ -300,7 +300,7 @@ struct pid_file
return;
require_path_is_nonexistent(path, F("pid file '%s' already exists") % path);
file.open(path.as_external().c_str());
- file << get_process_id();
+ file << get_process_id() << endl;
file.flush();
}
@@ -1339,7 +1339,7 @@ CMD(status, N_("informative"), N_("[PATH
}
-CMD(identify, N_("workspace"), N_("[PATH]"),
+CMD(identify, N_("debug"), N_("[PATH]"),
N_("calculate identity of PATH or stdin"),
OPT_NONE)
{
@@ -3219,6 +3219,7 @@ CMD(refresh_inodeprints, N_("tree"), "",
CMD(refresh_inodeprints, N_("tree"), "", N_("refresh the inodeprint cache"),
OPT_NONE)
{
+ app.require_workspace();
enable_inodeprints();
maybe_update_inodeprints(app);
}
@@ -3541,7 +3542,8 @@ CMD(log, N_("informative"), N_("[FILE] .
CMD(log, N_("informative"), N_("[FILE] ..."),
N_("print history in reverse order (filtering by 'FILE'). If one or more\n"
"revisions are given, use them as a starting point."),
- OPT_LAST % OPT_NEXT % OPT_REVISION % OPT_BRIEF % OPT_DIFFS % OPT_MERGES)
+ OPT_LAST % OPT_NEXT % OPT_REVISION % OPT_BRIEF % OPT_DIFFS % OPT_MERGES %
+ OPT_NO_FILES)
{
if (app.revision_selectors.size() == 0)
app.require_workspace("try passing a --revision to start at");
@@ -3716,7 +3718,7 @@ CMD(log, N_("informative"), N_("[FILE] .
log_certs(app, rid, branch_name, "Branch: ", false);
log_certs(app, rid, tag_name, "Tag: ", false);
- if (! csum.cs.empty())
+ if (!app.no_files && !csum.cs.empty())
{
cout << endl;
csum.print(cout, 70);
============================================================
--- contrib/monotone.bash_completion d942f24e3f430c7e12fceeb7a58e088e45211971
+++ contrib/monotone.bash_completion c5fff50c3c591f9dd72f80c3812c506571e3ab74
@@ -1,7 +1,9 @@
# -*- shell-script -*-
+# vim: set ft=sh:
-# bash completion for monotone 0.18
+# bash completion for monotone 0.25
# Author: Olivier Andrieu <oandrieu@nerim.net>
+# Contributions by Matthew A. Nicholson <matt@matt-land.com>
# source this file from your .bashrc
# If you use the bash completion package <http://www.caliban.org/bash/>,
@@ -42,6 +44,10 @@ _monotone_branches() {
COMPREPLY=( $(compgen -W "$(monotone $mono_db list branches 2> /dev/null)" -- ${cur#*=} ) )
}
+_monotone_tags() {
+ COMPREPLY=( $(compgen -W "$(monotone $mono_db list tags 2> /dev/null | awk '{print $1}')" -- ${cur#*=} ) )
+}
+
_monotone() {
local cur prev mono_db
@@ -68,6 +74,10 @@ _monotone() {
cur="${cur#*=}"
_filedir
;;
+ --root=* )
+ cur="${cur#*=}"
+ _filedir -d
+ ;;
--branch=* )
_monotone_branches
;;
@@ -76,19 +86,22 @@ _monotone() {
;;
--ticker=* )
cur="${cur#*=}"
- COMPREPLY=( $(compgen -W 'count dot' -- $cur ) )
+ COMPREPLY=( $(compgen -W 'count dot none' -- $cur ) )
;;
--revision=* )
_monotone_complete revision
;;
-* )
- COMPREPLY=( $(compgen -W '--debug --dump --quiet --help --nostd --norc\
- --rcfile --key --db --branch --version --full-version\
- --ticker --revision --message' -- $cur) )
+ COMPREPLY=( $(compgen -W '--debug --dump --quiet --help --version
+ --full-version --xargs --ticker --nostd --norc
+ --rcfile --key --db --root --verbose -k -d -@
+ -m -b -r --branch --message --date --author
+ --depth --execute --keydir --confdir
+ --key-to-push --bind' -- $cur) )
;;
* )
case $prev in
- --db | -d | --rcfile | --dump )
+ --db | -d | --rcfile | --dump | --root )
_filedir
;;
--branch | -b )
@@ -103,105 +116,112 @@ _monotone() {
--revision | -r )
_monotone_complete revision
;;
- db )
- COMPREPLY=( $(compgen -W 'init info version dump load migrate execute check changesetify rebuild' -- $cur ) )
- ;;
- cdiff | diff | annotate )
+ db )
+ COMPREPLY=( $(compgen -W 'init info version dump load migrate execute kill_rev_locally kill_branch_certs_locally kill_tag_locally check changesetify rebuild set_epoch' -- $cur ) )
+ ;;
+ cdiff | diff | annotate )
COMPREPLY=( $(compgen -W '--revision' -- $cur ) )
- _filedir
- ;;
- log | approve | disapprove | comment | tag | testresult | cert | explicit_merge | trusted | update )
- _monotone_complete revision
- ;;
- ls | list )
- COMPREPLY=( $(compgen -W 'certs keys branches epochs tags vars known unknown ignored missing' -- $cur ) )
- ;;
- attr )
- COMPREPLY=( $(compgen -W 'get set drop' -- $cur ) )
- ;;
- co | checkout )
- _filedir -d
- _monotone_complete revision
- ;;
- status | cvs_import | add | drop | rename | revert | identify )
- _filedir
- ;;
- cat )
- COMPREPLY=( $(compgen -W 'file manifest revision' -- $cur) )
- ;;
+ _filedir
+ ;;
+ log | approve | disapprove | comment | tag | testresult | cert | explicit_merge | trusted | update )
+ _monotone_complete revision
+ ;;
+ ls | list )
+ COMPREPLY=( $(compgen -W 'certs keys branches epochs tags vars known unknown ignored missing' -- $cur ) )
+ ;;
+ attr )
+ COMPREPLY=( $(compgen -W 'get set drop' -- $cur ) )
+ ;;
+ co | checkout )
+ _filedir -d
+ _monotone_complete revision
+ ;;
+ status | cvs_import | add | drop | rm | rename | mv | revert | identify )
+ _filedir
+ ;;
+ complete )
+ COMPREPLY=( $(compgen -W 'revision manifest file key' -- $cur) )
+ ;;
+ cat )
+ COMPREPLY=( $(compgen -W 'file manifest revision' -- $cur) )
+ ;;
push | pull | serve | sync )
- COMPREPLY=( $(compgen -A hostname -- $cur) )
- ;;
- pubkey | privkey )
- _monotone_keys $prev
- ;;
- chkeypass | dropkey )
- _monotone_keys privkey
- ;;
- propagate | reindex )
- _monotone_branches
- ;;
- * )
- if (( $COMP_CWORD >= 2 )) ; then
- local prev2=${COMP_WORDS[COMP_CWORD-2]}
- case $prev2 in
- cdiff | diff | explicit_merge )
- _monotone_complete revision
- ;;
- co | checkout | rename | annotate )
- _filedir -d
- ;;
- cat )
- _monotone_complete $prev
- ;;
- log | attr )
- _filedir
- ;;
- list )
- if [ $prev == certs ] ; then
- _monotone_complete revision
- _monotone_complete manifest
- _monotone_complete file
- fi
- ;;
- push | pull | serve | sync | propagate )
+ COMPREPLY=( $(compgen -A hostname -- $cur) )
+ ;;
+ pubkey | privkey )
+ _monotone_keys $prev
+ ;;
+ chkeypass | dropkey )
+ _monotone_keys privkey
+ ;;
+ propagate | reindex )
+ _monotone_branches
+ ;;
+ * )
+ if (( $COMP_CWORD >= 2 )) ; then
+ local prev2=${COMP_WORDS[COMP_CWORD-2]}
+ case $prev2 in
+ cdiff | diff | explicit_merge )
+ _monotone_complete revision
+ ;;
+ co | checkout | rename | mv | annotate )
+ _filedir
+ ;;
+ cat )
+ _monotone_complete $prev
+ ;;
+ log | attr )
+ _filedir
+ ;;
+ list )
+ if [ $prev == certs ] ; then
+ _monotone_complete revision
+ _monotone_complete manifest
+ _monotone_complete file
+ fi
+ ;;
+ push | pull | serve | sync | propagate )
_monotone_branches
- ;;
- * )
- if (( $COMP_CWORD >= 3 )) ; then
- local prev3=${COMP_WORDS[COMP_CWORD-3]}
- case $prev3 in
- explicit_merge )
- _monotone_complete revision
- _monotone_branches
- ;;
- *)
- unset prev2
- unset prev3
- esac
- else
- unset prev2
- fi
- ;;
- esac
- fi
- if [ -z "$prev2" ] ; then
- COMPREPLY=( $(compgen -W 'db agraph \
- annotate cat cdiff complete diff list log ls status \
- cert chkeypass dropkey genkey trusted \
- pull push reindex serve sync \
- privkey pubkey read \
- cvs_import \
- approve comment disapprove tag testresult \
- checkout co explicit_merge heads merge propagate refresh_inodeprints setup \
- set unset \
- add attr commit drop identify rename revert update' -- $cur) )
- fi
- ;;
+ ;;
+ * )
+ if (( $COMP_CWORD >= 3 )) ; then
+ local prev3=${COMP_WORDS[COMP_CWORD-3]}
+ case $prev3 in
+ explicit_merge )
+ _monotone_complete revision
+ _monotone_branches
+ ;;
+ *)
+ unset prev2
+ unset prev3
+ esac
+ else
+ unset prev2
+ _filedir
+ fi
+ ;;
+ esac
+ fi
+ if (( $COMP_CWORD < 2 )) ; then
+ COMPREPLY=( $(compgen -W 'automate db agraph fload fmerge lca lcad
+ rcs_import annotate cat complete diff
+ list log ls status cert chkeypass dropkey
+ genkey trusted pull push reindex serve
+ sync certs fdata fdelta mdata mdelta
+ privkey pubkey rdata read cvs_import
+ approve comment disapprove tag testresult
+ checkout co explicit_merge fcommit heads
+ merge propagate refresh_inodeprints setup
+ set unset add attr ci commit drop
+ identify mv rename revert rm update' -- $cur) )
+ else
+ _filedir
+ fi
+ ;;
esac
;;
esac
return 0
}
+complete -F _monotone -o filenames monotone
-complete -F _monotone -o default monotone
============================================================
--- contrib/usher.cc cb295e80eb1af0bd7d55cde7da973c340a05deb2
+++ contrib/usher.cc 599b754c575694458973cf7ecd5be5fd5a03c06d
@@ -1,3 +1,4 @@
+// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
// Timothy Brownawell <tbrownaw@gmail.com>
// GPL v2
//
@@ -691,10 +692,16 @@ struct server
c = servers_by_host.find(*i);
if (c != servers_by_host.end()) {
list<map<string, shared_ptr<server> >::iterator>::iterator j;
- for (j = c->second->by_host.begin(); j != c->second->by_host.end(); ++j)
- if ((*j)->first == *i) {
- servers_by_host.erase(*j);
- c->second->by_host.erase(j);
+ for (j = c->second->by_host.begin(); j != c->second->by_host.end();)
+ {
+ list<map<string, shared_ptr<server> >::iterator>::iterator j_saved
+ = j;
+ ++j;
+ if ((*j_saved)->first == *i)
+ {
+ servers_by_host.erase(*j_saved);
+ c->second->by_host.erase(j_saved);
+ }
}
}
c = servers_by_host.insert(make_pair(*i, me)).first;
============================================================
--- cset.cc ac5f2a4848a4c5661496ec4f5af706de1fb6a454
+++ cset.cc a8497f9a82330f842cda2f242e97ef48e3a6b9fb
@@ -225,6 +225,8 @@ cset::apply_to(editable_tree & t) const
for (map<pair<split_path, attr_key>, attr_value>::const_iterator i = attrs_set.begin();
i != attrs_set.end(); ++i)
t.set_attr(i->first.first, i->first.second, i->second);
+
+ t.commit();
}
////////////////////////////////////////////////////////////////////
============================================================
--- cset.hh f2d58803ea89b51b5029a349c30acc3c6c3cf580
+++ cset.hh 7bd817258ac15fa2b6e4c3473e9b97858721969d
@@ -46,6 +46,8 @@ struct editable_tree
attr_key const & name,
attr_value const & val) = 0;
+ virtual void commit() = 0;
+
virtual ~editable_tree() {}
};
============================================================
--- database.cc 2fc44fac19123c10272d86d0295b91f58a8ad6b1
+++ database.cc 70d4d8f0c43de5e18bb023fc2c87805c0cdfa659
@@ -1316,6 +1316,10 @@ database::remove_version(hexenc<id> cons
}
}
+ // no deltas are allowed to point to the target.
+ execute(query("DELETE from " + delta_table + " WHERE base = ?")
+ % text(target_id()));
+
if (delta_exists(target_id, delta_table))
{
if (!older.empty())
@@ -1335,6 +1339,8 @@ database::remove_version(hexenc<id> cons
for (map<hexenc<id>, data>::const_iterator i = older.begin();
i != older.end(); ++i)
{
+ if (delta_exists(i->first, delta_table))
+ continue;
delta bypass_delta;
diff(newer_data, i->second, bypass_delta);
put_delta(i->first, newer_id, bypass_delta, delta_table);
@@ -1349,7 +1355,10 @@ database::remove_version(hexenc<id> cons
I(exists(target_id, data_table));
for (map<hexenc<id>, data>::const_iterator i = older.begin();
i != older.end(); ++i)
- put(i->first, i->second, data_table);
+ {
+ if (!exists(i->first, data_table))
+ put(i->first, i->second, data_table);
+ }
execute(query("DELETE from " + data_table + " WHERE id = ?")
% text(target_id()));
}
============================================================
--- enumerator.cc 33a06c9ebfb955efb197f5eafb2e8d9beaee8a1d
+++ enumerator.cc 05baab83e8b397403e54ed13a6c514c81feb7b4f
@@ -68,6 +68,89 @@ void
}
void
+revision_enumerator::files_for_revision(revision_id const & r,
+ set<file_id> & full_files,
+ set<pair<file_id,file_id> > & del_files)
+{
+ // when we're sending a merge, we have to be careful if we
+ // want to send as little data as possible. see bug #15846
+ //
+ // njs's solution: "when sending the files for a revision,
+ // look at both csets. If a given hash is not listed as new
+ // in _both_ csets, throw it out. Now, for everything left
+ // over, if one side says "add" and the other says "delta",
+ // do a delta. If both sides say "add", do a data."
+
+ set<file_id> file_adds;
+ // map<dst, src>. src is arbitrary.
+ map<file_id, file_id> file_deltas;
+ map<file_id, size_t> file_edge_counts;
+
+ revision_set rs;
+ MM(rs);
+ app.db.get_revision(r, rs);
+
+ for (edge_map::const_iterator i = rs.edges.begin();
+ i != rs.edges.end(); ++i)
+ {
+ set<file_id> file_dsts;
+ 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)
+ {
+ file_adds.insert(fa->second);
+ file_dsts.insert(fa->second);
+ }
+
+ // 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)
+ {
+ file_deltas[fd->second.second] = fd->second.first;
+ file_dsts.insert(fd->second.second);
+ }
+
+ // we don't want to be counting files twice in a single edge
+ for (set<file_id>::const_iterator i = file_dsts.begin();
+ i != file_dsts.end(); i++)
+ file_edge_counts[*i]++;
+ }
+
+ del_files.clear();
+ full_files.clear();
+ size_t num_edges = rs.edges.size();
+
+ for (map<file_id, size_t>::const_iterator i = file_edge_counts.begin();
+ i != file_edge_counts.end(); i++)
+ {
+ MM(i->first);
+ if (i->second < num_edges)
+ continue;
+
+ // first preference is to send as a delta...
+ map<file_id, file_id>::const_iterator fd = file_deltas.find(i->first);
+ if (fd != file_deltas.end())
+ {
+ del_files.insert(make_pair(fd->second, fd->first));
+ continue;
+ }
+
+ // ... otherwise as a full file.
+ set<file_id>::const_iterator f = file_adds.find(i->first);
+ if (f != file_adds.end())
+ {
+ full_files.insert(*f);
+ continue;
+ }
+
+ I(false);
+ }
+}
+
+void
revision_enumerator::process_bunch()
{
// we build up a set of files and revs to send
@@ -89,42 +172,31 @@ revision_enumerator::process_bunch()
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)
+ set<file_id> full_files;
+ set<pair<file_id, file_id> > del_files;
+
+ files_for_revision(r, full_files, del_files);
+
+ set<file_id> top_files;
+ set<file_id> dst_files;
+
+ for (set<file_id>::const_iterator f = full_files.begin();
+ f != full_files.end(); f++)
{
- 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()))
- {
- dst_files.insert(fa->second);
- top_files.insert(fa->second);
- bunch_files.insert(fa->second);
- }
- }
-
- // 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()))
- {
- if (dst_files.find(fd->second.first) == dst_files.end())
- {
- top_files.insert(fd->second.first);
- }
+ bunch_files.insert(*f);
+ top_files.insert(*f);
+ dst_files.insert(*f)
+ }
- bunch_file_deltas.insert(make_pair(fd->second.first,
- fd->second.second));
- dst_files.insert(fd->second.second);
- }
- }
+ for (set<pair<file_id,file_id> >::const_iterator fd = del_files.begin();
+ fd != del_files.end(); fd++)
+ {
+ file_id src(fd->second);
+ file_id dst(fd->first);
+ bunch_file_deltas.insert(make_pair(fd->second, fd->first));
+ if (dst_files.find(src) == dst_files.end())
+ top_files.insert(src);
+ dst_files.insert(dst);
}
}
============================================================
--- enumerator.hh 1880dae7a6147b0ddd8064bfc4679334b520aeab
+++ enumerator.hh 5cc476581aed97dd306843e60c057ab1053cf0da
@@ -60,6 +60,9 @@ revision_enumerator
revision_enumerator(enumerator_callbacks & cb,
app_state & app);
void load_revs();
+ void revision_enumerator::files_for_revision(revision_id const & r,
+ std::set<file_id> & full_files,
+ std::set<std::pair<file_id,file_id> > & del_files);
void process_bunch();
void step();
bool done();
============================================================
--- lua.cc 8284c5010bee38f15141c3e60eeeeb7c288ee20c
+++ lua.cc a9045fcf6d8283a12a96f422b79fb54ae2da727c
@@ -426,7 +426,7 @@ extern "C"
{
int fd = -1;
FILE **pf = NULL;
- char const *filename = lua_tostring (L, -1);
+ char const *filename = luaL_checkstring (L, -1);
std::string dup(filename);
fd = monotone_mkstemp(dup);
@@ -458,7 +458,7 @@ extern "C"
static int
monotone_existsonpath_for_lua(lua_State *L)
{
- const char *exe = lua_tostring(L, -1);
+ const char *exe = luaL_checkstring(L, -1);
lua_pushnumber(L, existsonpath(exe));
return 1;
}
@@ -466,7 +466,7 @@ extern "C"
static int
monotone_is_executable_for_lua(lua_State *L)
{
- const char *path = lua_tostring(L, -1);
+ const char *path = luaL_checkstring(L, -1);
lua_pushboolean(L, is_executable(path));
return 1;
}
@@ -474,7 +474,7 @@ extern "C"
static int
monotone_make_executable_for_lua(lua_State *L)
{
- const char *path = lua_tostring(L, -1);
+ const char *path = luaL_checkstring(L, -1);
lua_pushnumber(L, make_executable(path));
return 1;
}
@@ -483,14 +483,14 @@ extern "C"
monotone_spawn_for_lua(lua_State *L)
{
int n = lua_gettop(L);
- const char *path = lua_tostring(L, -n);
+ const char *path = luaL_checkstring(L, -n);
char **argv = (char**)malloc((n+1)*sizeof(char*));
int i;
pid_t ret;
if (argv==NULL)
return 0;
argv[0] = (char*)path;
- for (i=1; i<n; i++) argv[i] = (char*)lua_tostring(L, -(n - i));
+ for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, -(n - i));
argv[i] = NULL;
ret = process_spawn(argv);
free(argv);
@@ -501,7 +501,7 @@ extern "C"
static int
monotone_wait_for_lua(lua_State *L)
{
- pid_t pid = (pid_t)lua_tonumber(L, -1);
+ pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -1));
int res;
int ret;
ret = process_wait(pid, &res);
@@ -514,10 +514,10 @@ extern "C"
monotone_kill_for_lua(lua_State *L)
{
int n = lua_gettop(L);
- pid_t pid = (pid_t)lua_tonumber(L, -2);
+ pid_t pid = static_cast<pid_t>(luaL_checknumber(L, -2));
int sig;
if (n>1)
- sig = (int)lua_tonumber(L, -1);
+ sig = static_cast<int>(luaL_checknumber(L, -1));
else
sig = SIGTERM;
lua_pushnumber(L, process_kill(pid, sig));
@@ -527,7 +527,7 @@ extern "C"
static int
monotone_sleep_for_lua(lua_State *L)
{
- int seconds = (int)lua_tonumber(L, -1);
+ int seconds = static_cast<int>(luaL_checknumber(L, -1));
lua_pushnumber(L, process_sleep(seconds));
return 1;
}
@@ -535,7 +535,7 @@ extern "C"
static int
monotone_guess_binary_file_contents_for_lua(lua_State *L)
{
- const char *path = lua_tostring(L, -1);
+ const char *path = luaL_checkstring(L, -1);
N(path, F("%s called with an invalid parameter") % "guess_binary");
std::ifstream file(path, ios_base::binary);
@@ -564,7 +564,7 @@ extern "C"
static int
monotone_include_for_lua(lua_State *L)
{
- const char *path = lua_tostring(L, -1);
+ const char *path = luaL_checkstring(L, -1);
N(path, F("%s called with an invalid parameter") % "Include");
bool res =Lua(L)
@@ -579,7 +579,7 @@ extern "C"
static int
monotone_includedir_for_lua(lua_State *L)
{
- const char *pathstr = lua_tostring(L, -1);
+ const char *pathstr = luaL_checkstring(L, -1);
N(pathstr, F("%s called with an invalid parameter") % "IncludeDir");
fs::path locpath(pathstr, fs::native);
@@ -613,8 +613,8 @@ extern "C"
static int
monotone_regex_search_for_lua(lua_State *L)
{
- const char *re = lua_tostring(L, -2);
- const char *str = lua_tostring(L, -1);
+ const char *re = luaL_checkstring(L, -2);
+ const char *str = luaL_checkstring(L, -1);
boost::cmatch what;
bool result = false;
@@ -632,8 +632,8 @@ extern "C"
static int
monotone_globish_match_for_lua(lua_State *L)
{
- const char *re = lua_tostring(L, -2);
- const char *str = lua_tostring(L, -1);
+ const char *re = luaL_checkstring(L, -2);
+ const char *str = luaL_checkstring(L, -1);
bool result = false;
try {
@@ -661,7 +661,7 @@ extern "C"
static int
monotone_gettext_for_lua(lua_State *L)
{
- const char *msgid = lua_tostring(L, -1);
+ const char *msgid = luaL_checkstring(L, -1);
lua_pushstring(L, gettext(msgid));
return 1;
}
@@ -685,7 +685,7 @@ extern "C"
monotone_parse_basic_io_for_lua(lua_State *L)
{
vector<pair<string, vector<string> > > res;
- const string str(lua_tostring(L, -1), lua_strlen(L, -1));
+ const string str(luaL_checkstring(L, -1), lua_strlen(L, -1));
basic_io::input_source in(str, "monotone_parse_basic_io_for_lua");
basic_io::tokenizer tok(in);
try
@@ -1049,18 +1049,6 @@ lua_hooks::hook_ignore_branch(std::strin
return exec_ok && ignore_it;
}
-bool
-lua_hooks::hook_non_blocking_rng_ok()
-{
- bool ok = false;
- bool exec_ok = Lua(st)
- .func("non_blocking_rng_ok")
- .call(0,1)
- .extract_bool(ok)
- .ok();
- return exec_ok && ok;
-}
-
static inline bool
shared_trust_function_body(Lua & ll,
std::set<rsa_keypair_id> const & signers,
============================================================
--- lua.hh a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea
+++ lua.hh 5691c7c116dc402741a8a9ba7f5ab7d2ebe7b2e0
@@ -49,7 +49,6 @@ public:
std::string const & user_log_message,
std::string & result);
bool hook_persist_phrase_ok();
- bool hook_non_blocking_rng_ok();
bool hook_get_revision_cert_trust(std::set<rsa_keypair_id> const & signers,
hexenc<id> const & id,
cert_name const & name,
============================================================
--- monotone.cc 92399bda2cd0fba92739636d7b0955c1c43bea23
+++ monotone.cc 6626e22d6ef4d9c8d3380a2f498599dd57bc6d3d
@@ -74,6 +74,7 @@ struct poptOption coptions[] =
{"unknown", 0, POPT_ARG_NONE, NULL, OPT_UNKNOWN, gettext_noop("perform the operations for unknown files from workspace"), NULL},
{"key-to-push", 0, POPT_ARG_STRING, &argstr, OPT_KEY_TO_PUSH, gettext_noop("push the specified key even if it hasn't signed anything"), NULL},
{"drop-attr", 0, POPT_ARG_STRING, &argstr, OPT_DROP_ATTR, gettext_noop("when rosterifying, drop attrs entries with the given key"), NULL},
+ {"no-files", 0, POPT_ARG_NONE, NULL, OPT_NO_FILES, gettext_noop("exclude files when printing logs"), NULL},
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
@@ -84,6 +85,7 @@ struct poptOption options[] =
{"debug", 0, POPT_ARG_NONE, NULL, OPT_DEBUG, gettext_noop("print debug log to stderr while running"), NULL},
{"dump", 0, POPT_ARG_STRING, &argstr, OPT_DUMP, gettext_noop("file to dump debugging log to, on failure"), NULL},
+ {"log", 0, POPT_ARG_STRING, &argstr, OPT_LOG, gettext_noop("file to write the log to"), NULL},
{"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, gettext_noop("suppress log and progress messages"), NULL},
{"help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, gettext_noop("display help message"), NULL},
{"version", 0, POPT_ARG_NONE, NULL, OPT_VERSION, gettext_noop("print version number, then exit"), NULL},
@@ -332,6 +334,10 @@ cpp_main(int argc, char ** argv)
global_sanity.filename = system_path(argstr);
break;
+ case OPT_LOG:
+ ui.redirect_log_to(system_path(argstr));
+ break;
+
case OPT_DB_NAME:
app.set_database(system_path(argstr));
break;
@@ -519,6 +525,10 @@ cpp_main(int argc, char ** argv)
app.attrs_to_drop.insert(string(argstr));
break;
+ case OPT_NO_FILES:
+ app.no_files = true;
+ break;
+
case OPT_HELP:
default:
requested_help = true;
============================================================
--- monotone.texi 355d07f84caee318dd69f37ff6274842ca2d2c70
+++ monotone.texi 1fcc35f2ac3ca9ba692509cd29f6f5ff01b6616a
@@ -4139,26 +4139,37 @@ @section Informative
to files changed within the current subdirectory of the workspace.
@item monotone log
-@itemx monotone log [--last=@var{n}] [--revision=@var{id} [...]] [--brief] [--merges] [@var{file} [...]]
+@itemx monotone log [--last=@var{n}] [--next=@var{n}] [--revision=@var{id} [...]] [--brief] [--merges] [--no-files] [--diffs] [@var{file} [...]]
This command prints out a log, in reverse-ancestry order, of small
history summaries. Each summary contains author, date, changelog and
-comment information associated with a revision.
+comment information associated with a revision.
If @code{--brief} is given, the output consists of one line per revision
with the revision ID, the author, the date and the branches (separated
with commas).
-If @code{--last=}@var{n} is given, at most that many log entries will be
+If @code{--last=}@var{n} is given, at most @var{n} log entries will be
given.
-By default, the log entries for merge nodes are not shown; usually they
-don't contain much interesting information. If @code{--merges} is given,
-the log entries for these nodes will be included.
+If @code{--next=}@var{n} is given, at most @var{n} log entries towards
+the current head revision will be given from the workspace's base
+revision in forward-ancestry order. This is useful to review changes
+that will be applied to the workspace when @command{update} is run.
+By default, the log entries for merge nodes are not shown; usually
+they don't contain much interesting information. If @code{--merges} is
+given, the log entries for these nodes will be included.
+
+If @code{--no-files} is given, the log output excludes the list of
+files changed in each revision.
+
+Specifying @code{--diffs} causes the log output to include a unified
+diff of the changes in each revision.
+
If one or more revision IDs are given, the command starts tracing back
-through history from these revisions, otherwise it starts from the base
-revision of your workspace.
+through history from these revisions, otherwise it starts from the
+base revision of your workspace.
If one or more files are given, the command will only log the revisions
where those files are changed.
@@ -4435,12 +4446,7 @@ @section Key and Cert
This command generates an @sc{rsa} public/private key pair, using a
system random number generator, and stores it in your keystore under
-the key name @var{keyid}. If the the hook
-@code{non_blocking_rng_ok()} returns @code{true}, the key
-generation will use an unlimited random number generator (such as
-@file{/dev/urandom}), otherwise it will use a higher quality random
-number generator (such as @file{/dev/random}) but might run slightly
-slower.
+the key name @var{keyid}.
The private half of the key is stored in an encrypted form, so that anyone
who can read your keystore cannot extract your private key and use it.
@@ -6157,25 +6163,6 @@ @subsection User Defaults
For the default definition of this hook, see @ref{Default hooks}.
-@item non_blocking_rng_ok ()
-
-Returns @code{true} if you are willing to let monotone use the
-system's non-blocking random number generator, such as
-@file{/dev/urandom}, for generating random values during cryptographic
-operations. This diminishes the cryptographic strength of such
-operations, but speeds them up. Returns @code{false} if you want to
-force monotone to always use higher quality random numbers, such as
-those from @file{/dev/random}.
-
-The default definition of this hook is:
-@smallexample
-@group
-function non_blocking_rng_ok()
- return true
-end
-@end group
-@end smallexample
-
@item persist_phrase_ok ()
Returns @code{true} if you want monotone to remember the passphrase of
@@ -7770,6 +7757,10 @@ @section OPTIONS
Dump debugging log to @i{<file>} on failure.
@comment TROFF INPUT: .TP
+@item @b{--log=}@i{<file>}
+Redirect the log lines to to @i{<file>}.
+@comment TROFF INPUT: .TP
+
@item @b{--nostd}
Do not evaluate "standard" Lua hooks compiled into @b{monotone}.
@comment TROFF INPUT: .TP
============================================================
--- netsync.cc 8d4dc8e530af4fb0a6cca30ca600dd74f905b1aa
+++ netsync.cc 0edebb049f6f44132b6c97be4663efc113efeee8
@@ -2390,7 +2390,7 @@ handle_new_connection(Netxx::Address & a
app_state & app)
{
L(FL("accepting new connection on %s : %s\n")
- % addr.get_name() % lexical_cast<string>(addr.get_port()));
+ % (addr.get_name()?addr.get_name():"") % lexical_cast<string>(addr.get_port()));
Netxx::Peer client = server.accept_connection();
if (!client)
@@ -2589,7 +2589,7 @@ serve_connections(protocol_role role,
else
addr.add_all_addresses (default_port);
- // If se use IPv6 and the initiasation of server fails, we want
+ // If se use IPv6 and the initialisation of server fails, we want
// to try again with IPv4. The reason is that someone may have
// downloaded a IPv6-enabled monotone on a system that doesn't
// have IPv6, and which might fail therefore.
============================================================
--- options.hh 6dc48543e2cb20ea82ded241dc5bb6088c3cb09c
+++ options.hh 16194449c59ae0307ab9bbf15ae879f0f8063fdd
@@ -51,3 +51,5 @@
#define OPT_KEY_TO_PUSH 42
#define OPT_CONF_DIR 43
#define OPT_DROP_ATTR 44
+#define OPT_NO_FILES 45
+#define OPT_LOG 46
============================================================
--- po/sv.po 754e90276863a8b1a53cad17c575bb93ffcdd5b4
+++ po/sv.po e065ecfd2c28c0ea89877c3c95ceeae23190b320
@@ -144,8 +144,8 @@ msgstr ""
msgstr ""
"Project-Id-Version: monotone 0.26pre1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-02-11 08:32+0100\n"
-"PO-Revision-Date: 2006-02-11 08:43+0100\n"
+"POT-Creation-Date: 2006-02-20 17:26+0100\n"
+"PO-Revision-Date: 2006-02-20 17:28+0100\n"
"Last-Translator: Joel Rosdahl <joel@rosdahl.net>\n"
"Language-Team: Richard Levitte <richard@levitte.org>\n"
"MIME-Version: 1.0\n"
@@ -303,7 +303,7 @@ msgstr "pid-filen '%s' finns redan"
msgstr "pid-filen '%s' finns redan"
#: commands.cc:325 commands.cc:1295 commands.cc:1365 commands.cc:1801
-#: commands.cc:2722 commands.cc:3266 commands.cc:3497 commands.cc:3536
+#: commands.cc:2722 commands.cc:3267 commands.cc:3498 commands.cc:3537
msgid "informative"
msgstr "informativ"
@@ -343,7 +343,7 @@ msgstr ""
#: commands.cc:481 commands.cc:737 commands.cc:1383 commands.cc:1460
#: commands.cc:1888 commands.cc:2772 commands.cc:2800 commands.cc:2803
-#: commands.cc:2939 commands.cc:3519
+#: commands.cc:2939 commands.cc:3520
#, c-format
msgid "no such revision '%s'"
msgstr "det finns ingen revision med identiteten '%s'"
@@ -618,13 +618,13 @@ msgstr "tom kommentar"
msgid "empty comment"
msgstr "tom kommentar"
-#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:1342
-#: commands.cc:2224 commands.cc:2342 commands.cc:2875 commands.cc:3314
+#: commands.cc:1168 commands.cc:1196 commands.cc:1221 commands.cc:2224
+#: commands.cc:2342 commands.cc:2875 commands.cc:3315
msgid "workspace"
msgstr "arbetskopia"
#: commands.cc:1168 commands.cc:1196 commands.cc:1295 commands.cc:2342
-#: commands.cc:2722 commands.cc:3314
+#: commands.cc:2722 commands.cc:3315
msgid "[PATH]..."
msgstr "[SÖKVÄG]..."
@@ -651,7 +651,8 @@ msgstr "byt namn på filer i arbetskopia
msgid "rename entries in the workspace"
msgstr "byt namn på filer i arbetskopian"
-#: commands.cc:1249 commands.cc:1262 commands.cc:3417 commands.cc:3857
+#: commands.cc:1249 commands.cc:1262 commands.cc:1342 commands.cc:3418
+#: commands.cc:3859
msgid "debug"
msgstr "felsökning"
@@ -708,13 +709,13 @@ msgstr "skriv ut angiven fil från datab
msgid "write file from database to stdout"
msgstr "skriv ut angiven fil från databasen"
-#: commands.cc:1395 commands.cc:1397 commands.cc:3528
+#: commands.cc:1395 commands.cc:1397 commands.cc:3529
#, c-format
msgid "no file '%s' found in revision '%s'\n"
msgstr "filen '%s' finns inte i revisionen '%s'\n"
#: commands.cc:1409 commands.cc:1531 commands.cc:3076 commands.cc:3125
-#: commands.cc:3214 commands.cc:3221 commands.cc:3770
+#: commands.cc:3214 commands.cc:3222 commands.cc:3772
msgid "tree"
msgstr "träd"
@@ -1224,13 +1225,13 @@ msgstr "slår ihop med revision %d av %d
msgid "merging with revision %d / %d\n"
msgstr "slår ihop med revision %d av %d\n"
-#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3244
-#: commands.cc:3245
+#: commands.cc:3101 commands.cc:3102 commands.cc:3169 commands.cc:3245
+#: commands.cc:3246
#, c-format
msgid "[source] %s\n"
msgstr "[källa] %s\n"
-#: commands.cc:3119 commands.cc:3210 commands.cc:3263
+#: commands.cc:3119 commands.cc:3210 commands.cc:3264
#, c-format
msgid "[merged] %s\n"
msgstr "[ihopslagen] %s\n"
@@ -1282,58 +1283,58 @@ msgstr "uppdatera inodeprint-cachen"
msgid "refresh the inodeprint cache"
msgstr "uppdatera inodeprint-cachen"
-#: commands.cc:3222
+#: commands.cc:3223
msgid "LEFT-REVISION RIGHT-REVISION DEST-BRANCH"
msgstr "VÄNSTERREVISION HÖGERREVISION MÅLGREN"
-#: commands.cc:3223
+#: commands.cc:3224
msgid "merge two explicitly given revisions, placing result in given branch"
msgstr ""
"slå ihop två explicit angivna revisioner, placera resultatet i angiven gren"
-#: commands.cc:3237
+#: commands.cc:3238
#, c-format
msgid "%s and %s are the same revision, aborting"
msgstr "%s och %s är samma revision, avbryter"
-#: commands.cc:3239 commands.cc:3241
+#: commands.cc:3240 commands.cc:3242
#, c-format
msgid "%s is already an ancestor of %s"
msgstr "%s är redan förfader till %s"
-#: commands.cc:3266
+#: commands.cc:3267
msgid "(revision|file|key) PARTIAL-ID"
msgstr "(revision|file|key) PARTIAL-ID"
-#: commands.cc:3267
+#: commands.cc:3268
msgid "complete partial id"
msgstr "utöka den partiella identiteten"
-#: commands.cc:3276
+#: commands.cc:3277
#, c-format
msgid "non-hex digits in partial id"
msgstr "något tecken i den partiella identiteten är inte hexadecimalt"
-#: commands.cc:3315
+#: commands.cc:3316
#, fuzzy
msgid "revert file(s), dir(s) or entire workspace (\".\")"
msgstr "återställ fil(er), katalog(er) eller hela arbetskopian (\".\")"
-#: commands.cc:3392
+#: commands.cc:3393
#, c-format
msgid "reverting %s"
msgstr "återställer %s"
-#: commands.cc:3396
+#: commands.cc:3397
#, c-format
msgid "no file version %s found in database for %s"
msgstr "filversionen %s finns inte i databasen för %s"
-#: commands.cc:3417
+#: commands.cc:3418
msgid "RCSFILE..."
msgstr "RCSFIL..."
-#: commands.cc:3418
+#: commands.cc:3419
msgid ""
"parse versions in RCS files\n"
"this command doesn't reconstruct or import revisions.you probably want "
@@ -1343,36 +1344,36 @@ msgstr ""
"detta kommando importerar inte revisioner; du vill antagligen använda\n"
"cvs_import"
-#: commands.cc:3434
+#: commands.cc:3435
msgid "rcs"
msgstr "rcs"
-#: commands.cc:3434
+#: commands.cc:3435
msgid "CVSROOT"
msgstr "CVSROOT"
-#: commands.cc:3434
+#: commands.cc:3435
msgid "import all versions in CVS repository"
msgstr "importera alla revisioner i ett CVS-arkiv"
-#: commands.cc:3497
+#: commands.cc:3498
msgid "PATH"
msgstr "SÖKVÄG"
-#: commands.cc:3498
+#: commands.cc:3499
msgid "print annotated copy of the file from REVISION"
msgstr "skriv ut filen ur REVISION med extra detaljer"
-#: commands.cc:3518
+#: commands.cc:3519
#, c-format
msgid "no revision for file '%s' in database"
msgstr "filen '%s' har ingen revision i databasen"
-#: commands.cc:3536
+#: commands.cc:3537
msgid "[FILE] ..."
msgstr "[FIL] ..."
-#: commands.cc:3537
+#: commands.cc:3538
msgid ""
"print history in reverse order (filtering by 'FILE'). If one or more\n"
"revisions are given, use them as a starting point."
@@ -1381,35 +1382,35 @@ msgstr ""
"arbetskatalogen om inga filer angivits. Om en eller flera revisioner\n"
"har angivits används de som utgångspunkter."
-#: commands.cc:3584
+#: commands.cc:3586
#, c-format
msgid "Unknown file '%s' for log command"
msgstr "Okänd fil '%s'"
-#: commands.cc:3602
+#: commands.cc:3604
#, c-format
msgid "only one of --last/--next allowed"
msgstr "enbart en av --last eller --next tillåten"
-#: commands.cc:3770
+#: commands.cc:3772
msgid "[DIRECTORY]"
msgstr "[KATALOG]"
-#: commands.cc:3770
+#: commands.cc:3772
#, fuzzy
msgid "setup a new workspace directory, default to current"
msgstr "initiera en ny arbetskatalog (nuvarande om katalog ej anges)"
-#: commands.cc:3776
+#: commands.cc:3778
#, c-format
msgid "need --branch argument for setup"
msgstr "du måste ange en gren med --branch till kommandot \"setup\""
-#: commands.cc:3790
+#: commands.cc:3792
msgid "automation"
msgstr "automatisering"
-#: commands.cc:3791
+#: commands.cc:3793
msgid ""
"interface_version\n"
"heads [BRANCH]\n"
@@ -1453,40 +1454,40 @@ msgstr ""
"get_revision [REVID]\n"
"keys\n"
-#: commands.cc:3811
+#: commands.cc:3813
msgid "automation interface"
msgstr "automatiseringsgränssnitt"
-#: commands.cc:3825 commands.cc:3841
+#: commands.cc:3827 commands.cc:3843
msgid "vars"
msgstr "variabler"
-#: commands.cc:3825
+#: commands.cc:3827
msgid "DOMAIN NAME VALUE"
msgstr "DOMÄN NAMN VÄRDE"
-#: commands.cc:3826
+#: commands.cc:3828
msgid "set the database variable NAME to VALUE, in domain DOMAIN"
msgstr "sätt databasvariabeln NAMN till VÄRDE i domänen DOMÄN"
-#: commands.cc:3841
+#: commands.cc:3843
msgid "DOMAIN NAME"
msgstr "DOMÄN NAMN"
-#: commands.cc:3842
+#: commands.cc:3844
msgid "remove the database variable NAME in domain DOMAIN"
msgstr "ta bort databasvariabeln NAMN från domänen DOMÄN"
-#: commands.cc:3853
+#: commands.cc:3855
#, c-format
msgid "no var with name %s in domain %s"
msgstr "det finns inga variabler med namnet %s i domänen %s"
-#: commands.cc:3857
+#: commands.cc:3859
msgid "REVID"
msgstr "REVID"
-#: commands.cc:3858
+#: commands.cc:3860
msgid "dump the roster associated with the given REVID"
msgstr "skriv ut den roster som hör ihop med angivet REVID"
@@ -1502,7 +1503,7 @@ msgstr "markeringar"
msgid "markings"
msgstr "markeringar"
-#: database_check.cc:319 database_check.cc:507 netsync.cc:2719
+#: database_check.cc:319 database_check.cc:507 netsync.cc:2755
#: rcs_import.cc:1226
msgid "revisions"
msgstr "revisioner"
@@ -1511,7 +1512,7 @@ msgstr "föräldraskap"
msgid "ancestry"
msgstr "föräldraskap"
-#: database_check.cc:451 netsync.cc:2723
+#: database_check.cc:451 netsync.cc:2759
msgid "keys"
msgstr "nycklar"
@@ -1780,7 +1781,7 @@ msgstr "databasen är i gott skick\n"
msgid "database is good\n"
msgstr "databasen är i gott skick\n"
-#: database.cc:134
+#: database.cc:144
#, c-format
msgid ""
"layout of database %s doesn't match this version of monotone\n"
@@ -1794,7 +1795,7 @@ msgstr ""
"(detta går inte att ångra; du vill nog ta en säkerhetskopia av databasen\n"
"först)"
-#: database.cc:158
+#: database.cc:168
#, c-format
msgid ""
"database %s contains revisions but no rosters\n"
@@ -1813,7 +1814,7 @@ msgstr ""
" sedan databasen på nytt.\n"
"ursäkta besväret."
-#: database.cc:177
+#: database.cc:187
#, c-format
msgid ""
"database %s contains manifests but no revisions\n"
@@ -1824,19 +1825,19 @@ msgstr ""
"detta är en väldigt gammal databas; den behöver uppgraderas\n"
"var god läs README.changesets för detaljer"
-#: database.cc:238
+#: database.cc:248
#, c-format
msgid "unable to probe database version in file %s"
msgstr "kunde inte hitta någon databasversion i filen %s"
-#: database.cc:245
+#: database.cc:255
#, c-format
msgid "database %s is not an sqlite version 3 file, try dump and reload"
msgstr ""
"databasen %s är inte skapad med SQLite version 3; testa att dumpa och ladda "
"på nytt"
-#: database.cc:272
+#: database.cc:282
msgid ""
"make sure database and containing directory are writeable\n"
"and you have not run out of disk space"
@@ -1845,7 +1846,7 @@ msgstr ""
"i\n"
"samt att det finns tillräckligt med ledigt utrymme på disken"
-#: database.cc:278
+#: database.cc:288
#, c-format
msgid ""
"sqlite error: %d: %s\n"
@@ -1854,12 +1855,12 @@ msgstr ""
"sqlite-fel: %d: %s\n"
"%s"
-#: database.cc:324
+#: database.cc:334
#, c-format
msgid "could not initialize database: %s: already exists"
msgstr "kunde inte initiera databasen: %s: den finns redan"
-#: database.cc:329
+#: database.cc:339
#, c-format
msgid ""
"existing (possibly stale) journal file '%s' has same stem as new database '%"
@@ -1870,12 +1871,12 @@ msgstr ""
"databasen '%s'\n"
"avbryter skapandet av databasen"
-#: database.cc:451
+#: database.cc:461
#, c-format
msgid "cannot create %s; it already exists"
msgstr "kan inte skapa %s; den finns redan"
-#: database.cc:511
+#: database.cc:521
#, c-format
msgid ""
"schema version : %s\n"
@@ -1916,52 +1917,52 @@ msgstr ""
" cert : %u\n"
" total : %u\n"
-#: database.cc:565
+#: database.cc:575
#, c-format
msgid "database schema version: %s"
msgstr "databasens schemaversion: %s"
-#: database.cc:642
+#: database.cc:652
#, c-format
msgid "multiple statements in query: %s\n"
msgstr "multipla kommandon i databasfråga: %s\n"
-#: database.cc:648
+#: database.cc:658
#, c-format
msgid "wanted %d columns got %d in query: %s\n"
msgstr "ville ha %d kolumner, fick %d i databasfråga: %s\n"
-#: database.cc:706
+#: database.cc:716
#, c-format
msgid "null result in query: %s\n"
msgstr "inget resultat med databasfråga: %s\n"
-#: database.cc:724
+#: database.cc:734
#, c-format
msgid "wanted %d rows got %s in query: %s\n"
msgstr "ville ha %d rader, fick %s i databasfråga: %s\n"
-#: database.cc:1771
+#: database.cc:1781
#, c-format
msgid "another key with name '%s' already exists"
msgstr "det finns redan en annan nyckel med namnet '%s'"
-#: database.cc:2815
+#: database.cc:2825
#, c-format
msgid "no database specified"
msgstr "ingen databas angiven"
-#: database.cc:2823
+#: database.cc:2833
#, c-format
msgid "database %s does not exist"
msgstr "databasen %s finns inte"
-#: database.cc:2824
+#: database.cc:2834
#, c-format
msgid "%s is a directory, not a database"
msgstr "%s är en katalog, inte en databas"
-#: database.cc:2849
+#: database.cc:2859
#, c-format
msgid "could not open database '%s': %s"
msgstr "kunde inte öppna databasen '%s': %s"
@@ -2344,100 +2345,109 @@ msgstr "släng attribut med den givna ny
msgid "when rosterifying, drop attrs entries with the given key"
msgstr "släng attribut med den givna nyckeln vid konvertering till 'rosters'"
-#: monotone.cc:85
+#: monotone.cc:77
+#, fuzzy
+msgid "exclude files when printing logs"
+msgstr "ta med ihopslagningar i loggen"
+
+#: monotone.cc:86
msgid "print debug log to stderr while running"
msgstr "skriv ut felsökningslogg till stderr under körning"
-#: monotone.cc:86
+#: monotone.cc:87
msgid "file to dump debugging log to, on failure"
msgstr "fil att skriva ut felsökningsloggen till om något gick fel"
-#: monotone.cc:87
+#: monotone.cc:88
+msgid "file to write the log to"
+msgstr "fil att skriva ut loggen till"
+
+#: monotone.cc:89
msgid "suppress log and progress messages"
msgstr "skriv inte ut loggar eller förloppsmeddelanden"
-#: monotone.cc:88
+#: monotone.cc:90
msgid "display help message"
msgstr "skriv ut extra hjälptext"
-#: monotone.cc:89
+#: monotone.cc:91
msgid "print version number, then exit"
msgstr "skriv ut versionsnumret och avsluta sedan omedelbart"
-#: monotone.cc:90
+#: monotone.cc:92
msgid "print detailed version number, then exit"
msgstr "skriv ut detaljerad versionsinformation och avsluta sedan omedelbart"
-#: monotone.cc:91
+#: monotone.cc:93
msgid "insert command line arguments taken from the given file"
msgstr "använd kommandoradsargument ur denna fil"
-#: monotone.cc:92
+#: monotone.cc:94
msgid "set ticker style (count|dot|none)"
msgstr "sätt stilen för förloppsinformationen (count|dot|none)"
-#: monotone.cc:93
+#: monotone.cc:95
msgid "do not load standard lua hooks"
msgstr "använd inte standard-lua-rutinerna"
-#: monotone.cc:94
+#: monotone.cc:96
msgid "do not load ~/.monotone/monotonerc or MT/monotonerc lua files"
msgstr "använd inte ~/.monotone/monotonerc eller MT/monotonerc"
-#: monotone.cc:95
+#: monotone.cc:97
msgid "load extra rc file"
msgstr "använd denna lua-fil"
-#: monotone.cc:96
+#: monotone.cc:98
msgid "set key for signatures"
msgstr "ange nyckel att signera med"
-#: monotone.cc:97
+#: monotone.cc:99
msgid "set name of database"
msgstr "ange databasens filnamn"
-#: monotone.cc:98
+#: monotone.cc:100
#, fuzzy
msgid "limit search for workspace to specified root"
msgstr "begränsa sökningen efter arbetskatalogen till denna katalog"
-#: monotone.cc:99
+#: monotone.cc:101
msgid "verbose completion output"
msgstr "ge utförlig information"
-#: monotone.cc:100
+#: monotone.cc:102
msgid "set location of key store"
msgstr "ange i vilken katalog nycklarna finns"
-#: monotone.cc:101
+#: monotone.cc:103
msgid "set location of configuration directory"
msgstr "ange i vilken katalog konfigurationsfilerna finns"
-#: monotone.cc:205
+#: monotone.cc:207
#, c-format
msgid "problem parsing arguments from file %s: %s"
msgstr "problem att tyda argumenten i filen %s: %s"
-#: monotone.cc:214
+#: monotone.cc:216
#, c-format
msgid "weird error when stuffing arguments read from %s: %s\n"
msgstr "underligt fel när argument lästa från %s stoppades in: %s\n"
-#: monotone.cc:294
+#: monotone.cc:296
msgid "[OPTION...] command [ARGS...]\n"
msgstr "[FLAGGOR...] kommando [ARGUMENT...]\n"
-#: monotone.cc:532
+#: monotone.cc:542
#, c-format
msgid "syntax error near the \"%s\" option: %s"
msgstr "syntaxfel nära flaggan \"%s\": %s"
-#: monotone.cc:571
+#: monotone.cc:581
#, c-format
msgid "monotone %s doesn't use the option %s"
msgstr "monotone %s använder inte flaggan %s"
-#: monotone.cc:606
+#: monotone.cc:616
#, c-format
msgid "Options specific to 'monotone %s':"
msgstr "Specifika flaggor för 'monotone %s':"
@@ -2885,53 +2895,53 @@ msgstr "fd %d (%s) har varit inaktiv fö
msgid "fd %d (peer %s) has been idle too long, disconnecting\n"
msgstr "fd %d (%s) har varit inaktiv för länge, kopplar ifrån\n"
-#: netsync.cc:2588
+#: netsync.cc:2610
#, c-format
msgid "beginning service on %s : %s\n"
msgstr "startar tjänst på %s : %s\n"
-#: netsync.cc:2603
+#: netsync.cc:2625
#, c-format
msgid "session limit %d reached, some connections will be refused\n"
msgstr ""
"gränsen för antalet sessioner, %d, är nådd, en del uppkopplingar kommer att "
"nekas\n"
-#: netsync.cc:2658
+#: netsync.cc:2680
#, c-format
msgid "got OOB from peer %s, disconnecting\n"
msgstr "fick OOB-data från %s, kopplar ifrån\n"
-#: netsync.cc:2713
+#: netsync.cc:2749
#, c-format
msgid "finding items to synchronize:\n"
msgstr "letar efter saker att synkronisera:\n"
-#: netsync.cc:2721
+#: netsync.cc:2757
msgid "certificates"
msgstr "certifikat"
-#: netsync.cc:2830
+#: netsync.cc:2866
#, c-format
msgid "Cannot find key '%s'"
msgstr "Kan inte hitta nyckeln '%s'"
-#: netsync.cc:2870
+#: netsync.cc:2906
#, c-format
msgid "include branch pattern contains a quote character:\n"
msgstr "grenmönstret givet med --include innehåller ett citattecken\n"
-#: netsync.cc:2871 netsync.cc:2877
+#: netsync.cc:2907 netsync.cc:2913
#, c-format
msgid "%s\n"
msgstr "%s\n"
-#: netsync.cc:2876
+#: netsync.cc:2912
#, c-format
msgid "exclude branch pattern contains a quote character:\n"
msgstr "grenmönstret givet med --exclude innehåller ett citattecken\n"
-#: netsync.cc:2899 netsync.cc:2903
+#: netsync.cc:2935 netsync.cc:2939
#, c-format
msgid "network error: %s"
msgstr "nätverksfel: %s"
@@ -3114,20 +3124,6 @@ msgstr "bygger om revisionsgrafen från
msgid "rebuilding revision graph from manifest certs\n"
msgstr "bygger om revisionsgrafen från manifestcert\n"
-#: sanity.cc:54
-#, c-format
-msgid ""
-"wrote debugging log to %s\n"
-"if reporting a bug, please include this file"
-msgstr ""
-"skrev felsökningslogg till %s\n"
-"om du rapporterar ett fel, var god bifoga den filen"
-
-#: sanity.cc:59
-#, c-format
-msgid "failed to write debugging log to %s\n"
-msgstr "misslyckades med att skriva felsökningsloggen till %s\n"
-
#: sanity.cc:116
#, c-format
msgid "fatal: formatter failed on %s:%d: %s"
@@ -3238,7 +3234,7 @@ msgstr ""
"Något gick fel när textredigeraren '%s' skulle användas för att skriva ett "
"loggmeddelande\n"
-#: std_hooks.lua:501
+#: std_hooks.lua:496
msgid "executing external 3-way merge command\n"
msgstr "använder externt 3-vägs ihopslagningskommando\n"
@@ -3290,7 +3286,7 @@ msgstr ""
"var god skicka detta felmeddelande, utskriften av 'monotone --full-version'\n"
"och en beskrivning av det du gjorde till %s.\n"
-#: ui.cc:412
+#: ui.cc:422
msgid "monotone: "
msgstr "monotone: "
@@ -3429,36 +3425,58 @@ msgstr "grundrevisionen %s finns inte i
msgid "base revision %s does not exist in database\n"
msgstr "grundrevisionen %s finns inte i databasen\n"
-#: work.cc:776 work.cc:787
+#: work.cc:771
+#, fuzzy, c-format
+msgid "dropping %s"
+msgstr "slänger cert\n"
+
+#: work.cc:782 work.cc:793
#, c-format
msgid "path %s already exists"
msgstr "sökvägen %s finns redan"
-#: work.cc:830
+#: work.cc:821 work.cc:853
#, c-format
+msgid "adding %s"
+msgstr "lägger till %s"
+
+#: work.cc:837
+#, c-format
msgid "renaming '%s' onto existing file: '%s'\n"
msgstr "byter namn på '%s' till redan existerande fil: '%s'\n"
#: work.cc:849
+#, fuzzy, c-format
+msgid "renaming %s to %s"
+msgstr "uppdaterar %s till %s"
+
+#: work.cc:865
#, c-format
msgid "file '%s' does not exist"
msgstr "filen '%s' finns inte"
-#: work.cc:850
+#: work.cc:866
#, c-format
msgid "file '%s' is a directory"
msgstr "filen '%s' är en katalog"
-#: work.cc:855
+#: work.cc:871
#, c-format
msgid "content of file '%s' has changed, not overwriting"
msgstr "innehållet i filen '%s' har ändrats, skriver inte över"
-#: work.cc:856
+#: work.cc:872
#, c-format
msgid "updating %s to %s"
msgstr "uppdaterar %s till %s"
+#~ msgid ""
+#~ "wrote debugging log to %s\n"
+#~ "if reporting a bug, please include this file"
+#~ msgstr ""
+#~ "skrev felsökningslogg till %s\n"
+#~ "om du rapporterar ett fel, var god bifoga den filen"
+
#, fuzzy
#~ msgid "adding %s to workspace delete set\n"
#~ msgstr "lägger till %s i mängden borttagna filer i arbetskopian\n"
============================================================
--- roster.cc 4547e72b235da17471b9781c3416e7eac2904027
+++ roster.cc 5313de9037e0af779b593f9f432155891a70374a
@@ -982,6 +982,11 @@ editable_roster_base::set_attr(split_pat
r.set_attr(pth, name, val);
}
+void
+editable_roster_base::commit()
+{
+}
+
namespace
{
struct true_node_id_source
@@ -2877,19 +2882,18 @@ change_automaton
}
};
-struct testing_node_id_source
- : public node_id_source
+testing_node_id_source::testing_node_id_source()
+ : curr(first_node)
+{}
+
+node_id
+testing_node_id_source::next()
{
- testing_node_id_source() : curr(first_node) {}
- virtual node_id next()
- {
- // L(FL("creating node %x\n") % curr);
- node_id n = curr++;
- I(!temp_node(n));
- return n;
- }
- node_id curr;
-};
+ // L(FL("creating node %x\n") % curr);
+ node_id n = curr++;
+ I(!temp_node(n));
+ return n;
+}
template <> void
dump(int const & i, std::string & out)
============================================================
--- roster.hh 0f6d33d17d3d1c804be21f2e8025d86e47f087f9
+++ roster.hh 0647777b7cab5a2c17419998351f049eadc706d5
@@ -143,6 +143,9 @@ downcast_to_file_t(node_t const n)
return f;
}
+bool
+shallow_equal(node_t a, node_t b, bool shallow_compare_dir_children);
+
template <> void dump(node_t const & n, std::string & out);
struct marking_t
@@ -277,6 +280,7 @@ public:
virtual void set_attr(split_path const & pth,
attr_key const & name,
attr_value const & val);
+ virtual void commit();
protected:
roster_t & r;
node_id_source & nis;
@@ -343,5 +347,17 @@ write_manifest_of_roster(roster_t const
write_manifest_of_roster(roster_t const & ros,
data & dat);
+#ifdef BUILD_UNIT_TESTS
+
+struct testing_node_id_source
+ : public node_id_source
+{
+ testing_node_id_source();
+ virtual node_id next();
+ node_id curr;
+};
+
+#endif // BUILD_UNIT_TESTS
+
#endif
============================================================
--- roster_merge.cc 4dec4aecf9c67f0ba369c9430bb492a3d93170bf
+++ roster_merge.cc aa38469bceafec9e94d2ba9c291cf08d6fc90e06
@@ -14,12 +14,8 @@ roster_merge_result::is_clean()
bool
roster_merge_result::is_clean()
{
- return node_name_conflicts.empty()
- && file_content_conflicts.empty()
- && node_attr_conflicts.empty()
- && orphaned_node_conflicts.empty()
- && rename_target_conflicts.empty()
- && directory_loop_conflicts.empty();
+ return is_clean_except_for_content()
+ && file_content_conflicts.empty();
}
bool
@@ -35,7 +31,7 @@ roster_merge_result::log_conflicts()
void
roster_merge_result::log_conflicts()
{
- L(FL("unclean mark-merge: %d name conflicts, %d content conflicts, %d attr conflicts, "
+ L(FL("unclean roster_merge: %d name conflicts, %d content conflicts, %d attr conflicts, "
"%d orphaned node conflicts, %d rename target conflicts, %d directory loop conflicts\n")
% node_name_conflicts.size()
% file_content_conflicts.size()
@@ -173,6 +169,10 @@ namespace
result = left;
return true;
}
+ MM(left_marks);
+ MM(left_uncommon_ancestors);
+ MM(right_marks);
+ MM(right_uncommon_ancestors);
bool left_wins = a_wins(right_marks, right_uncommon_ancestors);
bool right_wins = a_wins(left_marks, left_uncommon_ancestors);
// two bools means 4 cases:
@@ -214,11 +214,11 @@ namespace
inline void
insert_if_unborn(node_t const & n,
- marking_map const & marking,
+ marking_map const & markings,
std::set<revision_id> const & uncommon_ancestors,
roster_t & new_roster)
{
- revision_id const & birth = safe_get(marking, n->self).birth_revision;
+ revision_id const & birth = safe_get(markings, n->self).birth_revision;
if (uncommon_ancestors.find(birth) != uncommon_ancestors.end())
create_node_for(n, new_roster);
}
@@ -333,19 +333,18 @@ roster_merge(roster_t const & left_paren
void
roster_merge(roster_t const & left_parent,
- marking_map const & left_marking,
+ marking_map const & left_markings,
std::set<revision_id> const & left_uncommon_ancestors,
roster_t const & right_parent,
- marking_map const & right_marking,
+ marking_map const & right_markings,
std::set<revision_id> const & right_uncommon_ancestors,
roster_merge_result & result)
{
-
result.clear();
MM(left_parent);
- MM(left_marking);
+ MM(left_markings);
MM(right_parent);
- MM(right_marking);
+ MM(right_markings);
MM(result.roster);
// First handle lifecycles, by die-die-die merge -- our result will contain
@@ -362,13 +361,13 @@ roster_merge(roster_t const & left_paren
case parallel::in_left:
insert_if_unborn(i.left_data(),
- left_marking, left_uncommon_ancestors,
+ left_markings, left_uncommon_ancestors,
result.roster);
break;
case parallel::in_right:
insert_if_unborn(i.right_data(),
- right_marking, right_uncommon_ancestors,
+ right_markings, right_uncommon_ancestors,
result.roster);
break;
@@ -385,8 +384,8 @@ roster_merge(roster_t const & left_paren
node_map::const_iterator left_i, right_i;
parallel::iter<node_map> i(left_parent.all_nodes(), right_parent.all_nodes());
node_map::const_iterator new_i = result.roster.all_nodes().begin();
- marking_map::const_iterator left_mi = left_marking.begin();
- marking_map::const_iterator right_mi = right_marking.begin();
+ marking_map::const_iterator left_mi = left_markings.begin();
+ marking_map::const_iterator right_mi = right_markings.begin();
while (i.next())
{
switch (i.state())
@@ -530,11 +529,179 @@ roster_merge(roster_t const & left_paren
break;
}
}
- I(left_mi == left_marking.end());
- I(right_mi == right_marking.end());
+ I(left_mi == left_markings.end());
+ I(right_mi == right_markings.end());
I(new_i == result.roster.all_nodes().end());
}
+}
- // FIXME: looped nodes here
+#ifdef BUILD_UNIT_TESTS
+#include "unit_tests.hh"
+
+// cases for testing:
+//
+// lifecycle, file and dir
+// alive in both
+// alive in one and unborn in other (left vs. right)
+// alive in one and dead in other (left vs. right)
+//
+// mark merge:
+// same in both, same mark
+// same in both, diff marks
+// different, left wins with 1 mark
+// different, right wins with 1 mark
+// different, conflict with 1 mark
+// different, left wins with 2 marks
+// different, right wins with 2 marks
+// different, conflict with 1 mark winning, 1 mark losing
+// different, conflict with 2 marks both conflicting
+//
+// for:
+// node name, name and parent, file and dir
+// file content
+// node attr, file and dir
+//
+// attr lifecycle:
+// seen in both -- -->mark merge cases
+// live in one and unseen in other
+// dead in one and unseen in other
+//
+// two diff nodes with same name
+// directory loops
+// orphans
+// name collision on root dir
+//
+// interactions:
+// in-node name conflict + possible between-node name conflict
+// in-node name conflict + both possible names orphaned
+// in-node name conflict + directory loop conflict
+// between-node name conflict + both nodes orphaned
+// between-node name conflict + both nodes cause loop
+
+// need roster, marking, birth revs, and uncommon ancestors for each side...
+
+namespace
+{
+ const revision_id a_uncommon1 = revision_id(std::string("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
+ const revision_id a_uncommon2 = revision_id(std::string("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
+ const revision_id b_uncommon1 = revision_id(std::string("cccccccccccccccccccccccccccccccccccccccc"));
+ const revision_id b_uncommon2 = revision_id(std::string("dddddddddddddddddddddddddddddddddddddddd"));
+ const revision_id common1 = revision_id(std::string("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"));
+ const revision_id common2 = revision_id(std::string("ffffffffffffffffffffffffffffffffffffffff"));
+
+ const file_id fid1 = file_id(std::string("1111111111111111111111111111111111111111"));
+ const file_id fid2 = file_id(std::string("2222222222222222222222222222222222222222"));
+
+ split_path
+ split(std::string const & s)
+ {
+ split_path sp;
+ file_path_internal(s).split(sp);
+ return sp;
+ }
}
+static void
+make_dir(roster_t & r, marking_map & markings,
+ revision_id const & birth_rid, revision_id const & parent_name_rid,
+ std::string const & name, node_id nid)
+{
+ r.create_dir_node(nid);
+ r.attach_node(nid, split(name));
+ marking_t marking;
+ marking.birth_revision = birth_rid;
+ marking.parent_name.insert(parent_name_rid);
+ safe_insert(markings, std::make_pair(nid, marking));
+}
+
+static void
+make_file(roster_t & r, marking_map & markings,
+ revision_id const & birth_rid, revision_id const & parent_name_rid,
+ revision_id const & file_content_rid,
+ std::string const & name, file_id const & content,
+ node_id nid)
+{
+ r.create_file_node(content, nid);
+ r.attach_node(nid, split(name));
+ marking_t marking;
+ marking.birth_revision = birth_rid;
+ marking.parent_name.insert(parent_name_rid);
+ marking.file_content.insert(file_content_rid);
+ safe_insert(markings, std::make_pair(nid, marking));
+}
+
+static void
+make_lifecycle_objs(roster_t & r, marking_map & markings, revision_id uncommon,
+ std::string const & name, node_id common_dir_nid, node_id common_file_nid,
+ node_id & safe_dir_nid, node_id & safe_file_nid, node_id_source & nis)
+{
+ make_dir(r, markings, common1, common1, "common_old_dir", common_dir_nid);
+ make_file(r, markings, common1, common1, common1, "common_old_file", fid1, common_file_nid);
+ safe_dir_nid = nis.next();
+ make_dir(r, markings, uncommon, uncommon, name + "_safe_dir", safe_dir_nid);
+ safe_file_nid = nis.next();
+ make_file(r, markings, uncommon, uncommon, uncommon, name + "_safe_file", fid1, safe_file_nid);
+ make_dir(r, markings, common1, common1, name + "_dead_dir", nis.next());
+ make_file(r, markings, common1, common1, common1, name + "_dead_file", fid1, nis.next());
+}
+
+
+static void
+test_roster_merge_node_lifecycle()
+{
+ roster_t a_roster, b_roster;
+ marking_map a_markings, b_markings;
+ std::set<revision_id> a_uncommon, b_uncommon;
+ // boilerplate to get uncommon revision sets...
+ a_uncommon.insert(a_uncommon1);
+ a_uncommon.insert(a_uncommon2);
+ b_uncommon.insert(b_uncommon1);
+ b_uncommon.insert(b_uncommon2);
+ testing_node_id_source nis;
+ // boilerplate to set up a root node...
+ {
+ node_id root_nid = nis.next();
+ make_dir(a_roster, a_markings, common1, common1, "", root_nid);
+ make_dir(b_roster, b_markings, common1, common1, "", root_nid);
+ }
+ // create some nodes on each side
+ node_id common_dir_nid = nis.next();
+ node_id common_file_nid = nis.next();
+ node_id a_safe_dir_nid, a_safe_file_nid, b_safe_dir_nid, b_safe_file_nid;
+ make_lifecycle_objs(a_roster, a_markings, a_uncommon1, "a", common_dir_nid, common_file_nid,
+ a_safe_dir_nid, a_safe_file_nid, nis);
+ make_lifecycle_objs(b_roster, b_markings, b_uncommon1, "b", common_dir_nid, common_file_nid,
+ b_safe_dir_nid, b_safe_file_nid, nis);
+ // do the merge
+ roster_merge_result result;
+ roster_merge(a_roster, a_markings, a_uncommon, b_roster, b_markings, b_uncommon, result);
+ I(result.is_clean());
+ // 7 = 1 root + 2 common + 2 safe a + 2 safe b
+ I(result.roster.all_nodes().size() == 7);
+ // check that they're the right ones...
+ I(shallow_equal(result.roster.get_node(common_dir_nid),
+ a_roster.get_node(common_dir_nid), false));
+ I(shallow_equal(result.roster.get_node(common_file_nid),
+ a_roster.get_node(common_file_nid), false));
+ I(shallow_equal(result.roster.get_node(common_dir_nid),
+ b_roster.get_node(common_dir_nid), false));
+ I(shallow_equal(result.roster.get_node(common_file_nid),
+ b_roster.get_node(common_file_nid), false));
+ I(shallow_equal(result.roster.get_node(a_safe_dir_nid),
+ a_roster.get_node(a_safe_dir_nid), false));
+ I(shallow_equal(result.roster.get_node(a_safe_file_nid),
+ a_roster.get_node(a_safe_file_nid), false));
+ I(shallow_equal(result.roster.get_node(b_safe_dir_nid),
+ b_roster.get_node(b_safe_dir_nid), false));
+ I(shallow_equal(result.roster.get_node(b_safe_file_nid),
+ b_roster.get_node(b_safe_file_nid), false));
+}
+
+void
+add_roster_merge_tests(test_suite * suite)
+{
+ I(suite);
+ suite->add(BOOST_TEST_CASE(&test_roster_merge_node_lifecycle));
+}
+
+#endif // BUILD_UNIT_TESTS
============================================================
--- roster_merge.hh e9c290f799091e5ecb70e291daae0bff72df2d48
+++ roster_merge.hh 9227745f9aeb67c68ca363dc1df62537c8bcb873
@@ -116,10 +116,10 @@ roster_merge(roster_t const & left_paren
void
roster_merge(roster_t const & left_parent,
- marking_map const & left_marking,
+ marking_map const & left_markings,
std::set<revision_id> const & left_uncommon_ancestors,
roster_t const & right_parent,
- marking_map const & right_marking,
+ marking_map const & right_markings,
std::set<revision_id> const & right_uncommon_ancestors,
roster_merge_result & result);
============================================================
--- sanity.cc b31758131617cacbc373a95c25cab49e15ffedc3
+++ sanity.cc 36f79a9ba2cf13f0f96eb85a36ee0ca1619c39df
@@ -51,12 +51,12 @@ sanity::dump_buffer()
{
copy(logbuf.begin(), logbuf.end(), ostream_iterator<char>(out));
copy(gasp_dump.begin(), gasp_dump.end(), ostream_iterator<char>(out));
- ui.inform((F("wrote debugging log to %s\n"
- "if reporting a bug, please include this file")
- % filename).str());
+ ui.inform((FL("wrote debugging log to %s\n"
+ "if reporting a bug, please include this file")
+ % filename).str());
}
else
- ui.inform((F("failed to write debugging log to %s\n") % filename).str());
+ ui.inform((FL("failed to write debugging log to %s\n") % filename).str());
}
else
ui.inform("discarding debug log (maybe you want --debug or --dump?)");
============================================================
--- sanity.hh 3d91a4abd21f2af06ea78724a922b3b52fa0838f
+++ sanity.hh 88009f27365f17c86b8dd104021fbcc1cc08a497
@@ -268,15 +268,27 @@ protected:
};
+// remove_reference is a workaround for C++ defect #106.
template <typename T>
+struct remove_reference {
+ typedef T type;
+};
+
+template <typename T>
+struct remove_reference <T &> {
+ typedef typename remove_reference<T>::type type;
+};
+
+
+template <typename T>
class Musing : public MusingI, private MusingBase
{
public:
- Musing(T const & obj, char const * name, char const * file, int line, char const * func)
+ Musing(typename remove_reference<T>::type const & obj, char const * name, char const * file, int line, char const * func)
: MusingBase(name, file, line, func), obj(obj) {}
virtual void gasp(std::string & out) const;
private:
- T const & obj;
+ typename remove_reference<T>::type const & obj;
};
// The header line must be printed into the "out" string before
============================================================
--- sqlite/alter.c faf98b04050d674d06df21bcf23ded5bbff7b5b7
+++ sqlite/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091
@@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.19 2006/01/31 14:28:45 drh Exp $
+** $Id: alter.c,v 1.20 2006/02/09 02:56:03 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -541,6 +541,7 @@ void sqlite3AlterBeginAddColumn(Parse *p
for(i=0; i<pNew->nCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqliteStrDup(pCol->zName);
+ pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
}
============================================================
--- sqlite/btree.c f45f57e6cbd3b3db947cdd699db64e5215d20b2a
+++ sqlite/btree.c 23bbfb4745e549ca224f6c933a6e9bc106d77f56
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.311 2006/01/24 16:37:58 danielk1977 Exp $
+** $Id: btree.c,v 1.314 2006/02/11 01:25:51 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -411,8 +411,8 @@ struct BtCursor {
** The table that this cursor was opened on still exists, but has been
** modified since the cursor was last used. The cursor position is saved
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
-** this state, restoreOrClearCursorPosition() can be called to attempt to seek
-** the cursor to the saved position.
+** this state, restoreOrClearCursorPosition() can be called to attempt to
+** seek the cursor to the saved position.
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
@@ -756,10 +756,20 @@ static void unlockAllTables(Btree *p){
** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
** this test.
*/
-#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2)
-#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5)
-#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno)
+#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
+#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1))
+#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
+static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
+ int nPagesPerMapPage = (pBt->usableSize/5)+1;
+ int iPtrMap = (pgno-2)/nPagesPerMapPage;
+ int ret = (iPtrMap*nPagesPerMapPage) + 2;
+ if( ret==PENDING_BYTE_PAGE(pBt) ){
+ ret++;
+ }
+ return ret;
+}
+
/*
** The pointer map is a lookup table that identifies the parent page for
** each child page in the database file. The parent page is the page that
@@ -810,16 +820,19 @@ static int ptrmapPut(BtShared *pBt, Pgno
int offset; /* Offset in pointer map page */
int rc;
+ /* The master-journal page number must never be used as a pointer map page */
+ assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
+
assert( pBt->autoVacuum );
if( key==0 ){
return SQLITE_CORRUPT_BKPT;
}
- iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
if( rc!=SQLITE_OK ){
return rc;
}
- offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+ offset = PTRMAP_PTROFFSET(pBt, key);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
@@ -847,13 +860,13 @@ static int ptrmapGet(BtShared *pBt, Pgno
int offset; /* Offset of entry in pointer map */
int rc;
- iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
+ iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
if( rc!=0 ){
return rc;
}
- offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
+ offset = PTRMAP_PTROFFSET(pBt, key);
if( pEType ) *pEType = pPtrmap[offset];
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
@@ -1790,9 +1803,9 @@ int sqlite3BtreeSetCacheSize(Btree *p, i
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-int sqlite3BtreeSetSafetyLevel(Btree *p, int level){
+int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
BtShared *pBt = p->pBt;
- sqlite3pager_set_safety_level(pBt->pPager, level);
+ sqlite3pager_set_safety_level(pBt->pPager, level, fullSync);
return SQLITE_OK;
}
#endif
@@ -2344,7 +2357,7 @@ static int autoVacuumCommit(BtShared *pB
#endif
assert( pBt->autoVacuum );
- if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
+ if( PTRMAP_ISPAGE(pBt, sqlite3pager_pagecount(pPager)) ){
return SQLITE_CORRUPT_BKPT;
}
@@ -2357,15 +2370,27 @@ static int autoVacuumCommit(BtShared *pB
return SQLITE_OK;
}
+ /* This block figures out how many pages there are in the database
+ ** now (variable origSize), and how many there will be after the
+ ** truncation (variable finSize).
+ **
+ ** The final size is the original size, less the number of free pages
+ ** in the database, less any pointer-map pages that will no longer
+ ** be required, less 1 if the pending-byte page was part of the database
+ ** but is not after the truncation.
+ **/
origSize = sqlite3pager_pagecount(pPager);
- nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
+ if( origSize==PENDING_BYTE_PAGE(pBt) ){
+ origSize--;
+ }
+ nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pBt, origSize)+pgsz/5)/(pgsz/5);
finSize = origSize - nFreeList - nPtrMap;
- if( origSize>=PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
+ if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
finSize--;
- if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
- finSize--;
- }
}
+ while( PTRMAP_ISPAGE(pBt, finSize) || finSize==PENDING_BYTE_PAGE(pBt) ){
+ finSize--;
+ }
TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));
/* Variable 'finSize' will be the size of the file in pages after
@@ -2376,7 +2401,7 @@ static int autoVacuumCommit(BtShared *pB
*/
for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){
/* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
- if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
+ if( PTRMAP_ISPAGE(pBt, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
continue;
}
@@ -2434,6 +2459,7 @@ static int autoVacuumCommit(BtShared *pB
put4byte(&pBt->pPage1->aData[36], 0);
if( rc!=SQLITE_OK ) goto autovacuum_out;
*nTrunc = finSize;
+ assert( finSize!=PENDING_BYTE_PAGE(pBt) );
autovacuum_out:
assert( nRef==*sqlite3pager_stats(pPager) );
@@ -3806,7 +3832,7 @@ static int allocatePage(
*pPgno = sqlite3pager_pagecount(pBt->pPager) + 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){
+ if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
/* If *pPgno refers to a pointer-map page, allocate two new pages
** at the end of the file instead of one. The first allocated page
** becomes a new pointer-map page, the second is used by the caller.
@@ -5440,7 +5466,7 @@ int sqlite3BtreeCreateTable(Btree *p, in
/* The new root-page may not be allocated on a pointer-map page, or the
** PENDING_BYTE page.
*/
- if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
+ if( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
pgnoRoot++;
}
@@ -5713,7 +5739,7 @@ int sqlite3BtreeDropTable(Btree *p, int
if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){
maxRootPgno--;
}
- if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
+ if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){
maxRootPgno--;
}
assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
@@ -6390,11 +6416,11 @@ char *sqlite3BtreeIntegrityCheck(Btree *
** references to pointer-map pages.
*/
if( sCheck.anRef[i]==0 &&
- (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){
+ (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
}
if( sCheck.anRef[i]!=0 &&
- (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){
+ (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
}
#endif
@@ -6522,19 +6548,21 @@ int sqlite3BtreeSync(Btree *p, const cha
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeSync(Btree *p, const char *zMaster){
+ int rc = SQLITE_OK;
if( p->inTrans==TRANS_WRITE ){
BtShared *pBt = p->pBt;
-#ifndef SQLITE_OMIT_AUTOVACUUM
Pgno nTrunc = 0;
+#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
- int rc = autoVacuumCommit(pBt, &nTrunc);
- if( rc!=SQLITE_OK ) return rc;
+ rc = autoVacuumCommit(pBt, &nTrunc);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
}
- return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
#endif
- return sqlite3pager_sync(pBt->pPager, zMaster, 0);
+ rc = sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
}
- return SQLITE_OK;
+ return rc;
}
/*
============================================================
--- sqlite/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
+++ sqlite/btree.h 40055cfc09defd1146bc5b922399c035f969e56d
@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.69 2006/01/07 13:21:04 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.70 2006/02/11 01:25:51 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@@ -59,7 +59,7 @@ int sqlite3BtreeSetCacheSize(Btree*,int)
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int);
-int sqlite3BtreeSetSafetyLevel(Btree*,int);
+int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
============================================================
--- sqlite/build.c feaa61e769d7887ffeaa060d746638c7b3e994ef
+++ sqlite/build.c b46cd7d0e2daca775d9de0cba8abae1b1625caf4
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.383 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: build.c,v 1.386 2006/02/10 18:08:09 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1662,12 +1662,10 @@ int sqlite3ViewGetColumnNames(Parse *pPa
** Actually, this error is caught previously and so the following test
** should always fail. But we will leave it in place just to be safe.
*/
-#if 0
if( pTable->nCol<0 ){
sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
}
-#endif
assert( pTable->nCol>=0 );
/* If we get this far, it means we need to compute the table names.
@@ -2364,10 +2362,10 @@ void sqlite3CreateIndex(
nExtra /* Collation sequence names */
);
if( sqlite3MallocFailed() ) goto exit_create_index;
- pIndex->aiColumn = (int *)(&pIndex[1]);
+ pIndex->azColl = (char**)(&pIndex[1]);
+ pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
- pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]);
- pIndex->aSortOrder = (u8 *)(&pIndex->azColl[nCol]);
+ pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
zExtra = (char *)(&pIndex->zName[nName+1]);
strcpy(pIndex->zName, zName);
@@ -2849,6 +2847,7 @@ SrcList *sqlite3SrcListAppend(SrcList *p
pItem->zName = sqlite3NameFromToken(pTable);
pItem->zDatabase = sqlite3NameFromToken(pDatabase);
pItem->iCursor = -1;
+ pItem->isPopulated = 0;
pList->nSrc++;
return pList;
}
============================================================
--- sqlite/date.c c70a4f88e495ae2c523f6ef3848c26a021c96de8
+++ sqlite/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.53 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: date.c,v 1.54 2006/01/31 20:49:13 drh Exp $
**
** NOTES:
**
@@ -117,8 +117,8 @@ static int getDigits(const char *zDate,
zDate++;
cnt++;
}while( nextC );
+end_getDigits:
va_end(ap);
-end_getDigits:
return cnt;
}
============================================================
--- sqlite/delete.c 56ab34c3a384caa5d5ea06f5739944957e2e4213
+++ sqlite/delete.c ca404d5fd5f678e32f2f46377ad802cd0219aa99
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.120 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: delete.c,v 1.121 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -343,7 +343,7 @@ void sqlite3DeleteFrom(
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
}
delete_from_cleanup:
============================================================
--- sqlite/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9
+++ sqlite/expr.c 9c957fabf95ef62288151eecd5c490a629470666
@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.253 2006/01/30 14:36:59 drh Exp $
+** $Id: expr.c,v 1.254 2006/02/10 07:07:15 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -495,6 +495,7 @@ SrcList *sqlite3SrcListDup(SrcList *p){
pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
pNewItem->jointype = pOldItem->jointype;
pNewItem->iCursor = pOldItem->iCursor;
+ pNewItem->isPopulated = pOldItem->isPopulated;
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
pTab->nRef++;
============================================================
--- sqlite/func.c 96b26601c092b7b43a13e440e3f988b32a385f6a
+++ sqlite/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.117 2006/01/17 13:21:40 danielk1977 Exp $
+** $Id: func.c,v 1.121 2006/02/09 22:13:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -817,9 +817,9 @@ struct SumCtx {
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
- double sum; /* Sum of terms */
- int cnt; /* Number of elements summed */
- u8 seenFloat; /* True if there has been any floating point value */
+ LONGDOUBLE_TYPE sum; /* Sum of terms */
+ i64 cnt; /* Number of elements summed */
+ u8 approx; /* True if sum is approximate */
};
/*
@@ -830,18 +830,33 @@ struct SumCtx {
** 0.0 in that case. In addition, TOTAL always returns a float where
** SUM might return an integer if it never encounters a floating point
** value.
+**
+** I am told that SUM() should raise an exception if it encounters
+** a integer overflow. But after pondering this, I decided that
+** behavior leads to brittle programs. So instead, I have coded
+** SUM() to revert to using floating point if it encounters an
+** integer overflow. The answer may not be exact, but it will be
+** close. If the SUM() function returns an integer, the value is
+** exact. If SUM() returns a floating point value, it means the
+** value might be approximated.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
SumCtx *p;
int type;
assert( argc==1 );
p = sqlite3_aggregate_context(context, sizeof(*p));
- type = sqlite3_value_type(argv[0]);
+ type = sqlite3_value_numeric_type(argv[0]);
if( p && type!=SQLITE_NULL ){
- p->sum += sqlite3_value_double(argv[0]);
p->cnt++;
- if( type==SQLITE_FLOAT ){
- p->seenFloat = 1;
+ if( type==SQLITE_INTEGER ){
+ p->sum += sqlite3_value_int64(argv[0]);
+ if( !p->approx ){
+ i64 iVal;
+ p->approx = p->sum!=(LONGDOUBLE_TYPE)(iVal = (i64)p->sum);
+ }
+ }else{
+ p->sum += sqlite3_value_double(argv[0]);
+ p->approx = 1;
}
}
}
@@ -849,7 +864,7 @@ static void sumFinalize(sqlite3_context
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
if( p && p->cnt>0 ){
- if( p->seenFloat ){
+ if( p->approx ){
sqlite3_result_double(context, p->sum);
}else{
sqlite3_result_int64(context, (i64)p->sum);
@@ -870,23 +885,12 @@ static void totalFinalize(sqlite3_contex
}
/*
-** An instance of the following structure holds the context of a
-** variance or standard deviation computation.
-*/
-typedef struct StdDevCtx StdDevCtx;
-struct StdDevCtx {
- double sum; /* Sum of terms */
- double sum2; /* Sum of the squares of terms */
- int cnt; /* Number of terms counted */
-};
-
-/*
** The following structure keeps track of state information for the
** count() aggregate function.
*/
typedef struct CountCtx CountCtx;
struct CountCtx {
- int n;
+ i64 n;
};
/*
@@ -902,7 +906,7 @@ static void countFinalize(sqlite3_contex
static void countFinalize(sqlite3_context *context){
CountCtx *p;
p = sqlite3_aggregate_context(context, 0);
- sqlite3_result_int(context, p ? p->n : 0);
+ sqlite3_result_int64(context, p ? p->n : 0);
}
/*
============================================================
--- sqlite/insert.c 7e931b7f06afbcefcbbaab175c02eff8268db33f
+++ sqlite/insert.c 67b3dc11831c58d8703eb502355ad3704ee18f66
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.160 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: insert.c,v 1.161 2006/02/10 02:27:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -703,7 +703,7 @@ void sqlite3Insert(
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
}
insert_cleanup:
============================================================
--- sqlite/main.c 2693776249865dc69b97904205638e84a34a059c
+++ sqlite/main.c 9a42464c44a6532003391486e802e65e88789cfc
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.331 2006/01/24 16:37:58 danielk1977 Exp $
+** $Id: main.c,v 1.334 2006/02/09 13:43:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -29,7 +29,6 @@ const int sqlite3one = 1;
/*
** The version of the library
*/
-const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
const char sqlite3_version[] = SQLITE_VERSION;
const char *sqlite3_libversion(void){ return sqlite3_version; }
int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
@@ -732,6 +731,10 @@ int sqlite3_errcode(sqlite3 *db){
return db->errCode;
}
+/*
+** Create a new collating function for database "db". The name is zName
+** and the encoding is enc.
+*/
static int createCollation(
sqlite3* db,
const char *zName,
@@ -817,8 +820,9 @@ static int openDatabase(
** and UTF-16, so add a version for each to avoid any unnecessary
** conversions. The only error that can occur here is a malloc() failure.
*/
- if( createCollation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
- createCollation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
+ if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc) ||
+ createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc) ||
+ createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc) ||
(db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0
){
assert( sqlite3MallocFailed() );
@@ -1113,3 +1117,117 @@ void sqlite3_thread_cleanup(void){
sqlite3OsThreadSpecificData(-1);
}
}
+
+/*
+** Return meta information about a specific column of a database table.
+** See comment in sqlite3.h (sqlite.h.in) for details.
+*/
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+int sqlite3_table_column_metadata(
+ sqlite3 *db, /* Connection handle */
+ const char *zDbName, /* Database name or NULL */
+ const char *zTableName, /* Table name */
+ const char *zColumnName, /* Column name */
+ char const **pzDataType, /* OUTPUT: Declared data type */
+ char const **pzCollSeq, /* OUTPUT: Collation sequence name */