Author: vfr Date: Fri Nov 5 19:25:29 2010 New Revision: 36134 URL: http://www.lyx.org/trac/changeset/36134
Log: Fix bug #6058: Change tracking and versioning. Computes a hash value for the authors when using change tracking. Text.cpp, BufferParams.h, Author.h: Change unsigned int to int because the hash values can be negative. lyx2lyx: Allow to convert negative author_ids. See also: r30756. Modified: lyx-devel/trunk/development/FORMAT lyx-devel/trunk/lib/lyx2lyx/lyx_2_0.py lyx-devel/trunk/src/Author.cpp lyx-devel/trunk/src/Author.h lyx-devel/trunk/src/Buffer.cpp lyx-devel/trunk/src/BufferParams.h lyx-devel/trunk/src/Text.cpp Modified: lyx-devel/trunk/development/FORMAT ============================================================================== --- lyx-devel/trunk/development/FORMAT Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/development/FORMAT Fri Nov 5 19:25:29 2010 (r36134) @@ -6,6 +6,13 @@ The good example would be 2010-01-10 entry. ----------------------- +2010-10-23 Vincent van Ravesteijn <[email protected]> + * Format incremented to 405: author hash numbers + The authors that are used in change tracking are + now identified in the file by a number that represents + the hash value of the name and email. In this way + collaboration using version control leads to way less + merge conflicts. 2010-10-13 Richard Heck <[email protected]> * Format incremented to 404: refstyle support Modified: lyx-devel/trunk/lib/lyx2lyx/lyx_2_0.py ============================================================================== --- lyx-devel/trunk/lib/lyx2lyx/lyx_2_0.py Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/lib/lyx2lyx/lyx_2_0.py Fri Nov 5 19:25:29 2010 (r36134) @@ -771,7 +771,7 @@ " Remove the author_id from the \\author definition " i = 0 anum = 0 - rx = re.compile(r'(\\author)\s+(\d+)\s+(\".*\")\s*(.*)$') + rx = re.compile(r'(\\author)\s+([-\d]+)\s+(\".*\")\s*(.*)$') idmap = dict() while True: @@ -2013,10 +2013,12 @@ [401, []], [402, [convert_bibtex_clearpage]], [403, [convert_flexnames]], - [404, [convert_prettyref]] + [404, [convert_prettyref]], + [405, []] ] -revert = [[403, [revert_refstyle]], +revert = [[404, []], + [403, [revert_refstyle]], [402, [revert_flexnames]], [401, []], [400, [revert_diagram]], Modified: lyx-devel/trunk/src/Author.cpp ============================================================================== --- lyx-devel/trunk/src/Author.cpp Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/src/Author.cpp Fri Nov 5 19:25:29 2010 (r36134) @@ -12,9 +12,8 @@ #include "Author.h" -#include "support/lstrings.h" - #include "support/lassert.h" +#include "support/lstrings.h" #include <algorithm> #include <istream> @@ -24,6 +23,24 @@ namespace lyx { +static int computeHash(docstring const & name, + docstring const & email) +{ + string const full_author_string = to_ascii(name + email); + // Bernstein's hash function + unsigned int hash = 5381; + for (unsigned int i = 0; i < full_author_string.length(); ++i) + hash = ((hash << 5) + hash) + unsigned int(full_author_string[i]); + return int(hash); +} + + +Author::Author(docstring const & name, docstring const & email) + : name_(name), email_(email), used_(true) +{ + buffer_id_ = computeHash(name_, email_); +} + bool operator==(Author const & l, Author const & r) { @@ -65,17 +82,17 @@ int AuthorList::record(Author const & a) { + // If we record an author which equals the current + // author, we copy the buffer_id, so that it will + // keep the same id in the file. + if (authors_.size() > 0 && a == authors_[0]) + authors_[0].setBufferId(a.buffer_id()); + Authors::const_iterator it(authors_.begin()); Authors::const_iterator itend(authors_.end()); - for (int i = 0; it != itend; ++it, ++i) { - if (*it == a) { - if (it->buffer_id() == 0) - // The current author is internally represented as - // author 0, but it appears he has already an id. - it->setBufferId(a.buffer_id()); + if (*it == a) return i; - } } authors_.push_back(a); return last_id_++; @@ -128,24 +145,6 @@ AuthorList::Authors::const_iterator a_it = sorted.begin(); AuthorList::Authors::const_iterator a_end = sorted.end(); - - // Find the buffer id for the current author (internal id 0), - // if he doesn't have a buffer_id yet. - if (sorted.get(0).buffer_id() == 0) { - unsigned int cur_id = 1; - for (; a_it != a_end; ++a_it) { - if (a_it->buffer_id() == cur_id) - ++cur_id; - else if (a_it->buffer_id() > cur_id) { - break; - } - } - // Set the id in both the original authorlist, - // as in the copy. - a.get(0).setBufferId(cur_id); - sorted.get(0).setBufferId(cur_id); - sorted.sort(); - } for (a_it = sorted.begin(); a_it != a_end; ++a_it) { if (a_it->used()) Modified: lyx-devel/trunk/src/Author.h ============================================================================== --- lyx-devel/trunk/src/Author.h Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/src/Author.h Fri Nov 5 19:25:29 2010 (r36134) @@ -24,16 +24,15 @@ /// Author() {} /// - Author(docstring const & name, docstring const & email) - : name_(name), email_(email), used_(true), buffer_id_(0) {} + Author(docstring const & name, docstring const & email); /// docstring name() const { return name_; } /// docstring email() const { return email_; } /// - unsigned int buffer_id() const { return buffer_id_; } + int buffer_id() const { return buffer_id_; } /// - void setBufferId(unsigned int buffer_id) const { buffer_id_ = buffer_id; } + void setBufferId(int buffer_id) const { buffer_id_ = buffer_id; } /// void setUsed(bool u) const { used_ = u; } /// @@ -49,7 +48,7 @@ /// mutable bool used_; /// The id of the author in the lyx-file - mutable unsigned int buffer_id_; + mutable int buffer_id_; }; Modified: lyx-devel/trunk/src/Buffer.cpp ============================================================================== --- lyx-devel/trunk/src/Buffer.cpp Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/src/Buffer.cpp Fri Nov 5 19:25:29 2010 (r36134) @@ -128,7 +128,7 @@ // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -int const LYX_FORMAT = 404; // rgh: refstyle +int const LYX_FORMAT = 405; // vfr: author hash typedef map<string, bool> DepClean; typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache; Modified: lyx-devel/trunk/src/BufferParams.h ============================================================================== --- lyx-devel/trunk/src/BufferParams.h Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/src/BufferParams.h Fri Nov 5 19:25:29 2010 (r36134) @@ -340,7 +340,8 @@ AuthorList const & authors() const; /// map of the file's author IDs to AuthorList indexes - std::map<unsigned int, int> author_map; + typedef std::map<int, int> AuthorMap; + AuthorMap author_map; /// the buffer's font encoding std::string const font_encoding() const; /// Modified: lyx-devel/trunk/src/Text.cpp ============================================================================== --- lyx-devel/trunk/src/Text.cpp Fri Nov 5 18:54:57 2010 (r36133) +++ lyx-devel/trunk/src/Text.cpp Fri Nov 5 19:25:29 2010 (r36134) @@ -456,10 +456,10 @@ } else if (token == "\\change_inserted" || token == "\\change_deleted") { lex.eatLine(); istringstream is(lex.getString()); - unsigned int aid; + int aid; time_t ct; is >> aid >> ct; - map<unsigned int, int> const & am = bp.author_map; + BufferParams::AuthorMap const & am = bp.author_map; if (am.find(aid) == am.end()) { errorList.push_back(ErrorItem(_("Change tracking error"), bformat(_("Unknown author index for change: %1$d\n"), aid),
