#
# patch "ChangeLog"
# from [1ca0c140585eb24f3192496cb9194d1cde27c84b]
# to [8263954b8157f8429b731690a4f44795114d3caf]
#
# patch "commands.cc"
# from [42a9854e615fff7b96075632e07cb88a6d12ae29]
# to [5c9d5557618af9fc3447467688a61189c4727014]
#
# patch "manifest.cc"
# from [aefd8d086360ea7349a541e2dfc0f4f7c28d9913]
# to [e42a9ec927beb106fe6c251005eb6901a552199e]
#
# patch "manifest.hh"
# from [2665667c3cf960e64f39301fea45d1e4e67e5dba]
# to [32ecf7dfe6decb959f38856418e5e572afa82cd2]
#
# patch "revision.hh"
# from [95b50ede90037557fd0fbbfad6a9fdd67b0bf413]
# to [9600fe27d3ee00d922d158b0fe2e3abb6a1a56fb]
#
# patch "tests/t_status_missing.at"
# from [b4a0e1fa174b845f6e58c10db2fcf38ffbcc14ab]
# to [72d595bef8c751173ddf45eeaae5083e97cb1dc1]
#
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,13 @@
+2005-04-22 Derek Scherger
+
+ * manifest.{cc,hh} (build_restricted_manifest_map): keep and
+ return a set of missing files rather than failing on first missing
+ file
+ * commands.cc (calculate_restricted_revision): handle set of
+ missing files
+ * revision.hh: update comment on the format of a revision
+ * tests/t_status_missing.at: un-XFAIL and add a few tests
+
2005-04-21 Jeremy Cowgar
* tests/t_multiple_heads_msg.at: Now checks to ensure 'multiple head'
--- commands.cc
+++ commands.cc
@@ -538,6 +538,7 @@
revision_set & rev,
manifest_map & m_old,
manifest_map & m_new,
+ path_set & missing_files,
change_set::path_rearrangement & restricted_work)
{
manifest_id old_manifest_id;
@@ -570,7 +571,7 @@
cs->rearrangement = included;
restricted_work = excluded;
- build_restricted_manifest_map(new_paths, m_old, m_new, app);
+ build_restricted_manifest_map(new_paths, m_old, m_new, missing_files, app);
complete_change_set(m_old, m_new, *cs);
calculate_ident(m_new, rev.new_manifest);
@@ -578,6 +579,7 @@
rev.edges.insert(make_pair(old_revision_id,
make_pair(old_manifest_id, cs)));
+
}
static void
@@ -585,6 +587,27 @@
vector const & args,
revision_set & rev,
manifest_map & m_old,
+ manifest_map & m_new,
+ change_set::path_rearrangement & restricted_work)
+{
+ path_set missing_files;
+ calculate_restricted_revision(app, args, rev, m_old, m_new, missing_files, restricted_work);
+
+ for (path_set::const_iterator i = missing_files.begin();
+ i != missing_files.end(); ++i)
+ {
+ W(F("missing %s") % (*i)());
+ }
+
+ N(missing_files.size() == 0,
+ F("%d missing files\n") % missing_files.size());
+}
+
+static void
+calculate_restricted_revision(app_state & app,
+ vector const & args,
+ revision_set & rev,
+ manifest_map & m_old,
manifest_map & m_new)
{
change_set::path_rearrangement work;
--- manifest.cc
+++ manifest.cc
@@ -63,19 +63,25 @@
build_restricted_manifest_map(path_set const & paths,
manifest_map const & m_old,
manifest_map & m_new,
+ path_set & missing_files,
app_state & app)
{
m_new.clear();
inodeprint_map ipm;
+
if (in_inodeprints_mode())
{
data dat;
read_inodeprints(dat);
read_inodeprint_map(dat, ipm);
}
+
for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
{
- if (app.restriction_includes(*i))
+ bool exists = fs::exists(mkpath((*i)()));
+ bool included = app.restriction_includes(*i);
+
+ if (included && exists)
{
// compute the current sha1 id for included files
// we might be able to avoid it, if we have an inode fingerprint...
@@ -94,12 +100,20 @@
}
}
// ...ah, well, no good fingerprint, just check directly.
- N(fs::exists(mkpath((*i)())),
- F("file disappeared but exists in new manifest: %s") % (*i)());
hexenc ident;
calculate_ident(*i, ident, app.lua);
m_new.insert(manifest_entry(*i, file_id(ident)));
}
+ else if (included && !exists)
+ {
+ missing_files.insert(*i);
+
+ // copy the old manifest entry for missing files
+ manifest_map::const_iterator old = m_old.find(*i);
+ N(old != m_old.end(),
+ F("file missing but does not exist in old manifest: %s") % *i);
+ m_new.insert(*old);
+ }
else
{
// copy the old manifest entry for excluded files
--- manifest.hh
+++ manifest.hh
@@ -77,6 +77,7 @@
void build_restricted_manifest_map(path_set const & paths,
manifest_map const & m_old,
manifest_map & m_new,
+ path_set & missing_files,
app_state & app);
void read_manifest_map(data const & dat,
--- revision.hh
+++ revision.hh
@@ -20,37 +20,31 @@
// sub-components are separately serialized (they could be but there is no
// call for it). a grammar (aside from the parsing code) for the serialized
// form will show up here eventually. until then, here is an example.
+// form will show up here eventually. until then, here is an example.
//
-// revision:
-// {
-// new_manifest: [71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc]
-// edge:
-// {
-// old_revision: [71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc]
-// old_manifest: [71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc]
-// change_set:
-// {
-// paths:
-// {
-// rename_file:
-// {
-// src: "usr/bin/sh"
-// dst: "usr/bin/foo"
-// }
-// delete_dir: "usr/bin"
-// add_file: "tmp/foo/bar.txt"
-// }
-// deltas:
-// {
-// delta:
-// {
-// path: "tmp/foo/bar.txt"
-// src: [71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc]
-// dst: [71e0274f16cd68bdf9a2bf5743b86fcc1e597cdc]
-// }
-// }
-// }
-// }
+// new_manifest [16afa28e8783987223993d67f54700f0ecfedfaa]
+//
+// old_revision [d023242b16cbdfd46686a5d217af14e3c339f2b4]
+// old_manifest [2dc4a99e27a0026395fbd4226103614928c55c77]
+//
+// delete_file "deleted-file.cc"
+//
+// rename_file "old-file.cc"
+// to "new-file.cc"
+//
+// add_file "added-file.cc"
+//
+// patch "added-file.cc"
+// from []
+// to [da39a3ee5e6b4b0d3255bfef95601890afd80709]
+//
+// patch "changed-file.cc"
+// from [588fd8a7bcde43a46f0bde1dd1d13e9e77cf25a1]
+// to [559133b166c3154c864f912e9f9452bfc452dfdd]
+//
+// patch "new-file.cc"
+// from [95b50ede90037557fd0fbbfad6a9fdd67b0bf413]
+// to [bd39086b9da776fc22abd45734836e8afb59c8c0]
extern std::string revision_file_name;
--- tests/t_status_missing.at
+++ tests/t_status_missing.at
@@ -1,19 +1,24 @@
AT_SETUP([(normal) status with missing files])
MONOTONE_SETUP
-# This test is a bug report.
-AT_XFAIL_IF(true)
-
-ADD_FILE(testfile, [foo
+ADD_FILE(testfile1, [foo
])
+ADD_FILE(testfile2, [bar
+])
COMMIT(testbranch)
-AT_CHECK(rm -f testfile)
+AT_CHECK(rm -f testfile1)
+AT_CHECK(rm -f testfile2)
# status should successfully report on the status of things regardless
# of the status of those things -- i.e. it should report missing files
# as such rather than failing on them.
-AT_CHECK(MONOTONE status, [0], [ignore], [ignore])
+# status should list all missing files before failing
+# if/when there are missing files
+AT_CHECK(MONOTONE status, [1], [ignore], [stderr])
+AT_CHECK(grep testfile1 stderr, [], [ignore], [ignore])
+AT_CHECK(grep testfile2 stderr, [], [ignore], [ignore])
+
AT_CLEANUP