//
// aegis - project change supervisor
// Copyright (C) 2005-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
#include // for assert
#include
#include
#include
#include
bool
change_file_promote(change::pointer cp)
{
trace(("change_file_promote(cp = %08lX)\n{\n", (long)cp));
bool changed = false;
nstring_list remove_later;
for (size_t j = 0; ; ++j)
{
//
// find the relevant change src data
//
fstate_src_ty *c_src_data = change_file_nth(cp, j, view_path_first);
if (!c_src_data)
break;
trace(("c_src_data = %08lX\n", (long)c_src_data));
trace(("action = %s\n", file_action_ename(c_src_data->action)));
trace(("usage = %s\n", file_usage_ename(c_src_data->usage)));
//
// locate the equivalent project file
//
fstate_src_ty *p_src_data =
project_file_find(cp->pp, c_src_data->file_name, view_path_extreme);
trace(("p_src_data = %08lX\n", (long)p_src_data));
////////////////////////////////////////////////////////////////
// //
// FIXME: we have to cope with the case where files have //
// been MOVED in the baseline, not just created and deleted. //
// A moved file we are modifying means the file in the //
// development directory must be physicall moved to reflect //
// the change in the baseline. //
// //
// There is a similar issue with removing a file that has //
// been renamed from under the change, you have to switch to //
// removing the new name. //
// //
////////////////////////////////////////////////////////////////
//
// Look for inconsistencies.
//
switch (c_src_data->action)
{
case file_action_create:
//
// check if someone created it ahead of you
//
if (p_src_data)
{
trace(("action = %s\n", file_action_ename(c_src_data->action)));
trace(("usage = %s\n", file_usage_ename(c_src_data->usage)));
switch (p_src_data->action)
{
case file_action_create:
case file_action_modify:
case file_action_insulate:
{
trace(("create -> modify\n"));
changed = true;
sub_context_ty sc;
sc.var_set_string("File_Name", c_src_data->file_name);
change_verbose
(
cp,
&sc,
i18n("warning: $filename in baseline, copying")
);
c_src_data->action = file_action_modify;
if (p_src_data->edit_origin)
{
c_src_data->edit_origin =
history_version_copy(p_src_data->edit);
}
if (!c_src_data->uuid && p_src_data->uuid)
c_src_data->uuid = str_copy(p_src_data->uuid);
if (!str_equal(c_src_data->uuid, p_src_data->uuid))
{
// fixme: we come here if an UUID clash is
// present (the previous test failed). Must
// think a better way to handle it.
assert(0);
}
//
// must also remove ,D fingerprint, to force a new diff
//
if (c_src_data->diff_file_fp)
{
fingerprint_type.free(c_src_data->diff_file_fp);
c_src_data->diff_file_fp = 0;
}
}
break;
case file_action_transparent:
case file_action_remove:
// Do nothing.
break;
}
}
break;
case file_action_remove:
//
// check if someone deleted it ahead of you
//
if (!p_src_data)
{
sub_context_ty sc;
sc.var_set_string("File_Name", c_src_data->file_name);
change_verbose(cp, &sc, i18n("no $filename in baseline"));
remove_later.push_back(nstring(c_src_data->file_name));
}
else if
(
c_src_data->edit_origin
&&
c_src_data->edit_origin->revision
&&
p_src_data->edit_origin
&&
p_src_data->edit_origin->revision
&&
!str_equal
(
c_src_data->edit_origin->revision,
p_src_data->edit_origin->revision
)
)
{
//
// Update the version number and other attributes.
// The file will still be removed, of course.
//
trace(("updating removed version number\n"));
changed = true;
change_file_copy_basic_attributes(c_src_data, p_src_data);
assert(p_src_data->edit);
assert(p_src_data->edit->revision);
if (c_src_data->edit_origin)
history_version_type.free(c_src_data->edit_origin);
c_src_data->edit_origin =
history_version_copy(p_src_data->edit);
}
break;
case file_action_modify:
case file_action_insulate:
//
// Check that nobody has
// deleted it from under you.
//
if (!p_src_data)
{
trace(("modify -> create\n"));
sub_context_ty sc;
sc.var_set_string("File_Name", c_src_data->file_name);
change_verbose
(
cp,
&sc,
i18n("warning: no $filename in baseline, creating")
);
c_src_data->action = file_action_create;
changed = true;
//
// Must also invalidate the ,D fingerprint, to force a
// new difference to be performed.
//
if (c_src_data->diff_file_fp)
{
fingerprint_type.free(c_src_data->diff_file_fp);
c_src_data->diff_file_fp = 0;
}
}
break;
case file_action_transparent:
break;
}
}
for (size_t k = 0; k < remove_later.size(); ++k)
{
const nstring &file_name = remove_later[k];
trace(("remove \"%s\"\n", file_name.c_str()));
change_file_remove(cp, file_name.get_ref());
changed = true;
}
trace(("return %s;\n", (changed ? "true" : "false")));
trace(("}\n"));
return changed;
}