#
# delete_file "debian/compat"
#
# delete_file "debian/files"
#
# delete_file "debian/monotone.1"
#
# rename_file "contrib/Notify.pl"
# to "contrib/monotone-notify.pl"
#
# add_file "tests/t_checkout_id_sets_branch.at"
#
# add_file "tests/t_setup_checkout_modify_new_dir.at"
#
# add_file "tests/t_sticky_branch.at"
#
# add_file "tests/t_update_off_branch.at"
#
# patch "ChangeLog"
# from [1b83e56767ac8ff8c861351a650d2c46e2c08807]
# to [41f028c591c054cdc72ebcc3837baa8abc671896]
#
# patch "Makefile.am"
# from [0a4438478b5616d6f2ea9e0ab45f5642831ec383]
# to [b8121dcf5a8aecc511e437ae64e8bdfbba9e880f]
#
# patch "app_state.cc"
# from [d7d6fbd90b19c513269bb0a1b89feab31c681880]
# to [63120a266ad19ebd72022cf172ccbd0c299aa413]
#
# patch "app_state.hh"
# from [be65ffeb33feacce57408e9c43da259bb8583b15]
# to [9cfdb7a5976dc31edda11e99ee74046fdc318469]
#
# patch "cert.cc"
# from [871552c540c81b98ff7e9910f42bef787f922530]
# to [451241f5ac6f41b70211dc92aa500e36688579af]
#
# patch "commands.cc"
# from [f63e583a3a26df78f0877afd653e1d5244f5c611]
# to [958cd3bbc982aef81f63b90b24dcebaddf135166]
#
# patch "contrib/monotone-notify.pl"
# from [3ec4584fa088bf5a60e204219b01bc6ce3520e48]
# to [7b80bc10043bcd080e0a98742cd49a3c8aa7b8df]
#
# patch "cryptopp/integer.h"
# from [7b3d2d096b1f27f544339434b308fa2a756bb1e8]
# to [127faae1de80e2d8ac25f2f38866a3398bfd9723]
#
# patch "debian/docs"
# from [27b3b426e26dff78d825cbb511cbb9afbd11475c]
# to [269dde6d1f8533595c1ba331f3ecb165502a7c6a]
#
# patch "monotone.texi"
# from [b38091c6e7e77fe127975e3c5a98dd0e14290798]
# to [13bed7469b4e155326caade82d7328129accdbec]
#
# patch "rcs_import.cc"
# from [ad38b375c0cee6d0744ba0db9255b34874eebd27]
# to [4e0b292289773a83cad888d88a347d0423f1ad69]
#
# patch "tests/t_checkout_id_sets_branch.at"
# from []
# to [ea0df0caed46c80391d47ab546e3040c0d54bc1b]
#
# patch "tests/t_cvsimport.at"
# from [140f6332fd7b67c4c58055f2582ce3ee8c4d63df]
# to [a212a3cbc77e3bd78bb0bf4aea478769c93dc6d6]
#
# patch "tests/t_setup_checkout_modify_new_dir.at"
# from []
# to [d3861a3bdaf6b55792cb14000ab5e79f6b00d82b]
#
# patch "tests/t_sticky_branch.at"
# from []
# to [e07f23c47b810968535f7282238be910907a07eb]
#
# patch "tests/t_update_off_branch.at"
# from []
# to [951445e014367f691ff2d44c2018ec13a24daf7b]
#
# patch "testsuite.at"
# from [808a1d4da002cf024b623e459c05fa5b0a519288]
# to [03503ada6caff92de4120e9248a98cfacf60862d]
#
# patch "unix/terminal.cc"
# from [b7fe1f3bd20d831442ec40db67d9e1bdd2d647a0]
# to [eef0e6fbdd9455b96654b8f3842c48fbbacfc08e]
#
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,61 @@
+2005-04-13 Nathaniel Smith
+
+ * tests/t_setup_checkout_modify_new_dir.at:
+ * tests/t_update_off_branch.at: New tests.
+ * testsuite.at: Add them.
+
+ * commands.cc (checkout): Tweak branch checking logic.
+ (update): Make user explicitly switch branches.
+
+2005-04-13 Nathaniel Smith
+
+ * rcs_import.cc (import_cvs_repo): Check that user isn't trying to
+ import a whole CVS repo.
+ * tests/t_cvsimport.at: Test new check.
+
+2005-04-13 Richard Levitte
+
+ * contrib/Notify.pl: Rename ...
+ * contrib/monotone-notify.pl: ... to this.
+ * Makefile.am (EXTRA_DIST): Take note of the change.
+ * debian/docs: Distribute the contributions as well.
+ * debian/compat, debian/files, debian/monotone.1: Remove, since
+ they are self-generated by debhelper. They were obviously added
+ by mistake.
+
+2005-04-13 Nathaniel Smith
+
+ * cert.cc (guess_branch): Call app.set_branch.
+ * app_state.cc (create_working_copy): Call make_branch_sticky
+ here...
+ * commands.cc (checkout): ...instead of here.
+ (approve, disapprove, fcommit, commit): Don't call app.set_branch
+ on guess_branch's output.
+ (checkout): Call guess_branch.
+
+ * tests/t_sticky_branch.at:
+ * tests/t_checkout_id_sets_branch.at: New tests.
+ * testsuite.at: Add them.
+
+2005-04-12 Florian Weimer
+
+ * app_state.cc (app_state::allow_working_copy): Only update
+ branch_name from the options file if it has not yet been set. Log
+ the branch name.
+ (app_state::set_branch): No longer update the options map.
+ (app_state::make_branch_sticky): New function which copies the
+ stored branch name to the options map. Only commands which call
+ this function change the branch default stored in the working
+ copy.
+
+ * commands.cc (CMD(checkout)): Mark branch argument as sticky.
+ (CMD(commit)): Likewise.
+ (CMD(update)): Likewise.
+
+ * monotone.texi (Working Copy): Mention that the "commit" and
+ "update" commands update the stored default branch ("checkout"
+ does, too, but this one should be obvious).
+
2005-04-13 Matthew Gregan
* cryptopp/integer.h: Fix detection of GCC version for SSE2
builds.
--- Makefile.am
+++ Makefile.am
@@ -260,7 +260,7 @@
$(wildcard $(srcdir)/popt/test?.c) popt/testit.sh \
sqlite/keywordhash.h \
contrib/README \
- contrib/Notify.pl \
+ contrib/monotone-notify.pl \
contrib/ciabot_monotone.py \
contrib/monotone.el \
contrib/monotone.bash_completion \
--- app_state.cc
+++ app_state.cc
@@ -60,7 +60,9 @@
string dbname = absolutify(options[database_option]());
if (dbname != "") db.set_filename(mkpath(dbname));
- branch_name = options[branch_option];
+ if (branch_name().empty())
+ branch_name = options[branch_option];
+ L(F("branch name is '%s'\n") % branch_name());
internalize_rsa_keypair_id(options[key_option], signing_key);
if (!current.empty())
@@ -131,6 +133,8 @@
mkdir_p(mt);
+ make_branch_sticky();
+
write_options();
blank_user_log();
@@ -234,8 +238,12 @@
app_state::set_branch(utf8 const & branch)
{
branch_name = branch();
+}
- options[branch_option] = branch;
+void
+app_state::make_branch_sticky()
+{
+ options[branch_option] = branch_name();
}
void
--- app_state.hh
+++ app_state.hh
@@ -49,7 +49,15 @@
void set_restriction(path_set const & valid_paths, std::vector const & paths);
bool restriction_includes(file_path const & path);
+ // Set the branch name. If you only invoke set_branch, the branch
+ // name is not sticky (and won't be written to the working copy and
+ // reused by subsequent monotone invocations). Commands which
+ // switch the working to a different branch should invoke
+ // make_branch_sticky (before require_working_copy because this
+ // function updates the working copy).
void set_branch(utf8 const & name);
+ void make_branch_sticky();
+
void set_database(utf8 const & filename);
void set_signing_key(utf8 const & key);
void set_root(utf8 const & root);
--- cert.cc
+++ cert.cc
@@ -488,6 +488,7 @@
"please provide a branch name") % ident);
decode_base64(certs[0].inner().value, branchname);
+ app.set_branch(branchname());
}
}
--- commands.cc
+++ commands.cc
@@ -1329,8 +1329,7 @@
complete(app, idx(args, 0)(), r);
packet_db_writer dbw(app);
cert_value branchname;
- guess_branch (r, app, branchname);
- app.set_branch(branchname());
+ guess_branch(r, app, branchname);
N(app.branch_name() != "", F("need --branch argument for approval"));
cert_revision_in_branch(r, app.branch_name(), app, dbw);
}
@@ -1352,8 +1351,7 @@
F("revision %s has %d changesets, cannot invert\n") % r % rev.edges.size());
cert_value branchname;
- guess_branch (r, app, branchname);
- app.set_branch(branchname());
+ guess_branch(r, app, branchname);
N(app.branch_name() != "", F("need --branch argument for disapproval"));
edge_entry const & old_edge (*rev.edges.begin());
@@ -1545,8 +1543,7 @@
dbw.consume_revision_data(new_rid, rdata);
// take care of any extra certs
- guess_branch (old_rid, app, branchname);
- app.set_branch(branchname());
+ guess_branch(old_rid, app, branchname);
if (args.size() == 3)
log_message = idx(args, 2)();
@@ -1777,7 +1774,6 @@
if (args.size() == 0 || args.size() == 1)
{
N(app.branch_name() != "", F("need --branch argument for branch-based checkout"));
-
// if no checkout dir specified, use branch name
if (args.size() == 0)
dir = app.branch_name();
@@ -1796,25 +1792,29 @@
{
dir = idx(args, 1)();
complete(app, idx(args, 0)(), ident);
+
+ {
+ cert_value b;
+ guess_branch(ident, app, b);
+ }
+ {
+ I(!app.branch_name().empty());
+ cert_value branch_name(app.branch_name());
+ base64 branch_encoded;
+ encode_base64(branch_name, branch_encoded);
+
+ vector< revision > certs;
+ app.db.get_revision_certs(ident, branch_cert_name, branch_encoded, certs);
+
+ L(F("found %d %s branch certs on revision %s\n")
+ % certs.size()
+ % app.branch_name
+ % ident);
+
+ N(certs.size() != 0, F("revision %s is not a member of branch %s\n")
+ % ident % app.branch_name);
+ }
- if (!app.branch_name().empty())
- {
- cert_value branch_name(app.branch_name());
- base64 branch_encoded;
- encode_base64(branch_name, branch_encoded);
-
- vector< revision > certs;
- app.db.get_revision_certs(ident, branch_cert_name, branch_encoded, certs);
-
- L(F("found %d %s branch certs on revision %s\n")
- % certs.size()
- % app.branch_name
- % ident);
-
- N(certs.size() != 0, F("revision %s is not a member of branch %s\n")
- % ident % app.branch_name);
- }
-
app.create_working_copy(dir);
}
@@ -2549,6 +2549,7 @@
revision_id rid;
manifest_map m_old, m_new;
+ app.make_branch_sticky();
app.require_working_copy();
// preserve excluded work for future commmits
@@ -2563,8 +2564,7 @@
cert_value branchname;
I(rs.edges.size() == 1);
- guess_branch (edge_old_revision(rs.edges.begin()), app, branchname);
- app.set_branch(branchname());
+ guess_branch(edge_old_revision(rs.edges.begin()), app, branchname);
P(F("beginning commit on branch '%s'\n") % branchname);
L(F("new manifest %s\n") % rs.new_manifest);
@@ -3112,6 +3112,8 @@
if (args.size() != 0 && args.size() != 1)
throw usage(name);
+ if (!app.branch_name().empty())
+ app.make_branch_sticky();
app.require_working_copy();
calculate_current_revision(app, r_working, m_old, m_working);
@@ -3147,8 +3149,24 @@
P(F("already up to date at %s\n") % r_old_id);
return;
}
+
+ P(F("selected update target %s\n") % r_chosen_id);
- P(F("selected update target %s\n") % r_chosen_id);
+ if (!app.branch_name().empty())
+ {
+ cert_value branch_name(app.branch_name());
+ base64 branch_encoded;
+ encode_base64(branch_name, branch_encoded);
+
+ vector< revision > certs;
+ app.db.get_revision_certs(r_chosen_id, branch_cert_name, branch_encoded, certs);
+
+ N(certs.size() != 0,
+ F("revision %s is not a member of branch %s\n"
+ "try again with explicit --branch\n")
+ % r_chosen_id % app.branch_name);
+ }
+
app.db.get_revision_manifest(r_chosen_id, m_chosen_id);
app.db.get_manifest(m_chosen_id, m_chosen);
--- contrib/monotone-notify.pl
+++ contrib/monotone-notify.pl
@@ -624,11 +624,12 @@
=head1 NAME
-Notify.pl - a script to send monotone change notifications by email
+monotone-notify.pl - a script to send monotone change notifications by email
=head1 SYNOPSIS
-Notify.pl [--help] [--man] [--db=database] [--root=path] [--branch=branch ...]
+monotone-notify.pl [--help] [--man]
+[--db=database] [--root=path] [--branch=branch ...]
[--[no]update] [--[no]mail] [--[no]attachments]
[--from=email-sender]
[--difflogs-to=email-recipient] [--nodifflogs-to=email-recipient]
@@ -637,9 +638,10 @@
=head1 DESCRIPTION
-B is used to generate emails containing monotone change
-logs for recent changes. It uses monotone database variables in the
-domain 'notify' to keep track of the latest revisions already logged.
+B is used to generate emails containing monotone
+change logs for recent changes. It uses monotone database variables
+in the domain 'notify' to keep track of the latest revisions already
+logged.
=head1 OPTIONS
@@ -672,8 +674,8 @@
=item B<--update>
-Has Notify.pl update the database variables at the end of the run.
-This is the default unless B<--debug> is given.
+Has B update the database variables at the end of
+the run. This is the default unless B<--debug> is given.
=item B<--noupdate>
@@ -682,8 +684,8 @@
=item B<--mail>
-Has Notify.pl send the constructed logs as emails. This is the
-default unless B<--debug> is given.
+Has B send the constructed logs as emails. This
+is the default unless B<--debug> is given.
=item B<--nomail>
@@ -742,15 +744,15 @@
=item B<--debug>
-Makes Notify.pl go to debug mode. It means a LOT of extra output, and
-also implies B<--noupdate> and B<--nomail> unless specified
-differently on the command line.
+Makes B go to debug mode. It means a LOT of extra
+output, and also implies B<--noupdate> and B<--nomail> unless
+specified differently on the command line.
=item B<--quiet>
-Makes Notify.pl really silent. It will normally produce a small log
-of it's activities, but with B<--quiet>, it will only output error
-messages. If B<--debug> was given, B<--quiet> is turned off
+Makes B really silent. It will normally produce a
+small log of it's activities, but with B<--quiet>, it will only output
+error messages. If B<--debug> was given, B<--quiet> is turned off
unconditionally.
=back
@@ -763,12 +765,12 @@
other means to move changes from one branch to another.
This behavior isn't entirely deterministic, as it depends on when the
-last run of Notify.pl was done, and what head revisions were active at
-that time. It might be seen as a bug, but if corrected, it might miss
-out on development that moves entirely to another branch and moves
-back later in time, thereby creating a hole in the branch currently
-looked at. This has actually happened in the development of monotone
-itself.
+last run of B was done, and what head revisions
+were active at that time. It might be seen as a bug, but if
+corrected, it might miss out on development that moves entirely to
+another branch and moves back later in time, thereby creating a hole
+in the branch currently looked at. This has actually happened in the
+development of monotone itself.
For now, it's assumed that a little too much information is better
than (unjust) lack of information.
--- cryptopp/integer.h
+++ cryptopp/integer.h
@@ -26,7 +26,7 @@
#endif
// SSE2 intrinsics work in GCC 3.3 or later
-#if defined(__SSE2__) && __GNUC_PREREQ (3,3)
+#if defined(__SSE2__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2))
#define SSE2_INTRINSICS_AVAILABLE
#endif
--- debian/docs
+++ debian/docs
@@ -1,3 +1,4 @@
NEWS
README
html
+contrib
--- monotone.texi
+++ monotone.texi
@@ -3288,6 +3288,10 @@
If the commit is successful, the @file{MT/log} file is cleared of
all content making it ready for another edit/commit cycle.
+If a @option{--branch} option is specified, the @command{commit} command
+commits to this branch (creating it if necessary). The branch becomes
+the new default branch of the working copy.
+
The @command{commit} command also synthesizes a number of
certificates, which it attaches to the new manifest version and copies
into your database:
@@ -3364,6 +3368,11 @@
specified, with your local changes (and only your local changes)
applied.
+If a @option{--branch} option is specified, the @command{update} command
+tries to select the revision to update to from this branch. The branch
+becomes the new default branch of the working copy (even if you also
+specify an explicit @var{revision} argument).
+
@end ftable
@page
--- rcs_import.cc
+++ rcs_import.cc
@@ -79,8 +79,8 @@
otherit = other.files.find(it->first);
if (otherit != other.files.end() && it->second!=otherit->second)
{
- L(F("!similar_enough: %d/%d\n") % id % other.id);
- return false;
+ L(F("!similar_enough: %d/%d\n") % id % other.id);
+ return false;
}
else if (otherit != other.files.end())
{
@@ -1285,6 +1285,10 @@
import_cvs_repo(fs::path const & cvsroot,
app_state & app)
{
+ N(!fs::exists(cvsroot / "CVSROOT"),
+ F("%s appears to be a CVS repository root directory\n"
+ "try importing a module instead, with 'cvs_import %s/")
+ % cvsroot.native_directory_string() % cvsroot.native_directory_string());
{
// early short-circuit to avoid failure after lots of work
--- tests/t_checkout_id_sets_branch.at
+++ tests/t_checkout_id_sets_branch.at
@@ -0,0 +1,27 @@
+AT_SETUP([checkout without --branch sets branch])
+MONOTONE_SETUP
+
+ADD_FILE(foo, [blah blah
+])
+COMMIT(testbranch)
+REV=`BASE_REVISION`
+
+AT_CHECK(MONOTONE checkout $REV codir1, [], [ignore], [ignore])
+AT_CHECK(cmp foo codir1/foo)
+AT_DATA(codir1/foo, [hi maude
+])
+# verify that no branch is needed for commit
+AT_CHECK(cd codir1 && MONOTONE commit --message=foo, [], [ignore], [ignore])
+
+AT_CHECK(MONOTONE cert $REV branch otherbranch)
+
+# but, now we can't checkout without a --branch...
+# need to make sure don't pick up branch from our local MT dir...
+AT_CHECK(rm -rf MT)
+AT_CHECK(MONOTONE checkout $REV codir2, [1], [ignore], [ignore])
+AT_CHECK(MONOTONE checkout $REV --branch=testbranch codir3, [], [ignore], [ignore])
+AT_CHECK(cmp foo codir3/foo)
+AT_CHECK(MONOTONE checkout $REV --branch=otherbranch codir4, [], [ignore], [ignore])
+AT_CHECK(cmp foo codir4/foo)
+
+AT_CLEANUP
--- tests/t_cvsimport.at
+++ tests/t_cvsimport.at
@@ -46,6 +46,9 @@
# import into monotone and check presence of files
+# safety check -- we stop people from accidentally feeding their whole
+# repo to cvs_import instead of just a module.
+AT_CHECK(MONOTONE --branch=testbranch cvs_import $CVSROOT, [1], [ignore], [ignore])
AT_CHECK(MONOTONE --branch=testbranch cvs_import $CVSROOT/testdir, [], [ignore], [ignore])
AT_CHECK(MONOTONE cat file $TSHA0, [], [ignore])
AT_CHECK(MONOTONE cat file $TSHA1, [], [ignore])
--- tests/t_setup_checkout_modify_new_dir.at
+++ tests/t_setup_checkout_modify_new_dir.at
@@ -0,0 +1,30 @@
+AT_SETUP([setup/checkout touch new MT/options only])
+MONOTONE_SETUP
+
+ADD_FILE(foo, [blah blah
+])
+COMMIT(testbranch)
+
+# okay, now wd is on testbranch
+
+# setup a dir on otherbranch and make sure we stay on testbranch
+AT_CHECK(MONOTONE setup setupdir --branch=otherbranch, [], [ignore], [ignore])
+SET_FILE(foo, [stuff stuff
+])
+AT_CHECK(MONOTONE commit --message=foo, [], [ignore], [ignore])
+CHECK_SAME_STDOUT(BASE_REVISION, MONOTONE automate heads testbranch)
+
+# now create a revision in otherbranch...
+AT_DATA(setupdir/blah, [yum yum
+])
+AT_CHECK(cd setupdir && MONOTONE add blah, [], [ignore], [ignore])
+AT_CHECK(cd setupdir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+# and check it out
+AT_CHECK(MONOTONE checkout codir --branch=otherbranch, [], [ignore], [ignore])
+# and make sure we still stayed on testbranch
+SET_FILE(foo, [more more
+])
+AT_CHECK(MONOTONE commit --message=foo, [], [ignore], [ignore])
+CHECK_SAME_STDOUT(BASE_REVISION, MONOTONE automate heads testbranch)
+
+AT_CLEANUP
--- tests/t_sticky_branch.at
+++ tests/t_sticky_branch.at
@@ -0,0 +1,67 @@
+AT_SETUP([sticky branches])
+MONOTONE_SETUP
+
+# setup saves given branch
+AT_CHECK(MONOTONE setup setupdir --branch=testbranch, [], [ignore], [ignore])
+AT_DATA(setupdir/foo, [blah blah
+])
+AT_CHECK(cd setupdir && MONOTONE add foo, [], [ignore], [ignore])
+AT_CHECK(cd setupdir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+
+# checkout saves given branch
+AT_CHECK(MONOTONE checkout --branch=testbranch codir, [], [ignore], [ignore])
+AT_CHECK(cmp setupdir/foo codir/foo)
+AT_DATA(codir/foo, [other other
+])
+AT_CHECK(cd codir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+
+# log doesn't affect given branch
+AT_CHECK(cd codir && MONOTONE log --branch=otherbranch, [], [ignore], [ignore])
+AT_DATA(codir/foo, [more more
+])
+AT_CHECK(cd codir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+AT_CHECK(MONOTONE ls branches, [], [testbranch
+], [])
+
+# commit saves given branch
+AT_DATA(codir/foo, [newbranch newbranch
+])
+AT_CHECK(cd codir && MONOTONE commit --branch=otherbranch --message=foo, [], [ignore], [ignore])
+AT_DATA(codir/foo, [newbranch 2 newbranch 2
+])
+AT_CHECK(cd codir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+AT_CHECK(MONOTONE checkout --branch=otherbranch otherdir, [], [ignore], [ignore])
+AT_CHECK(cmp codir/foo otherdir/foo)
+
+# update saves the given branch
+AT_CHECK(MONOTONE checkout --branch=testbranch updir, [], [ignore], [ignore])
+AT_CHECK(cd updir && MONOTONE update --branch=otherbranch, [], [ignore], [ignore])
+AT_CHECK(cmp otherdir/foo updir/foo)
+AT_DATA(otherdir/foo, [yet another chunk of entropy
+])
+AT_CHECK(cd otherdir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+AT_CHECK(cd updir && MONOTONE update, [], [ignore], [ignore])
+AT_CHECK(cmp otherdir/foo updir/foo)
+
+# merge doesn't affect given branch
+AT_CHECK(MONOTONE setup third1, [], [ignore], [ignore])
+AT_DATA(third1/a, [1a
+])
+AT_CHECK(cd third1 && MONOTONE add a, [], [ignore], [ignore])
+AT_CHECK(cd third1 && MONOTONE commit --branch=third --message=foo, [], [ignore], [ignore])
+AT_CHECK(MONOTONE setup third2, [], [ignore], [ignore])
+AT_DATA(third2/b, [2b
+])
+AT_CHECK(cd third2 && MONOTONE add b, [], [ignore], [ignore])
+AT_CHECK(cd third2 && MONOTONE commit --branch=third --message=foo, [], [ignore], [ignore])
+AT_CHECK(cd codir && MONOTONE merge --branch=third, [], [ignore], [ignore])
+AT_CHECK(MONOTONE automate heads third, [], [stdout], [ignore])
+AT_CHECK(mv stdout old-third-heads)
+AT_DATA(codir/foo, [more more
+])
+AT_CHECK(cd codir && MONOTONE commit --message=foo, [], [ignore], [ignore])
+# we check that this didn't create a new head of branch third
+AT_CHECK(MONOTONE automate heads third, [], [stdout], [ignore])
+AT_CHECK(cmp stdout old-third-heads)
+
+AT_CLEANUP
--- tests/t_update_off_branch.at
+++ tests/t_update_off_branch.at
@@ -0,0 +1,18 @@
+AT_SETUP([update to off-branch rev])
+MONOTONE_SETUP
+
+ADD_FILE(testfile, [blah blah
+])
+COMMIT(testbranch)
+TR=`BASE_REVISION`
+
+SET_FILE(testfile, [other other
+])
+COMMIT(otherbranch)
+OR=`BASE_REVISION`
+
+AT_CHECK(MONOTONE checkout --branch=testbranch $TR codir, [], [ignore], [ignore])
+AT_CHECK(cd codir && MONOTONE update $OR, [1], [ignore], [ignore])
+AT_CHECK(cd codir && MONOTONE update --branch=otherbranch $OR, [], [ignore], [ignore])
+
+AT_CLEANUP
--- testsuite.at
+++ testsuite.at
@@ -546,3 +546,7 @@
m4_include(tests/t_inodeprints_update.at)
m4_include(tests/t_ls_known.at)
m4_include(tests/t_cvsimport_samelog.at)
+m4_include(tests/t_sticky_branch.at)
+m4_include(tests/t_checkout_id_sets_branch.at)
+m4_include(tests/t_update_off_branch.at)
+m4_include(tests/t_setup_checkout_modify_new_dir.at)
--- unix/terminal.cc
+++ unix/terminal.cc
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include