// // aegis - project change supervisor // Copyright (C) 2001-2008, 2011, 2012, 2014 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void process(change::pointer cp, fstate_src_ty *src, user_ty::pointer up) { trace(("reconstruct::process(filename = \"%s\")\n{\n", src->file_name->str_text)); if (src->usage == file_usage_config) { trace(("}\n")); return; } project *pp = cp->project_get(); nstring bl(pp->baseline_path_get()); int mode = 0755 & ~project_umask_get(pp); project_become(pp); os_mkdir_between(bl, nstring(src->file_name), mode); project_become_undo(pp); nstring path = os_path_cat(bl, nstring(src->file_name)); trace(("src->action = %s;\n", file_action_ename(src->action))); switch (src->action) { case file_action_remove: break; case file_action_insulate: case file_action_transparent: assert(0); break; case file_action_create: case file_action_modify: #ifndef DEBUG default: #endif // // Extract the file // trace_string(path); trace(("extract %s\n", src->edit->revision->str_text)); change_run_history_get_command(cp, src, path.get_ref(), up); // // Fingerprint the file. // src->file_fp = (fingerprint_ty *)fingerprint_type.alloc(); user_ty::become scoped(pp->get_user()); change_fingerprint_same(src->file_fp, path.get_ref(), false); } if (!pp->is_a_trunk()) { // // Difference the file. // nstring dev_null = "/dev/null"; nstring path_in = dev_null; nstring path_d = path + ",D"; trace_string(path_d->str_text); switch (src->action) { case file_action_insulate: case file_action_transparent: #ifndef DEBUG default: #endif assert(!"action not present in switch"); // fall through... case file_action_remove: path_in = dev_null; break; case file_action_create: case file_action_modify: path_in = path; break; } change_run_diff_command ( cp, up, dev_null.get_ref(), path_in.get_ref(), path_d.get_ref() ); // // Fingerprint the difference file. // src->diff_file_fp = (fingerprint_ty *)fingerprint_type.alloc(); user_ty::become scoped(pp->get_user()); change_fingerprint_same(src->diff_file_fp, path_d.get_ref(), 0); } trace(("}\n")); } void reconstruct(const nstring &project_name) { // // Take some locks. // trace(("reconstruct()\n{\n")); project *pp = project_alloc(project_name.get_ref()); pp->bind_existing(); project_error(pp, 0, i18n("reconstruct baseline")); pp->pstate_lock_prepare(); project_baseline_write_lock_prepare(pp); lock_take(); // // Process each file. // change::pointer cp_bogus = change::create_bogus(pp); nstring bl(pp->baseline_path_get()); cp_bogus->integration_directory_set(bl); user_ty::pointer up = project_user(pp); for (size_t j = 0; ; ++j) { fstate_src_ty *src; src = pp->file_nth(j, view_path_simple); if (!src) break; process(cp_bogus, src, up); } // // Write it all back out. // pp->pstate_write(); commit(); lock_release(); project_verbose(pp, 0, i18n("import complete")); pp->free(); trace(("}\n")); } // vim: set ts=8 sw=4 et :