Am 15.10.2010 um 21:28 schrieb Stephan Witt:

> Am 15.10.2010 um 18:00 schrieb Pavel Sanda:
> 
>> Pavel Sanda wrote:
>>> this is already bug #chrrm (bugzilla is down). 
>> 
>> #6396 
> 
> Ok, thanks.

An attempt to attack it (together with repoUpdate implementation) is attached...

I tried to make the implementation for CVS as example with minimal intrusion 
upon the VC code base.
That's why I added the two functions checkInWithMessage() and 
revertWithConfirmation().
The more ambitious solution would be to add the diff query operation for all VC 
backends and act on the outcome.
That would be a somewhat bigger change than the proposed patch.

The change to doVCCommand() is needed because of "cvs diff" unfortunately exits 
with 1 if a diff is detected.
(As documented in cvs man page.)

I'm not sure if the revert() for unchanged files should happen without 
confirmation or with a modified question. 

Stephan

Index: src/VCBackend.cpp
===================================================================
--- src/VCBackend.cpp   (Revision 35671)
+++ src/VCBackend.cpp   (Arbeitskopie)
@@ -47,7 +47,7 @@
 }
 
 
-int VCS::doVCCommand(string const & cmd, FileName const & path)
+int VCS::doVCCommand(string const & cmd, FileName const & path, bool 
reportStatus)
 {
        if (owner_)
                owner_->setBusy(true);
@@ -56,7 +56,7 @@
 
        if (owner_)
                owner_->setBusy(false);
-       if (ret)
+       if (ret && reportStatus)
                frontend::Alert::error(_("Revision control error."),
                        bformat(_("Some problem occured while running the 
command:\n"
                                  "'%1$s'."),
@@ -402,21 +402,14 @@
 
                        //sm[4]; // options
                        //sm[5]; // tag or tagdate
-                       // FIXME: must double check file is stattable/existing
-                       time_t mod = file_.lastModified();
-                       string mod_date = rtrim(asctime(gmtime(&mod)), "\n");
-                       LYXERR(Debug::LYXVC, "Date in Entries: `" << file_date
-                               << "'\nModification date of file: `" << 
mod_date << '\'');
-                       //FIXME this whole locking bussiness is not working 
under cvs and the machinery
-                       // conforms to the ci usage, not cvs.
-                       if (file_date == mod_date) {
-                               locker_ = "Unlocked";
-                               vcstatus = UNLOCKED;
+                       if (file_.isReadableFile()) {
+                               time_t mod = file_.lastModified();
+                               string mod_date = rtrim(asctime(gmtime(&mod)), 
"\n");
+                               LYXERR(Debug::LYXVC, "Date in Entries: `" << 
file_date
+                                       << "'\nModification date of file: `" << 
mod_date << '\'');
+                               vcstatus = file_.isReadOnly() ? UNLOCKED : 
LOCKED;
                        } else {
-                               // Here we should also do some more checking
-                               // to see if there are conflicts or not.
-                               locker_ = "Locked";
-                               vcstatus = LOCKED;
+                               vcstatus = NOLOCKING;
                        }
                        break;
                }
@@ -432,12 +425,81 @@
 }
 
 
+string const CVS::getTarget(OperationMode opmode)
+{
+       switch(opmode) {
+       case Directory:
+               return quoteName(owner_->filePath());
+       case File:
+               return quoteName(onlyFileName(owner_->absFileName()));
+       }
+       return string();
+}
+
+
+FileName const CVS::getDiff(OperationMode opmode)
+{
+       FileName tmpf = FileName::tempName("lyxvcout");
+       if (tmpf.empty()) {
+               LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf);
+               return tmpf;
+       }
+
+       doVCCommand("cvs diff " + getTarget(opmode)
+               + " > " + quoteName(tmpf.toFilesystemEncoding()),
+               FileName(owner_->filePath()), false);
+       return tmpf;
+}
+
+
+bool const CVS::hasDiff(OperationMode opmode)
+{
+       FileName tmpf = getDiff(opmode);
+       docstring res = tmpf.fileContents("UTF-8");
+       return !res.empty();
+}
+
+
+int CVS::edit()
+{
+       vcstatus = LOCKED;
+       return doVCCommand("cvs -q edit "
+               + quoteName(onlyFileName(owner_->absFileName())),
+               FileName(owner_->filePath()));
+}
+
+
+int CVS::unedit()
+{
+       vcstatus = UNLOCKED;
+       return doVCCommand("cvs -q unedit "
+               + quoteName(onlyFileName(owner_->absFileName())),
+               FileName(owner_->filePath()));
+}
+
+
+int CVS::update(OperationMode opmode, FileName const tmpf)
+{
+       string const redirection = tmpf.empty() ? ""
+               : " > " + quoteName(tmpf.toFilesystemEncoding());
+
+       return doVCCommand("cvs -q update "
+               + getTarget(opmode) + redirection,
+               FileName(owner_->filePath()));
+}
+
+
 string CVS::checkIn(string const & msg)
 {
-       int ret = doVCCommand("cvs -q commit -m \"" + msg + "\" "
-                   + quoteName(onlyFileName(owner_->absFileName())),
+       if (!hasDiff()) {
+               unedit();
+               return "CVS: Proceeded";
+       }
+
+       int rc = doVCCommand("cvs -q commit -m \"" + msg + "\" "
+                       + quoteName(onlyFileName(owner_->absFileName())),
                    FileName(owner_->filePath()));
-       return ret ? string() : "CVS: Proceeded";
+       return rc ? string() : "CVS: Proceeded";
 }
 
 
@@ -449,19 +511,17 @@
 
 string CVS::checkOut()
 {
-       // to be sure we test it again...
-       if (!checkOutEnabled())
+       // to be sure test readonly state again...
+       FileName fn(owner_->absFileName());
+       fn.refresh();
+       if (!fn.isReadOnly())
                return string();
 
-       int ret = doVCCommand("cvs -q edit "
-                                                 + 
quoteName(onlyFileName(owner_->absFileName())),
-                                                 FileName(owner_->filePath()));
+       int ret = edit();
        if (ret)
                return string();
 
-       ret = doVCCommand("cvs update "
-                                         + 
quoteName(onlyFileName(owner_->absFileName())),
-                                         FileName(owner_->filePath()));
+       ret = update(File, FileName());
        return ret ? string() : "CVS: Proceeded";
 }
 
@@ -474,14 +534,40 @@
 
 string CVS::repoUpdate()
 {
-       lyxerr << "Sorry, not implemented." << endl;
-       return string();
+       FileName tmpf = getDiff(Directory);
+       docstring res = tmpf.fileContents("UTF-8");
+       if (!res.empty()) {
+               LYXERR(Debug::LYXVC, "Diff detected:\n" << res);
+               docstring const file = from_utf8(owner_->filePath());
+               docstring text = bformat(_("There were detected changes "
+                               "in the working directory:\n%1$s\n\n"
+                               "In case of file conflict you have to resolve 
them "
+                               "manually or revert to repository version 
later."
+                               "\n\nContinue?"), file);
+               int ret = frontend::Alert::prompt(_("Changes detected"),
+                               text, 0, 1, _("&Yes"), _("&No"), _("View &Log 
..."));
+               if (ret == 2 ) {
+                       dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + 
tmpf.absFileName()));
+                       ret = frontend::Alert::prompt(_("Changes detected"),
+                               text, 0, 1, _("&Yes"), _("&No"));
+                       hideDialogs("file", 0);
+               }
+               if (ret == 1 ) {
+                       return string();
+               }
+       }
+
+       update(Directory, tmpf);
+       res += "Update log:\n" + tmpf.fileContents("UTF-8");
+
+       LYXERR(Debug::LYXVC, res);
+       return to_utf8(res);
 }
 
 
 bool CVS::repoUpdateEnabled()
 {
-       return false;
+       return true;
 }
 
 
@@ -509,8 +595,8 @@
                return;
        FileName f(owner_->absFileName());
        f.removeFile();
-       doVCCommand("cvs -q update " + fil,
-                   FileName(owner_->filePath()));
+       update(File, FileName());
+       unedit();
        owner_->markClean();
 }
 
@@ -715,7 +801,7 @@
        while (ifs) {
                getline(ifs, line);
                LYXERR(Debug::LYXVC, line << "\n");
-               if (!line.empty()) 
+               if (!line.empty())
                        status += line + "; ";
                if (prefixIs(line, "C ") || prefixIs(line, "CU ")
                                         || contains(line, "Commit failed")) {
Index: src/VCBackend.h
===================================================================
--- src/VCBackend.h     (Revision 35671)
+++ src/VCBackend.h     (Arbeitskopie)
@@ -33,6 +33,11 @@
                LOCKED,
                NOLOCKING
        };
+       /// the mode of operation for some VC commands
+       enum OperationMode {
+               Directory = 0,
+               File = 1
+       };
 
        virtual ~VCS() {}
 
@@ -42,6 +47,8 @@
        virtual std::string checkIn(std::string const & msg) = 0;
        // can be this operation processed in the current RCS?
        virtual bool checkInEnabled() = 0;
+       // should a log message provided for next checkin?
+       virtual bool checkInWithMessage() { return true; }
        /// check out for editing, returns log
        virtual std::string checkOut() = 0;
        // can be this operation processed in the current RCS?
@@ -54,6 +61,8 @@
        virtual std::string lockingToggle() = 0;
        // can be this operation processed in the current RCS?
        virtual bool lockingToggleEnabled() = 0;
+       // should a confirmation before revert requested?
+       virtual bool revertWithConfirmation() { return true; }
        /// revert current edits
        virtual void revert() = 0;
        /// FIXME
@@ -88,7 +97,7 @@
        virtual void scanMaster() = 0;
 
        // GUI container for doVCCommandCall
-       int doVCCommand(std::string const & cmd, support::FileName const & 
path);
+       int doVCCommand(std::string const & cmd, support::FileName const & 
path, bool reportStatus = true);
        /**
         * doVCCommandCall - call out to the version control utility
         * @param cmd the command to execute
@@ -190,6 +199,8 @@
 
        virtual bool checkInEnabled();
 
+       virtual bool checkInWithMessage() { return hasDiff(); }
+
        virtual std::string checkOut();
 
        virtual bool checkOutEnabled();
@@ -202,6 +213,8 @@
 
        virtual bool lockingToggleEnabled();
 
+       virtual bool revertWithConfirmation() { return hasDiff(); }
+
        virtual void revert();
 
        virtual void undoLast();
@@ -223,14 +236,26 @@
        virtual bool prepareFileRevisionEnabled();
 
 protected:
+       // type of the revision information
        virtual void scanMaster();
-
+       /// the mode of operation for some VC commands
+       enum OperationMode {
+               Directory = 0,
+               File = 1
+       };
+       
 private:
        support::FileName file_;
        // revision number from scanMaster
        std::string version_;
-       /// The user currently keeping the lock on the VC file.
-       std::string locker_;
+
+       virtual std::string const getTarget(OperationMode opmode);
+       virtual support::FileName const getDiff(OperationMode opmode);
+       virtual int edit();
+       virtual int unedit();
+       virtual int update(OperationMode opmode, support::FileName const tmpf);
+       virtual bool const hasDiff(OperationMode opmode);
+       virtual bool const hasDiff() { return hasDiff(File); }
 };
 
 
Index: src/LyXVC.cpp
===================================================================
--- src/LyXVC.cpp       (Revision 35671)
+++ src/LyXVC.cpp       (Arbeitskopie)
@@ -163,9 +163,10 @@
        docstring empty(_("(no log message)"));
        docstring response;
        string log;
-       bool ok = Alert::askForText(response, _("LyX VC: Log Message"));
+       bool dolog = vcs->checkInWithMessage();
+       bool ok = !dolog || Alert::askForText(response, _("LyX VC: Log 
Message"));
        if (ok) {
-               if (response.empty())
+               if (dolog && response.empty())
                        response = empty;
                log = vcs->checkIn(to_utf8(response));
 
@@ -212,8 +213,9 @@
        docstring text = bformat(_("Reverting to the stored version of the "
                                "document %1$s will lose all current 
changes.\n\n"
                                "Do you want to revert to the older version?"), 
file);
-       int const ret = Alert::prompt(_("Revert to stored version of 
document?"),
-               text, 0, 1, _("&Revert"), _("&Cancel"));
+       bool const doask = vcs->revertWithConfirmation();
+       int const ret = doask ? Alert::prompt(_("Revert to stored version of 
document?"),
+               text, 0, 1, _("&Revert"), _("&Cancel")) : 0;
 
        if (ret == 0)
                vcs->revert();

Reply via email to