Hi,

Since I've started to use LyX again (doing an M.Sc. in CS in Ireland) I
thought I'd scratch and itch.

Attached is a patch to add Subversion support to the Version Control system.

Unlike CVS I'm not trying to parse .svn/entries, it's XML and I'm not
sure I want to deal with it at all. I'm simply running svn info on the
file and getting the data.

I'm using RunCommand and I saw that it might be considered deprecated,
but there is no alternative for now, hope I won't be crucified for this.

Regards,
Baruch

p.s. I'm not subscribed, please CC me on correspondence. Thanks!
Index: ChangeLog
===================================================================
RCS file: /cvs/lyx/lyx-devel/ChangeLog,v
retrieving revision 1.1012
diff -u -r1.1012 ChangeLog
--- ChangeLog   2005/06/01 13:49:15     1.1012
+++ ChangeLog   2005/06/08 16:13:45
@@ -1,3 +1,10 @@
+2005-06-08  Baruch Even <[EMAIL PROTECTED]>
+
+       * src/lyxvc.C:
+       * src/vc-backend.h:
+       * src/vc-backend.C: Added support for Subversion (SVN) version
+       control.
+
 2005-06-01  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
        * configure.ac: if the xforms frontend is added just to help gtk,
Index: src/lyxvc.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/lyxvc.C,v
retrieving revision 1.55
diff -u -r1.55 lyxvc.C
--- src/lyxvc.C 2004/02/25 12:00:48     1.55
+++ src/lyxvc.C 2005/06/08 16:13:48
@@ -62,6 +62,12 @@
                vcs->owner(owner_);
                return true;
        }
+       // Check if file is under SVN
+       if (!(found_file = SVN::find_file(fn)).empty()) {
+               vcs.reset(new SVN(found_file));
+               vcs->owner(owner_);
+               return true;
+       }
        // file is not under any VCS.
        return false;
 }
@@ -74,6 +80,8 @@
                return true;
        if (!CVS::find_file(fn).empty())
                return true;
+       if (!SVN::find_file(fn).empty())
+               return true;
        return false;
 }
 
