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),

Reply via email to