// // aegis - project change supervisor // Copyright (C) 2001-2008 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 // for assert #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) { project_ty *pp; string_ty *bl; string_ty *path; int mode; trace(("reconstruct::process(filename = \"%s\")\n{\n", src->file_name->str_text)); if (src->usage == file_usage_config) { trace(("}\n")); return; } pp = cp->pp; bl = pp->baseline_path_get(); mode = 0755 & ~project_umask_get(pp); project_become(pp); os_mkdir_between(bl, src->file_name, mode); project_become_undo(pp); path = os_path_cat(bl, 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->str_text); trace(("extract %s\n", src->edit->revision->str_text)); change_run_history_get_command(cp, src, path, 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, 0); } if (!pp->is_a_trunk()) { string_ty *path_in = 0; string_ty *path_d; static string_ty *dev_null; // // Difference the file. // if (!dev_null) dev_null = str_from_c("/dev/null"); path_d = str_format("%s,D", path->str_text); trace_string(path_d->str_text); switch (src->action) { case file_action_insulate: case file_action_transparent: assert(0); // fall through... case file_action_remove: path_in = dev_null; break; case file_action_create: case file_action_modify: #ifndef DEBUG default: #endif path_in = path; break; } change_run_diff_command(cp, up, dev_null, path_in, path_d); // // 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, 0); str_free(path_d); } str_free(path); trace(("}\n")); } void reconstruct(string_ty *project_name) { project_ty *pp; size_t j; change::pointer cp_bogus; string_ty *bl; user_ty::pointer up; // // Take some locks. // trace(("reconstruct()\n{\n")); pp = project_alloc(project_name); 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. // cp_bogus = change_alloc(pp, project_next_change_number(pp, 1)); change_bind_new(cp_bogus); change_architecture_from_pconf(cp_bogus); cp_bogus->bogus = 1; bl = pp->baseline_path_get(); change_integration_directory_set(cp_bogus, bl); up = project_user(pp); for (j = 0; ; ++j) { fstate_src_ty *src; src = pp->file_nth(j, view_path_simple); if (!src) break; process(cp_bogus, src, up); } change_free(cp_bogus); // // Write it all back out. // pp->pstate_write(); commit(); lock_release(); project_verbose(pp, 0, i18n("import complete")); project_free(pp); trace(("}\n")); }