#
#
# add_file "git_change.cc"
# content [36ac90ebc9c461622315a75e53f3d3e2f31b69cb]
#
# add_file "git_change.hh"
# content [031cc2efb3ffba1a881f22b485f9ad039e70e56a]
#
# add_file "unit-tests/git_change.cc"
# content [dae7215d87f93975a61caacce1c8214dea75b9c0]
#
# patch "Makefile.am"
# from [71dc300612ac5a26edff2f9643a19209e0c50968]
# to [33969621e13d4b468317ed05fc7b0b479391d1f0]
#
# patch "cmd_othervcs.cc"
# from [ca6b1401a25aefc8d105c34875e3c12b7de7a770]
# to [9e422824e408cc244da6b40156e03b0bf769d4eb]
#
# patch "git_export.cc"
# from [d5b856f5f9138740e1b796fd5844f97e53656dd2]
# to [86a71cc98ad6b77161b79a057f5b5edabc6761a0]
#
# patch "git_export.hh"
# from [fd36f0dab149c0e0f7d047b89f873abb3fcd2069]
# to [7a82929d4b697da2668cf766734fea3febf065e2]
#
============================================================
--- git_change.cc 36ac90ebc9c461622315a75e53f3d3e2f31b69cb
+++ git_change.cc 36ac90ebc9c461622315a75e53f3d3e2f31b69cb
@@ -0,0 +1,189 @@
+// Copyright (C) 2009 Derek Scherger
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include "base.hh"
+#include "git_change.hh"
+#include "parallel_iter.hh"
+#include "roster.hh"
+
+#include
+
+using std::make_pair;
+using std::map;
+using std::stack;
+using std::string;
+using std::vector;
+
+void
+get_change(roster_t const & left, roster_t const & right,
+ git_change & change)
+{
+ typedef full_attr_map_t::const_iterator attr_iterator;
+ static attr_key exe_attr("mtn:execute");
+
+ parallel::iter i(left.all_nodes(), right.all_nodes());
+ while (i.next())
+ {
+ MM(i);
+ switch (i.state())
+ {
+ case parallel::invalid:
+ I(false);
+
+ case parallel::in_left:
+ // deleted
+ if (is_file_t(i.left_data()))
+ {
+ file_path path;
+ left.get_name(i.left_key(), path);
+ change.deletions.push_back(path);
+ }
+ break;
+
+ case parallel::in_right:
+ // added
+ if (is_file_t(i.right_data()))
+ {
+ file_t file = downcast_to_file_t(i.right_data());
+
+ attr_iterator exe = file->attrs.find(exe_attr);
+
+ string mode = "100644";
+ if (exe != file->attrs.end() &&
+ exe->second.first && // live attr
+ exe->second.second() == "true")
+ mode = "100755";
+
+ file_path path;
+ right.get_name(i.right_key(), path);
+ change.additions.push_back(git_add(path,
+ file->content,
+ mode));
+ }
+ break;
+
+ case parallel::in_both:
+ // moved/renamed/patched/attribute changes
+ if (is_file_t(i.left_data()))
+ {
+ file_t left_file = downcast_to_file_t(i.left_data());
+ file_t right_file = downcast_to_file_t(i.right_data());
+
+ attr_iterator left_attr = left_file->attrs.find(exe_attr);
+ attr_iterator right_attr = right_file->attrs.find(exe_attr);
+
+ string left_mode = "100644";
+ string right_mode = "100644";
+
+ if (left_attr != left_file->attrs.end() &&
+ left_attr->second.first && // live attr
+ left_attr->second.second() == "true")
+ left_mode = "100755";
+
+ if (right_attr != right_file->attrs.end() &&
+ right_attr->second.first && // live attr
+ right_attr->second.second() == "true")
+ right_mode = "100755";
+
+ file_path left_path, right_path;
+ left.get_name(i.left_key(), left_path);
+ right.get_name(i.right_key(), right_path);
+
+ if (left_path != right_path)
+ change.renames.push_back(make_pair(left_path,
+ right_path));
+
+ // git handles content changes as additions
+ if (left_file->content != right_file->content ||
+ left_mode != right_mode)
+ change.additions.push_back(git_add(right_path,
+ right_file->content,
+ right_mode));
+ }
+ break;
+ }
+ }
+}
+
+// re-order renames so that they occur in the correct order
+// i.e. rename a->b + rename b->c will be re-ordered as
+// rename b->c + rename a->b
+// this will also insert temporary names to resolve circular
+// renames and name swaps:
+// i.e. rename a->b + rename b->a will be re-ordered as
+// rename a->tmp + rename b->a + rename tmp->b
+void
+reorder_renames(vector const & renames,
+ vector & reordered_renames)
+{
+ typedef map map_type;
+
+ map_type rename_map;
+
+ for (rename_iterator i = renames.begin(); i != renames.end(); ++i)
+ rename_map.insert(*i);
+
+ while (!rename_map.empty())
+ {
+ map_type::iterator i = rename_map.begin();
+ I(i != rename_map.end());
+ git_rename base(*i);
+ rename_map.erase(i);
+
+ map_type::iterator next = rename_map.find(base.second);
+ stack rename_stack;
+
+ // stack renames so their order can be reversed
+ while (next != rename_map.end())
+ {
+ git_rename rename(*next);
+ rename_stack.push(rename);
+ rename_map.erase(next);
+ next = rename_map.find(rename.second);
+ }
+
+ // break rename loops
+ if (!rename_stack.empty())
+ {
+ git_rename const & top = rename_stack.top();
+ // if there is a loop push another rename onto the stack that
+ // renames the old base to a temporary and adjust the base
+ // rename to account for this
+ if (base.first == top.second)
+ {
+ // the temporary path introduced here is pretty weak in
+ // terms of random filenames but should suffice for the
+ // already rare situations where any of this is required.
+ string path = top.second.as_internal();
+ path += ".tmp.break-rename-loop";
+ file_path tmp = file_path_internal(path);
+ rename_stack.push(git_rename(base.first, tmp));
+ base.first = tmp;
+ }
+ }
+
+ // insert the stacked renames in reverse order
+ while (!rename_stack.empty())
+ {
+ git_rename rename = rename_stack.top();
+ rename_stack.pop();
+ reordered_renames.push_back(rename);
+ }
+
+ reordered_renames.push_back(base);
+ }
+}
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
============================================================
--- git_change.hh 031cc2efb3ffba1a881f22b485f9ad039e70e56a
+++ git_change.hh 031cc2efb3ffba1a881f22b485f9ad039e70e56a
@@ -0,0 +1,55 @@
+#ifndef __GIT_CHANGE_HH__
+#define __GIT_CHANGE_HH__
+
+// Copyright (C) 2009 Derek Scherger
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include "paths.hh"
+#include "vocab.hh"
+
+#include
+
+typedef file_path git_delete;
+typedef std::pair git_rename;
+
+struct git_add
+{
+ file_path path;
+ file_id content;
+ std::string mode;
+ git_add(file_path path, file_id content, std::string mode) :
+ path(path), content(content), mode(mode) {}
+};
+
+typedef std::vector::const_iterator delete_iterator;
+typedef std::vector::const_iterator rename_iterator;
+typedef std::vector::const_iterator add_iterator;
+
+struct git_change
+{
+ std::vector deletions;
+ std::vector renames;
+ std::vector additions;
+};
+
+void get_change(roster_t const & left, roster_t const & right,
+ git_change & change);
+
+void reorder_renames(std::vector const & renames,
+ std::vector & reordered_renames);
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
+
+#endif // __GIT_CHANGE_HH__
============================================================
--- unit-tests/git_change.cc dae7215d87f93975a61caacce1c8214dea75b9c0
+++ unit-tests/git_change.cc dae7215d87f93975a61caacce1c8214dea75b9c0
@@ -0,0 +1,117 @@
+// Copyright (C) 2009 Derek Scherger
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include "base.hh"
+#include "unit_tests.hh"
+#include "git_change.hh"
+
+using std::make_pair;
+using std::vector;
+
+UNIT_TEST(reorder_chained_renames)
+{
+ vector renames, reordered_renames;
+ renames.push_back(make_pair(file_path_internal("a"), file_path_internal("b")));
+ renames.push_back(make_pair(file_path_internal("b"), file_path_internal("c")));
+ renames.push_back(make_pair(file_path_internal("c"), file_path_internal("d")));
+
+ // these should be reordered from a->b b->c c->d to c->d b->c a->b
+ reorder_renames(renames, reordered_renames);
+ rename_iterator rename = reordered_renames.begin();
+ UNIT_TEST_CHECK(rename->first == file_path_internal("c"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("d"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("b"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("c"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("a"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("b"));
+ ++rename;
+ UNIT_TEST_CHECK(rename == reordered_renames.end());
+}
+
+UNIT_TEST(reorder_swapped_renames)
+{
+ vector renames, reordered_renames;
+ renames.push_back(make_pair(file_path_internal("a"), file_path_internal("b")));
+ renames.push_back(make_pair(file_path_internal("b"), file_path_internal("a")));
+
+ // these should be reordered from a->b b->a to a->tmp b->a tmp->b
+ reorder_renames(renames, reordered_renames);
+ rename_iterator rename = reordered_renames.begin();
+ UNIT_TEST_CHECK(rename->first == file_path_internal("a"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("a.tmp.break-rename-loop"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("b"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("a"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("a.tmp.break-rename-loop"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("b"));
+ ++rename;
+ UNIT_TEST_CHECK(rename == reordered_renames.end());
+}
+
+UNIT_TEST(reorder_rename_loop)
+{
+ vector renames, reordered_renames;
+ renames.push_back(make_pair(file_path_internal("a"), file_path_internal("b")));
+ renames.push_back(make_pair(file_path_internal("b"), file_path_internal("c")));
+ renames.push_back(make_pair(file_path_internal("c"), file_path_internal("a")));
+
+ // these should be reordered from a->b b->c c->a to a->tmp c->a b->c a->b tmp->b
+ reorder_renames(renames, reordered_renames);
+ rename_iterator rename = reordered_renames.begin();
+ UNIT_TEST_CHECK(rename->first == file_path_internal("a"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("a.tmp.break-rename-loop"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("c"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("a"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("b"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("c"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("a.tmp.break-rename-loop"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("b"));
+ ++rename;
+ UNIT_TEST_CHECK(rename == reordered_renames.end());
+}
+
+UNIT_TEST(reorder_reversed_rename_loop)
+{
+ vector renames, reordered_renames;
+ renames.push_back(make_pair(file_path_internal("z"), file_path_internal("y")));
+ renames.push_back(make_pair(file_path_internal("y"), file_path_internal("x")));
+ renames.push_back(make_pair(file_path_internal("x"), file_path_internal("z")));
+
+ // assuming that the x->z rename gets pulled from the rename map first
+ // these should be reordered from z->y y->x x->z to x->tmp y->x z->y tmp->z
+ reorder_renames(renames, reordered_renames);
+ rename_iterator rename = reordered_renames.begin();
+ UNIT_TEST_CHECK(rename->first == file_path_internal("x"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("x.tmp.break-rename-loop"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("y"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("x"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("z"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("y"));
+ ++rename;
+ UNIT_TEST_CHECK(rename->first == file_path_internal("x.tmp.break-rename-loop"));
+ UNIT_TEST_CHECK(rename->second == file_path_internal("z"));
+ ++rename;
+ UNIT_TEST_CHECK(rename == reordered_renames.end());
+}
+
+// Local Variables:
+// mode: C++
+// fill-column: 76
+// c-file-style: "gnu"
+// indent-tabs-mode: nil
+// End:
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
============================================================
--- Makefile.am 71dc300612ac5a26edff2f9643a19209e0c50968
+++ Makefile.am 33969621e13d4b468317ed05fc7b0b479391d1f0
@@ -53,7 +53,7 @@ MOST_SOURCES = \
merkle_tree.cc merkle_tree.hh \
lcs.cc lcs.hh \
rcs_import.cc rcs_import.hh \
- git_export.cc git_export.hh \
+ git_change.cc git_change.hh git_export.cc git_export.hh \
revision.cc ancestry.cc revision.hh \
cset.cc cset.hh \
roster.cc roster.hh \
@@ -299,7 +299,8 @@ UNIT_TESTEES = \
# these files (part of the main program) contain code subject to unit testing
UNIT_TESTEES = \
- basic_io.cc charset.cc commands.cc cset.cc globish.cc graph.cc \
+ basic_io.cc charset.cc commands.cc cset.cc \
+ git_change.cc globish.cc graph.cc \
merge_3way.cc merge_roster.cc netcmd.cc netxx_pipe.cc \
option.cc outdated_indicator.cc refiner.cc restrictions.cc \
revision.cc simplestring_xform.cc transforms.cc uri.cc \
@@ -311,6 +312,7 @@ UNIT_TESTERS = \
UNIT_TESTERS = \
unit-tests/basic_io.cc unit-tests/charset.cc \
unit-tests/commands.cc unit-tests/cset.cc \
+ unit-tests/git_change.cc \
unit-tests/globish.cc unit-tests/graph.cc \
unit-tests/merge_3way.cc unit-tests/merge_roster.cc \
unit-tests/netcmd.cc unit-tests/netxx_pipe.cc \
============================================================
--- cmd_othervcs.cc ca6b1401a25aefc8d105c34875e3c12b7de7a770
+++ cmd_othervcs.cc 9e422824e408cc244da6b40156e03b0bf769d4eb
@@ -12,6 +12,7 @@
#include "cmd.hh"
#include "app_state.hh"
#include "database.hh"
+#include "git_change.hh"
#include "git_export.hh"
#include "project.hh"
#include "rcs_import.hh"
@@ -115,7 +116,7 @@ CMD(git_export, "git_export", "", CMD_RE
vector revisions;
toposort(db, revision_set, revisions);
- map change_map;
+ map change_map;
load_changes(db, revisions, change_map);
============================================================
--- git_export.cc d5b856f5f9138740e1b796fd5844f97e53656dd2
+++ git_export.cc 86a71cc98ad6b77161b79a057f5b5edabc6761a0
@@ -12,9 +12,9 @@
#include "database.hh"
#include "dates.hh"
#include "file_io.hh"
+#include "git_change.hh"
#include "git_export.hh"
#include "outdated_indicator.hh"
-#include "parallel_iter.hh"
#include "revision.hh"
#include "roster.hh"
#include "simplestring_xform.hh"
@@ -23,15 +23,12 @@
#include
#include
-#include
using std::cout;
using std::istringstream;
-using std::make_pair;
using std::map;
using std::ostringstream;
using std::set;
-using std::stack;
using std::string;
using std::vector;
@@ -56,173 +53,6 @@ namespace
return quoted;
}
-
- typedef vector::const_iterator delete_iterator;
- typedef vector::const_iterator rename_iterator;
- typedef vector::const_iterator add_iterator;
-
- attr_key exe_attr("mtn:execute");
-
- void
- get_changes(roster_t const & left, roster_t const & right,
- file_changes & changes)
- {
-
- typedef full_attr_map_t::const_iterator attr_iterator;
-
- parallel::iter i(left.all_nodes(), right.all_nodes());
- while (i.next())
- {
- MM(i);
- switch (i.state())
- {
- case parallel::invalid:
- I(false);
-
- case parallel::in_left:
- // deleted
- if (is_file_t(i.left_data()))
- {
- file_path path;
- left.get_name(i.left_key(), path);
- changes.deletions.push_back(file_delete(path));
- }
- break;
-
- case parallel::in_right:
- // added
- if (is_file_t(i.right_data()))
- {
- file_t file = downcast_to_file_t(i.right_data());
-
- attr_iterator exe = file->attrs.find(exe_attr);
-
- string mode = "100644";
- if (exe != file->attrs.end() &&
- exe->second.first && // live attr
- exe->second.second() == "true")
- mode = "100755";
-
- file_path path;
- right.get_name(i.right_key(), path);
- changes.additions.push_back(file_add(path,
- file->content,
- mode));
- }
- break;
-
- case parallel::in_both:
- // moved/renamed/patched/attribute changes
- if (is_file_t(i.left_data()))
- {
- file_t left_file = downcast_to_file_t(i.left_data());
- file_t right_file = downcast_to_file_t(i.right_data());
-
- attr_iterator left_attr = left_file->attrs.find(exe_attr);
- attr_iterator right_attr = right_file->attrs.find(exe_attr);
-
- string left_mode = "100644";
- string right_mode = "100644";
-
- if (left_attr != left_file->attrs.end() &&
- left_attr->second.first && // live attr
- left_attr->second.second() == "true")
- left_mode = "100755";
-
- if (right_attr != right_file->attrs.end() &&
- right_attr->second.first && // live attr
- right_attr->second.second() == "true")
- right_mode = "100755";
-
- file_path left_path, right_path;
- left.get_name(i.left_key(), left_path);
- right.get_name(i.right_key(), right_path);
-
- if (left_path != right_path)
- changes.renames.push_back(file_rename(left_path,
- right_path));
-
- // git handles content changes as additions
- if (left_file->content != right_file->content ||
- left_mode != right_mode)
- changes.additions.push_back(file_add(right_path,
- right_file->content,
- right_mode));
- }
- break;
- }
- }
- }
-
- // re-order renames so that they occur in the correct order
- // i.e. rename a->b + rename b->c will be re-ordered as
- // rename b->c + rename a->b
- // this will also insert temporary names to resolve circular
- // renames and name swaps:
- // i.e. rename a->b + rename b->a will be re-ordered as
- // rename a->tmp + rename b->a + rename tmp->b
- void
- reorder_renames(vector const & renames,
- vector & reordered_renames)
- {
- typedef map map_type;
-
- map_type rename_map;
-
- for (rename_iterator i = renames.begin(); i != renames.end(); ++i)
- rename_map.insert(make_pair(i->old_path, i->new_path));
-
- while (!rename_map.empty())
- {
- map_type::iterator i = rename_map.begin();
- I(i != rename_map.end());
- file_rename base(i->first, i->second);
- rename_map.erase(i);
-
- map_type::iterator next = rename_map.find(base.new_path);
- stack rename_stack;
-
- // stack renames so their order can be reversed
- while (next != rename_map.end())
- {
- file_rename rename(next->first, next->second);
- rename_stack.push(rename);
- rename_map.erase(next);
- next = rename_map.find(rename.new_path);
- }
-
- // break rename loops
- if (!rename_stack.empty())
- {
- file_rename const & top = rename_stack.top();
- // if there is a loop push another rename onto the stack that
- // renames the old base to a temporary and adjust the base
- // rename to account for this
- if (base.old_path == top.new_path)
- {
- // the temporary path introduced here is pretty weak in
- // terms of random filenames but should suffice for the
- // already rare situations where any of this is required.
- string path = top.new_path.as_internal();
- path += ".tmp.break-rename-loop";
- file_path tmp = file_path_internal(path);
- rename_stack.push(file_rename(base.old_path, tmp));
- base.old_path = tmp;
- }
- }
-
- // insert the stacked renames in reverse order
- while (!rename_stack.empty())
- {
- file_rename rename = rename_stack.top();
- rename_stack.pop();
- reordered_renames.push_back(rename);
- }
-
- reordered_renames.push_back(base);
- }
- }
-
};
void
@@ -301,7 +131,7 @@ load_changes(database & db,
void
load_changes(database & db,
vector const & revisions,
- map & change_map)
+ map & change_map)
{
// process revisions in reverse order and calculate the file changes for
// each revision. these are cached in a map for use in the export phase
@@ -342,8 +172,8 @@ load_changes(database & db,
db.get_roster(parent1, old_roster);
db.get_roster(*r, new_roster);
- file_changes changes;
- get_changes(old_roster, new_roster, changes);
+ git_change changes;
+ get_change(old_roster, new_roster, changes);
change_map[*r] = changes;
++loaded;
@@ -356,7 +186,7 @@ export_changes(database & db,
map & marked_revs,
map const & author_map,
map const & branch_map,
- map const & change_map,
+ map const & change_map,
bool log_revids, bool log_certs)
{
size_t revnum = 0;
@@ -498,17 +328,17 @@ export_changes(database & db,
else
I(false);
- map::const_iterator f = change_map.find(*r);
+ map::const_iterator f = change_map.find(*r);
I(f != change_map.end());
- file_changes const & changes = f->second;
+ git_change const & change = f->second;
- vector reordered_renames;
- reorder_renames(changes.renames, reordered_renames);
+ vector reordered_renames;
+ reorder_renames(change.renames, reordered_renames);
// emit file data blobs for modified and added files
for (add_iterator
- i = changes.additions.begin(); i != changes.additions.end(); ++i)
+ i = change.additions.begin(); i != change.additions.end(); ++i)
{
if (marked_files.find(i->content) == marked_files.end())
{
@@ -572,17 +402,17 @@ export_changes(database & db,
cout << "merge :" << marked_revs[parent2] << "\n";
for (delete_iterator
- i = changes.deletions.begin(); i != changes.deletions.end(); ++i)
- cout << "D " << quote_path(i->path) << "\n";
+ i = change.deletions.begin(); i != change.deletions.end(); ++i)
+ cout << "D " << quote_path(*i) << "\n";
for (rename_iterator
i = reordered_renames.begin(); i != reordered_renames.end(); ++i)
cout << "R "
- << quote_path(i->old_path) << " "
- << quote_path(i->new_path) << "\n";
+ << quote_path(i->first) << " "
+ << quote_path(i->second) << "\n";
for (add_iterator
- i = changes.additions.begin(); i != changes.additions.end(); ++i)
+ i = change.additions.begin(); i != change.additions.end(); ++i)
cout << "M " << i->mode << " :"
<< marked_files[i->content] << " "
<< quote_path(i->path) << "\n";
@@ -643,7 +473,6 @@ export_root_refs(database & db,
<< "from :" << marked_revs[*i] << "\n";
}
-
void
export_leaf_refs(database & db,
map & marked_revs)
@@ -656,106 +485,6 @@ export_leaf_refs(database & db,
<< "from :" << marked_revs[*i] << "\n";
}
-#ifdef BUILD_UNIT_TESTS
-
-#include "unit_tests.hh"
-
-UNIT_TEST(git_rename_reordering, reorder_chained_renames)
-{
- vector renames, reordered_renames;
- renames.push_back(file_rename(file_path_internal("a"), file_path_internal("b")));
- renames.push_back(file_rename(file_path_internal("b"), file_path_internal("c")));
- renames.push_back(file_rename(file_path_internal("c"), file_path_internal("d")));
-
- // these should be reordered from a->b b->c c->d to c->d b->c a->b
- reorder_renames(renames, reordered_renames);
- rename_iterator rename = reordered_renames.begin();
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("c"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("d"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("b"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("c"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("a"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("b"));
- ++rename;
- UNIT_TEST_CHECK(rename == reordered_renames.end());
-}
-
-UNIT_TEST(git_rename_reordering, reorder_swapped_renames)
-{
- vector renames, reordered_renames;
- renames.push_back(file_rename(file_path_internal("a"), file_path_internal("b")));
- renames.push_back(file_rename(file_path_internal("b"), file_path_internal("a")));
-
- // these should be reordered from a->b b->a to a->tmp b->a tmp->b
- reorder_renames(renames, reordered_renames);
- rename_iterator rename = reordered_renames.begin();
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("a"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("a.tmp.break-rename-loop"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("b"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("a"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("a.tmp.break-rename-loop"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("b"));
- ++rename;
- UNIT_TEST_CHECK(rename == reordered_renames.end());
-}
-
-UNIT_TEST(git_rename_reordering, reorder_rename_loop)
-{
- vector renames, reordered_renames;
- renames.push_back(file_rename(file_path_internal("a"), file_path_internal("b")));
- renames.push_back(file_rename(file_path_internal("b"), file_path_internal("c")));
- renames.push_back(file_rename(file_path_internal("c"), file_path_internal("a")));
-
- // these should be reordered from a->b b->c c->a to a->tmp c->a b->c a->b tmp->b
- reorder_renames(renames, reordered_renames);
- rename_iterator rename = reordered_renames.begin();
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("a"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("a.tmp.break-rename-loop"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("c"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("a"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("b"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("c"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("a.tmp.break-rename-loop"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("b"));
- ++rename;
- UNIT_TEST_CHECK(rename == reordered_renames.end());
-}
-
-UNIT_TEST(git_rename_reordering, reorder_reversed_rename_loop)
-{
- vector renames, reordered_renames;
- renames.push_back(file_rename(file_path_internal("z"), file_path_internal("y")));
- renames.push_back(file_rename(file_path_internal("y"), file_path_internal("x")));
- renames.push_back(file_rename(file_path_internal("x"), file_path_internal("z")));
-
- // assuming that the x->z rename gets pulled from the rename map first
- // these should be reordered from z->y y->x x->z to x->tmp y->x z->y tmp->z
- reorder_renames(renames, reordered_renames);
- rename_iterator rename = reordered_renames.begin();
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("x"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("x.tmp.break-rename-loop"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("y"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("x"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("z"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("y"));
- ++rename;
- UNIT_TEST_CHECK(rename->old_path == file_path_internal("x.tmp.break-rename-loop"));
- UNIT_TEST_CHECK(rename->new_path == file_path_internal("z"));
- ++rename;
- UNIT_TEST_CHECK(rename == reordered_renames.end());
-}
-
-#endif // BUILD_UNIT_TESTS
-
// Local Variables:
// mode: C++
// fill-column: 76
============================================================
--- git_export.hh fd36f0dab149c0e0f7d047b89f873abb3fcd2069
+++ git_export.hh 7a82929d4b697da2668cf766734fea3febf065e2
@@ -10,38 +10,6 @@
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.
-struct file_delete
-{
- file_path path;
- file_delete(file_path path) :
- path(path) {}
-};
-
-struct file_rename
-{
- file_path old_path;
- file_path new_path;
- file_rename(file_path old_path, file_path new_path) :
- old_path(old_path), new_path(new_path) {}
-};
-
-struct file_add
-{
- file_path path;
- file_id content;
- std::string mode;
- file_add(file_path path, file_id content, std::string mode) :
- path(path), content(content), mode(mode) {}
-};
-
-struct file_changes
-{
- std::vector deletions;
- std::vector renames;
- std::vector additions;
-};
-
-
void read_mappings(system_path const & path,
std::map & mappings);
@@ -53,16 +21,16 @@ void load_changes(database & db,
void load_changes(database & db,
std::vector const & revisions,
- std::map & change_map);
+ std::map & change_map);
void export_changes(database & db,
std::vector const & revisions,
std::map & marked_revs,
std::map const & author_map,
std::map const & branch_map,
- std::map const & change_map,
+ std::map const & change_map,
bool log_revids, bool log_certs);
-
+
void export_rev_refs(std::vector const & revisions,
std::map & marked_revs);
@@ -80,4 +48,4 @@ void export_leaf_refs(database & db,
// End:
// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
-#endif // __RCS_IMPORT_HH__
+#endif // __GIT_EXPORT_HH__