//
// 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 :