@@ -99,6 +107,7 @@
        // it is very likely here that the vcs is not created yet...
        if (!vcs) {
                string const cvs_entries = "CVS/Entries";
+               string const svn_entries = ".svn/entries";
 
                if (IsFileReadable(cvs_entries)) {
                        lyxerr[Debug::LYXVC]
@@ -106,7 +115,12 @@
                                << MakeDisplayPath(filename)
                                << " with CVS" << endl;
                        vcs.reset(new CVS(cvs_entries, filename));
-
+               } else if (IsFileReadable(svn_entries)) {
+                       lyxerr[Debug::LYXVC]
+                               << "LyXVC: registering "
+                               << MakeDisplayPath(filename)
+                               << " with SVN" << endl;
+                       vcs.reset(new SVN(filename));
                } else {
                        lyxerr[Debug::LYXVC]
                                << "LyXVC: registering "
Index: src/vc-backend.C
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/vc-backend.C,v
retrieving revision 1.52
diff -u -r1.52 vc-backend.C
--- src/vc-backend.C    2005/04/26 11:12:15     1.52
+++ src/vc-backend.C    2005/06/08 16:13:48
@@ -35,6 +35,10 @@
 using lyx::support::rtrim;
 using lyx::support::split;
 using lyx::support::Systemcall;
+using lyx::support::cmd_ret;
+using lyx::support::RunCommand;
+using lyx::support::token;
+using lyx::support::trim;
 
 using boost::regex;
 using boost::regex_match;
@@ -347,6 +351,116 @@
 void CVS::getLog(string const & tmpf)
 {
        doVCCommand("cvs log " + QuoteName(OnlyFilename(owner_->fileName()))
+                   + " > " + tmpf,
+                   owner_->filePath());
+}
+
+
+SVN::SVN(string const & f)
+{
+       file_ = f;
+       scanMaster();
+       vcstatus = UNLOCKED; // There is no locked state for Subversion
+}
+
+
+static cmd_ret RunSVNInfo(string const & file)
+{
+       string dir = OnlyPath(file);
+       string filename = OnlyFilename(file);
+       Path p(dir);
+       string svn_info = "svn info ";
+
+       lyxerr[Debug::LYXVC] << "LyXVC: checking in `" << dir
+                            << "' for `" << filename << '\'' << endl;
+       return RunCommand(svn_info + filename);
+}
+
+
+string const SVN::find_file(string const & file)
+{
+       cmd_ret ret = RunSVNInfo(file);
+       lyxerr[Debug::LYXVC] << "LyXVC: got errcode=" << ret.first
+                            << " and string '" << ret.second << "'" << endl;
+       if (ret.first == 0 && !contains(ret.second, "Not a versioned 
resource")) {
+               lyxerr[Debug::LYXVC] << "LyXVC: success, returning " << file << 
endl;
+               return file;
+       }
+       return string();
+}
+
+
+void SVN::scanMaster(void)
+{
+       cmd_ret ret = RunSVNInfo(file_);
+       string buffer = ret.second;
+       string head;
+       string tail;
+       bool found = false;
+
+       while (buffer.length() > 0) {
+               tail = split(buffer, head, '\n');
+               if (contains(head, "Revision:")) {
+                       found = true;
+                       break;
+               }
+               buffer = tail;
+       }
+
+       if (found) {
+               version_ = token(head, ':', 1);
+               version_ = trim(version_);
+       }
+}
+
+
+void SVN::registrer(string const & msg)
+{
+       doVCCommand("svn -q add -m \"" + msg + "\" "
+                   + QuoteName(OnlyFilename(owner_->fileName())),
+                   owner_->filePath());
+}
+
+
+void SVN::checkIn(string const & msg)
+{
+       doVCCommand("svn -q commit -m \"" + msg + "\" "
+                   + QuoteName(OnlyFilename(owner_->fileName())),
+                   owner_->filePath());
+}
+
+
+void SVN::checkOut()
+{
+       // SVN update or perhaps for SVN this should be a noop
+       lyxerr << "Sorry not implemented." << endl;
+}
+
+
+void SVN::revert()
+{
+       // Reverts to the version in SVN repository and
+       // gets the updated version from the repository.
+       string const fil = QuoteName(OnlyFilename(owner_->fileName()));
+
+       doVCCommand("svn revert " + fil,
+                   owner_->filePath());
+       owner_->markClean();
+}
+
+
+void SVN::undoLast()
+{
+       // merge the current with the previous version
+       // in a reverse patch kind of way, so that the
+       // result is to revert the last changes.
+       lyxerr << "Sorry not implemented." << endl;
+}
+
+
+void SVN::getLog(string const & tmpf)
+{
+       doVCCommand("svn log " + QuoteName(OnlyFilename(owner_->fileName()))
                    + " > " + tmpf,
                    owner_->filePath());
 }
Index: src/vc-backend.h
===================================================================
RCS file: /cvs/lyx/lyx-devel/src/vc-backend.h,v
retrieving revision 1.16
diff -u -r1.16 vc-backend.h
--- src/vc-backend.h    2003/10/06 15:42:43     1.16
+++ src/vc-backend.h    2005/06/08 16:13:48
@@ -155,4 +155,36 @@
 private:
        std::string file_;
 };
+
+class SVN : public VCS {
+public:
+       explicit
+       SVN(std::string const & f);
+
+       /// return the revision file for the given file, if found
+       static std::string const find_file(std::string const & file);
+
+       virtual void registrer(std::string const & msg);
+
+       virtual void checkIn(std::string const & msg);
+
+       virtual void checkOut(void);
+
+       virtual void revert(void);
+
+       virtual void undoLast(void);
+
+       virtual void getLog(std::string const &);
+
+       virtual std::string const versionString() const {
+               return "SVN: " + version_;
+       }
+
+protected:
+       virtual void scanMaster(void);
+
+private:
+       std::string file_;
+};
+
 #endif // VCBACKEND_H

Reply via email to