# # # patch "cmd_db.cc" # from [817d6efef439b40502eec5b8d7adc678758e032d] # to [6a53f8c43ec53a7c59d7762889efda9c720cac87] # # patch "database.cc" # from [15e02283dd92688ab83eee556e4b8b0eb5500554] # to [8d0e1cf1db07ba61bd878f65a9e36da81db25bfd] # # patch "tests/db_kill_certs_locally/__driver__.lua" # from [23e4a6565a97a0882eb001fba64c2a7c4fc07073] # to [f086f265480052907b09f15a6376a5b2596610a7] # ============================================================ --- cmd_db.cc 817d6efef439b40502eec5b8d7adc678758e032d +++ cmd_db.cc 6a53f8c43ec53a7c59d7762889efda9c720cac87 @@ -262,6 +262,8 @@ CMD(db_kill_certs_locally, "kill_certs_l transaction_guard guard(db); + set branches; + if (args.size() == 2) { L(FL("deleting all certs named '%s' on %d revisions") @@ -269,6 +271,16 @@ CMD(db_kill_certs_locally, "kill_certs_l for (set::const_iterator r = revisions.begin(); r != revisions.end(); ++r) { + if (name == branch_cert_name) + { + vector to_delete; + db.get_revision_certs(*r, name, to_delete); + for (vector::const_iterator i = to_delete.begin(); + i != to_delete.end(); ++i) + { + branches.insert(i->value); + } + } db.delete_certs_locally(*r, name); } } @@ -282,7 +294,19 @@ CMD(db_kill_certs_locally, "kill_certs_l { db.delete_certs_locally(*r, name, value); } + branches.insert(value); } + + for (set::const_iterator i = branches.begin(); + i != branches.end(); ++i) + { + db.recalc_branch_leaves(*i); + set leaves; + db.get_branch_leaves(*i, leaves); + if (leaves.empty()) + db.clear_epoch(typecast_vocab(*i)); + } + guard.commit(); } ============================================================ --- database.cc 15e02283dd92688ab83eee556e4b8b0eb5500554 +++ database.cc 8d0e1cf1db07ba61bd878f65a9e36da81db25bfd @@ -3108,6 +3108,7 @@ void database::delete_certs_locally(revi { imp->execute(query("DELETE FROM revision_certs WHERE revision_id = ? AND name = ?") % blob(rev.inner()()) % text(name())); + imp->cert_stamper.note_change(); } void database::delete_certs_locally(revision_id const & rev, cert_name const & name, @@ -3115,6 +3116,7 @@ void database::delete_certs_locally(revi { imp->execute(query("DELETE FROM revision_certs WHERE revision_id = ? AND name = ? AND value = ?") % blob(rev.inner()()) % text(name()) % blob(value())); + imp->cert_stamper.note_change(); } // crypto key management ============================================================ --- tests/db_kill_certs_locally/__driver__.lua 23e4a6565a97a0882eb001fba64c2a7c4fc07073 +++ tests/db_kill_certs_locally/__driver__.lua f086f265480052907b09f15a6376a5b2596610a7 @@ -20,6 +20,10 @@ check(qgrep("testbranch", "stdout")) check(qgrep("somebranch", "stdout")) check(qgrep("testbranch", "stdout")) +check(mtn("db", "set_epoch", "somebranch", string.rep("1234567890",4))) +check(mtn("ls", "epochs"), 0, true) +check(qgrep("somebranch", "stdout")) + check(mtn("cert", "b:somebranch", "branch", "otherbranch"), 0, nil, false) check(mtn("ls", "branches"), 0, true) @@ -31,6 +35,8 @@ check(mtn("db", "kill_certs_locally", "i check(qgrep(rev2, "stdout")) check(mtn("db", "kill_certs_locally", "i:", "branch", "somebranch"), 0, nil, false) +check(mtn("ls", "epochs"), 0, true) +check(not qgrep("somebranch", "stdout")) check(mtn("ls", "branches"), 0, true) check(not qgrep("somebranch", "stdout")) @@ -50,3 +56,11 @@ check(mtn("ls", "tags")) check(mtn("db", "kill_certs_locally", "t:*", "tag"), 0, nil, false) check(mtn("ls", "tags")) + +-- check that branch heads get handled correctly +check(mtn("heads", "-b", "otherbranch"), 0, true, false) +check(qgrep(rev2, "stdout")) +check(mtn("db", "kill_certs_locally", "h:otherbranch", "branch", "otherbranch"), 0, nil, false) +check(mtn("heads", "-b", "otherbranch"), 0, true, false) +check(not qgrep(rev2, "stdout")) +check(qgrep(rev1, "stdout")) \ No newline at end of file